dAgentBase API Reference
Everything you need to integrate with dAgentBase. Search listings, purchase data, stream real-time feeds, and manage your account programmatically.
https://dagentbase.com/api/v1New here? Start with the 5-minute Quickstart
Auth → search → preview → free purchase → download, all with copy-paste cURL.
Authentication
dAgentBase supports two authentication methods. Both use the Authorization header.
API Key (recommended)
Best for agents, scripts, and server-side integrations. Keys start with dm_live_ and never expire until revoked.
Authorization: Bearer dm_live_abc123...Supabase JWT
Used automatically by the web app. JWTs are short-lived session tokens issued by Supabase Auth.
Authorization: Bearer eyJhbGciOi...How to get an API key
- Sign in at dagentbase.com/settings
- Scroll to the API Keys section
- Click "Create API Key" and give it a name
- Copy the key immediately — it is only shown once
Programmatic signup (agent path)
Agents can sign up and get a working API key in a single request — no CAPTCHA, no email click. Accounts created this way start on the anonymous tier (10 free claims / 24h). Sign in via GitHub or Google to upgrade to 100/24h, or complete any paid purchase for unlimited.
curl -X POST https://dagentbase.com/api/v1/auth/signup \
-H "Content-Type: application/json" \
-d '{
"email": "your-agent@example.com",
"terms_accepted": true
}'Rate limit: 5 signups per IP per 24 hours. Required fields: email, terms_accepted (must be true — acknowledges Terms + Privacy). Optional fields: password, display_name, api_key_name. The response contains api_key — store it immediately, it is shown only once.
curl https://dagentbase.com/api/v1/listings \
-H "Authorization: Bearer dm_live_abc123..."const res = await fetch("https://dagentbase.com/api/v1/listings", {
headers: {
Authorization: "Bearer dm_live_abc123...",
},
});
const { data, error, meta } = await res.json();import requests
resp = requests.get(
"https://dagentbase.com/api/v1/listings",
headers={"Authorization": "Bearer dm_live_abc123..."},
)
data = resp.json()Rate Limits
Rate limits are applied per IP address (unauthenticated) or per API key (authenticated). All windows are 60 seconds unless noted.
| Endpoint group | Limit | Window |
|---|---|---|
| Default (most endpoints) | 60 requests | 1 minute |
| Proxy & stream | 120 requests | 1 minute |
| Webhooks (Stripe) | 100 requests | 1 minute |
| Admin | 30 requests | 1 minute |
| Purchases (POST) | 10 requests | 1 minute |
| Auth (signup / login) | 10 requests | 1 minute |
| API key creation | 5 requests | 1 minute |
| Seed (dev only) | 3 requests | 1 hour |
Rate limit headers
Every API response includes rate limit information in the headers:
X-RateLimit-Limit: 60
X-RateLimit-Remaining: 57
X-RateLimit-Reset: 1719750000X-RateLimit-Reset is a Unix timestamp (seconds) at which the current window resets.
When you exceed a rate limit
You will receive a 429 Too Many Requests response with a Retry-After header indicating the number of seconds to wait.
{
"data": null,
"error": "Rate limit exceeded. Try again later."
}
// Headers:
// Retry-After: 12
// X-RateLimit-Limit: 60
// X-RateLimit-Remaining: 0Free-Claim Quota & Tiers
Free listings can be claimed via POST /purchases without payment, but each account is bounded by a daily quota on two axes — claims and bandwidth. Whichever you hit first triggers a 429. The quota window is a sliding 24 hours per claim, not a fixed calendar reset.
| Tier | Claims / 24h | Bandwidth / 24h | How to reach this tier |
|---|---|---|---|
| anonymous | 10 | 1 GB | Sign up via POST /api/v1/auth/signup |
| email_verified | 50 | 10 GB | Web signup with confirmed email |
| oauth_verified | 100 | 50 GB | Sign in with GitHub or Google |
| payment_verified | unlimited | 500 GB | Complete any paid purchase (one-time, subscription, or per-query) |
Quota headers on every free-claim response
Every successful and quota-blocked free claim includes structured headers so SDK clients can self-throttle without an extra round-trip:
X-Quota-Tier: anonymous
X-Quota-Claims-Limit: 10 # claims per 24h on this tier
X-Quota-Claims-Used: 3 # claims already used in the current window
X-Quota-Claims-Remaining: 7 # claims left
X-Quota-Bandwidth-Limit: 1073741824 # bytes per 24h on this tier
X-Quota-Bandwidth-Used: 304082944 # bytes consumed in the current window
X-Quota-Reset: 1777897257 # Unix seconds when the oldest claim falls out
Retry-After: 23910 # only on 429 responses, secondsThese are distinct from the per-IP X-RateLimit-* headers emitted by the request-rate limiter (see Rate Limits, above).
What a quota-blocked 429 looks like
HTTP/1.1 429 Too Many Requests
X-Quota-Tier: anonymous
X-Quota-Claims-Limit: 10
X-Quota-Claims-Used: 10
X-Quota-Claims-Remaining: 0
Retry-After: 23910
{
"data": null,
"error": "Daily free-claim limit reached (10/10 on the anonymous tier). Upgrade by signing in with GitHub or Google, or by completing any paid purchase. Otherwise try again in 24 hours."
}The error message names the tier and the upgrade path. SDK clients should surface X-Quota-Tier and Retry-After to the agent owner.
Why bandwidth on top of claim count?
A 10-claim limit alone doesn't bound abuse if listings are multi-GB. A bot at the anonymous tier can't exceed 1 GB of file size summed across all its claims in 24 hours, even if every claim is for a 5 GB Parquet file.
Response Format
All dAgentBase API endpoints return a consistent JSON envelope with three top-level fields:
{
"data": { ... }, // The requested resource(s), or null on error
"error": null, // Error message string, or null on success
"meta": { // Pagination and request metadata
"page": 1,
"per_page": 20,
"total": 142
}
}dataThe requested resource or array of resources. null when an error occurs.
errorA human-readable error message. null on success.
metaPagination info, total counts, and other request metadata.
{
"data": {
"id": "a1b2c3d4-...",
"title": "S&P 500 Historical Data",
"price_cents": 499,
"category": "dataset"
},
"error": null,
"meta": {}
}{
"data": null,
"error": "Listing not found",
"meta": {}
}Error Codes
dAgentBase uses standard HTTP status codes. The error field in the response body provides a human-readable explanation.
| Code | Name | Description |
|---|---|---|
400 | Bad Request | Missing or invalid parameters |
401 | Unauthorized | Missing or invalid API key / JWT |
403 | Forbidden | Valid credentials, but insufficient permissions |
404 | Not Found | Resource does not exist |
409 | Conflict | Duplicate action (e.g. already purchased) |
413 | Payload Too Large | Request body exceeds 1 MB (JSON) or 50 MB (file upload) |
429 | Too Many Requests | Rate limit exceeded. Check the Retry-After header. |
500 | Internal Server Error | Something went wrong on our end |
Discovery
Search and browse listings on the marketplace. All discovery endpoints are publicly accessible without authentication.
How q is matched
- 2+ words — semantic search via OpenAI embeddings. Matches by meaning, not exact words.
- Single word, 4+ chars — full-text search across title, description, and tags.
- Single word, < 4 chars — prefix match on title.
/api/v1/listingsSearch and filter listings. Supports full-text search, category filtering, price range, and pagination.
Parameters
qstring— Full-text search querycategorystring— dataset, api, image, database, model, vector_store, otherlicensestring— commercial, research_only, open, custommin_priceint— Minimum price in centsmax_priceint— Maximum price in cents (0 = free only)formatstring— Filter by format (CSV, JSON, Parquet, etc.)tagstring— Filter by tag (e.g., finance, crypto)delivery_typestring— file, api, stream, webhookmin_qualityint— Minimum quality score (0-100)min_gradestring— Minimum quality grade: A (85+), B (70+), C (55+), D (40+)has_databool— Only listings with quality score > 0 (true/false)seller_tierstring— Filter by seller reputation: verified (50+), trusted (70+), top_seller (85+)min_trustint— Minimum seller trust score (0-100)max_qualityint— Maximum quality score (0-100)freshness_guaranteestring— realtime, daily, weekly, monthly, snapshotmax_stalenessint— Maximum days since last updateregulatory_tagstring— GDPR, HIPAA, SOC2, etc.supported_formatstring— Filter by any format the listing exposes (CSV, JSON, Parquet…)intelligence_typestring— Intelligence-category subtype (rumor, sighting, primary_doc, signal)exclude_expiredbool— Hide listings whose intel expiry has passedexclusive_onlybool— Only single-buyer / exclusive intel listingsavailable_onlybool— Hide exclusives already claimed by another buyermarket_tickerstring— Intel listings tagged with this market ticker (e.g. AAPL)include_trendsbool— Add quality_trend (slope of recent quality scores) to each rowsortstring— created_at, price_cents, quality_score, title, row_countorderstring— asc or desc (default)pageint— Page number (default: 1)per_pageint— Results per page (default: 20, max: 100)Response
{
"data": [
{
"id": "a1b2c3d4-...",
"title": "S&P 500 Historical Data",
"category": "dataset",
"price_cents": 499,
"quality_score": 92,
"seller": { "display_name": "DataCorp" }
}
],
"error": null,
"meta": { "page": 1, "per_page": 20, "total": 142 }
}/api/v1/listings/:idGet full listing details including seller info, files, quality score, and review stats.
Response
{
"data": {
"id": "a1b2c3d4-...",
"title": "S&P 500 Historical Data",
"description": "...",
"category": "dataset",
"price_cents": 499,
"quality_score": 92,
"seller": { ... },
"files": [ ... ],
"review_stats": { "avg": 4.5, "count": 12 }
},
"error": null,
"meta": {}
}/api/v1/listings/:id/previewGet free sample data and schema preview. No authentication required.
Response
{
"data": {
"id": "a1b2c3d4-...",
"title": "S&P 500 Historical Data",
"schema": { "columns": ["date", "open", "high", "low", "close", "volume"] },
"sample": [
{ "date": "2025-01-02", "open": 5881.63, "close": 5906.94 }
]
},
"error": null,
"meta": {}
}Collections
Curated bundles of related listings (e.g. "Crypto OHLCV Datasets", "Real-time Sports Feeds"). Public — no authentication required.
/api/v1/collectionsList collections, featured first.
Parameters
pageint— Page number (default: 1)per_pageint— Per page (default: 30, max: 100)Response
{
"data": [
{
"id": "col_uuid",
"slug": "crypto-ohlcv",
"title": "Crypto OHLCV Datasets",
"description": "Hand-picked daily & intraday crypto price feeds.",
"is_featured": true,
"listings": [{ "listing": { "id": "...", "title": "..." } }]
}
],
"error": null,
"meta": { "page": 1, "per_page": 30, "total": 12, "total_pages": 1 }
}/api/v1/collections/:slugGet a single collection by slug, with full listing details and seller info. Inactive listings are filtered out automatically.
Purchasing
Purchase listings and access your purchased data. Free listings complete instantly via API. Paid listings return a Stripe-hostedcheckout_urlthat the buyer opens in a browser to pay — agent-initiated paid purchases are not yet supported.
/api/v1/purchasesRequiredPurchase a listing. Free listings complete instantly. Paid listings return a Stripe checkout URL — the buyer opens it in a browser to pay (one-time minimum: $10).
Request body
{ "listing_id": "a1b2c3d4-..." }Response
// Free listing — full Purchase object:
{
"data": {
"id": "p1...",
"buyer_id": "u_...",
"listing_id": "a1b2c3d4-...",
"amount_cents": 0,
"platform_fee_cents": 0,
"currency": "usd",
"status": "completed",
"created_at": "2025-06-15T10:30:00Z"
},
"error": null
}
// Paid listing — Stripe checkout URL the buyer opens in a browser:
{
"data": {
"purchase_id": "p1...",
"checkout_url": "https://checkout.stripe.com/c/pay/cs_...",
"amount_cents": 1499
},
"error": null
}/api/v1/purchasesRequiredList all your purchases. Includes listing info and purchase status.
Parameters
statusstring— Filter by status: completed, pending, refundedResponse
{
"data": [
{
"id": "p1...",
"listing_id": "a1b2...",
"amount_cents": 499,
"status": "completed",
"created_at": "2025-06-15T10:30:00Z",
"listing": { "title": "S&P 500 Data", ... }
}
],
"error": null,
"meta": { "total": 5 }
}/api/v1/purchases/:id/accessRequiredGet signed download URLs for a completed purchase. URLs expire after 1 hour.
Response
{
"data": {
"files": [
{
"filename": "sp500_2020_2025.csv",
"download_url": "https://storage.dagentbase.com/...",
"size_bytes": 4521987
}
]
},
"error": null,
"meta": {}
}/api/v1/purchases/:id/refundRequiredRequest a refund for a completed purchase. Available within 48 hours. Free purchases refund instantly; paid purchases reverse the original Stripe payment_intent. Reason is optional.
Request body
{ "reason": "Data quality did not match description" }Response
{
"data": { "id": "p1...", "status": "refunded" },
"error": null
}/api/v1/purchases/:id/deliverRequiredQueue delivery of a completed purchase to one of your saved cloud destinations (S3, GCS, Azure, Snowflake, BigQuery, Databricks). Returns 202 Accepted with a delivery_id.
Request body
{
"delivery_preference_id": "pref_uuid",
"format": "parquet"
}Response
{
"data": {
"delivery_id": "del_1719750000000",
"status": "queued",
"destination": { "type": "s3", "name": "primary-bucket" },
"files_count": 3,
"format": "parquet",
"estimated_time_seconds": 60
},
"error": null
}Disputes
File and resolve disputes on completed purchases. Buyers open disputes; sellers can decline, approve refunds, or wait. Either party can mark the dispute resolved. Buyers can escalate to admin after 3 days. Maximum 3 open disputes per buyer at a time.
/api/v1/disputesRequiredList your disputes (as buyer or seller). Each row includes the listing, both parties, and the most recent message.
/api/v1/disputesBuyerOpen a dispute on a completed purchase. The reason is auto-posted as the first message and the seller is notified by email.
Request body
{
"purchase_id": "p1...",
"reason": "File only had 5,000 rows — listing claimed 10,000."
}Response
{
"data": {
"id": "d1...",
"purchase_id": "p1...",
"status": "open",
"reason": "...",
"created_at": "2025-06-22T08:00:00Z"
},
"error": null
}/api/v1/disputes/:idRequiredGet a dispute with the full message thread. Only the buyer, seller, or an admin can read it.
/api/v1/disputes/:idRequiredTake an action on a dispute. resolve = either party closes; escalate = buyer-only, after 3 days; approve_refund = seller agrees to refund; decline = seller rejects (buyer can escalate).
Request body
{ "action": "resolve" }
// or "escalate" | "approve_refund" | "decline"/api/v1/disputes/:id/messagesRequiredGet all messages on a dispute, oldest first.
/api/v1/disputes/:id/messagesRequiredPost a message on an open dispute. Accepts JSON or multipart/form-data (with a file attachment up to 10 MB — pdf, jpg, png, gif, txt, doc(x), csv, xls(x)).
Request body
{ "message": "I uploaded a screenshot of the row count..." }Real-time Data
Access real-time API proxies and SSE streams for live data feeds. These endpoints forward requests to the seller's upstream service.
/api/v1/proxy/:listing_idRequiredAPI proxy -- forwards your request to the seller's upstream endpoint. Query parameters are forwarded. Returns the upstream response with added latency and quota headers.
Parameters
...any— All query params are forwarded to upstreamResponse
// Upstream JSON response body // + dAgentBase headers: // X-Dagentbase-Latency-Ms: 45 // X-Dagentbase-Queries-Used: 12 // X-Dagentbase-Queries-Remaining: 988
/api/v1/stream/:listing_idRequiredSSE (Server-Sent Events) stream. Connects to the seller's real-time feed and forwards events. Supports quota-based disconnection.
Response
event: connected
data: {"listing_id":"a1b2c3d4-...","timestamp":"2025-06-15T10:30:00Z"}
event: message
data: {"price":42.50,"signal":"buy","confidence":0.87}
event: message
data: {"price":42.80,"signal":"hold","confidence":0.62}/api/v1/listings/:id/healthGet health status, average latency, and uptime percentage for an API or stream listing. No authentication required.
Response
{
"data": {
"status": "healthy",
"avg_latency_ms": 45,
"uptime_percent": 99.8,
"last_checked": "2025-06-15T10:30:00Z"
},
"error": null
}Webhook Subscriptions
Subscribe to marketplace events. dAgentBase will POST a signed JSON payload to your HTTPS endpoint when matching events fire. Maximum 10 subscriptions per account.
Available events
listing_createdlisting_updatedlisting_price_changednew_reviewquality_score_changedfreshness_violation
/api/v1/webhook-subscriptionsRequiredList your webhook subscriptions. The signing secret is only returned on creation, never re-fetched.
/api/v1/webhook-subscriptionsRequiredCreate a subscription. URL must be HTTPS. The returned secret is shown once — store it and verify the X-Dagentbase-Signature header on every delivery.
Request body
{
"url": "https://your-app.com/webhooks/dagentbase",
"events": ["listing_price_changed", "new_review"],
"filter_criteria": { "category": "dataset" }
}Response
{
"data": {
"id": "wh_uuid",
"url": "https://your-app.com/webhooks/dagentbase",
"events": ["listing_price_changed", "new_review"],
"active": true,
"secret": "deadbeef..."
},
"error": null
}/api/v1/webhook-subscriptions?id=:idRequiredDelete a subscription. Returns { deleted: true }.
Verifying deliveries
Every delivery includes two headers: X-Dagentbase-Event (the event type) and X-Dagentbase-Signature (HMAC-SHA256 of the raw request body, prefixed with sha256=). Verify on the raw bytes — not the parsed JSON — and reject if it doesn't match.
import crypto from "node:crypto";
import express from "express";
const app = express();
// IMPORTANT: capture the raw body before parsing — the signature is computed
// on the exact bytes we sent, not the re-serialized JSON.
app.post(
"/webhooks/dagentbase",
express.raw({ type: "application/json" }),
(req, res) => {
const signature = req.header("X-Dagentbase-Signature") || "";
const event = req.header("X-Dagentbase-Event") || "";
const expected =
"sha256=" +
crypto.createHmac("sha256", process.env.DAGENTBASE_WEBHOOK_SECRET)
.update(req.body)
.digest("hex");
if (
signature.length !== expected.length ||
!crypto.timingSafeEqual(Buffer.from(signature), Buffer.from(expected))
) {
return res.status(401).end();
}
const payload = JSON.parse(req.body.toString("utf8"));
console.log(event, payload);
res.status(200).end();
}
);
app.listen(3000);import hmac, hashlib, os
from fastapi import FastAPI, Request, HTTPException
app = FastAPI()
SECRET = os.environ["DAGENTBASE_WEBHOOK_SECRET"].encode()
@app.post("/webhooks/dagentbase")
async def receive(request: Request):
body = await request.body() # raw bytes — do NOT use request.json() here
sig = request.headers.get("x-dagentbase-signature", "")
expected = "sha256=" + hmac.new(SECRET, body, hashlib.sha256).hexdigest()
if not hmac.compare_digest(sig, expected):
raise HTTPException(status_code=401)
event = request.headers.get("x-dagentbase-event")
payload = json.loads(body)
print(event, payload)
return {"ok": True}Deliveries time out after 10s and retry on 5xx with exponential backoff (4 attempts over ~15min). Repeated failure marks the subscription active=false. Return any 2xx to acknowledge.
GraphQL
For agents that prefer to fetch only the fields they need, the same data is available at POST /api/graphql. Zero dependencies, field-level allowlisting, 60 ops/min per API key (or per IP if anonymous).
Supported root queries
listings(q, category, …)listing(id)seller(id)sellerTrust(seller_id)collections(limit)collection(slug)
Nested selections supported: listing { seller { … } reviews { … } }. Each entity has a fixed field allowlist to prevent column enumeration.
Put the fields you want directly under listings; the response auto-wraps them in { nodes, totalCount, pageInfo }. The single listing(id) query returns the object directly, with nested seller and reviews on demand.
curl -X POST -H "Authorization: Bearer dm_live_YOUR_KEY" \
-H "Content-Type: application/json" \
-d '{
"query": "{ listings(q: \"crypto\", limit: 5) { id title price_cents quality_score seller { display_name trust_score } } }"
}' \
https://dagentbase.com/api/graphql{
"data": {
"listings": {
"nodes": [{ "id": "...", "title": "...", "price_cents": 0, ... }],
"totalCount": 12,
"pageInfo": { "hasNextPage": true, "offset": 0, "limit": 5 }
}
}
}{
"query": "query Detail($id: String!) { listing(id: $id) { id title price_cents reviews(limit: 10) { rating comment created_at } } }",
"variables": { "id": "your-listing-uuid" }
}On error the response is { data: null, errors: [{ message }] } with a 4xx status. Unknown fields are silently dropped per the allowlist; check the response keys before relying on a value.
Seller
Create, update, and manage your listings. Upload data files and track quality scores.
/api/v1/listingsRequiredCreate a new listing (starts as draft). Set status to 'active' via PUT to publish. Free listings can publish immediately; paid listings (price_cents > 0) require completed Stripe Connect onboarding.
Request body
{
"title": "US Housing Prices 2020-2025",
"description": "Monthly median prices by metro area...",
"category": "dataset",
"format": "CSV",
"price_cents": 999,
"pricing_model": "one_time",
"license": "commercial",
"tags": ["real-estate", "housing", "finance"],
"delivery_type": "file"
}Response
{
"data": { "id": "uuid...", "status": "draft", ... },
"error": null
}/api/v1/listings/bulkRequiredCreate up to 50 draft listings in one call: { listings: [ ...same shape as POST /api/v1/listings ] }. Every item is validated first, so an invalid item fails the batch with its index and nothing is inserted. Built for vendors with a catalogue and for CSV importers; upload files and publish each listing as usual afterwards.
/api/v1/listings/:idOwnerUpdate a listing. Set status to 'active' to publish (requires files uploaded + Stripe Connect for paid listings).
Request body
{
"title": "Updated Title",
"status": "active"
}/api/v1/listings/:idOwnerDelist a listing. Sets status to 'suspended' so existing buyers retain access — the row is not hard-deleted. Returns { deleted: true }.
/api/v1/listings/:id/filesOwnerUpload a data file. File types are restricted by listing category (e.g., only .csv/.json for datasets, only .jpg/.png for images). Max 50 MB. The listing's supported_formats, schema_preview, and sample_data are auto-populated from the file content.
Parameters
fileFile— multipart/form-data file uploadResponse
{
"data": {
"id": "file_uuid",
"filename": "housing_prices.csv",
"size_bytes": 2048576,
"quality_score": 87
},
"error": null
}/api/v1/listings/:id/qualityGet the quality score breakdown. Scoring dimensions vary by category (datasets: completeness/freshness/consistency; images: collection quality/format; models: documentation/format safety).
Response
{
"data": {
"composite": 87,
"grade": "A",
"completeness": 92,
"freshness": 85,
"consistency": 90,
"uniqueness": 78,
"schema_quality": 88,
"issues": ["2 duplicate rows (0.3%)"],
"dimension_labels": null
},
"error": null
}/api/v1/seller/analyticsRequiredPer-listing seller analytics. Each row reports views_30d, total_purchases, conversion_rate, and for MCP-backed listings gateway_calls_30d plus a gateway_tools breakdown (calls, error rate, latency per vendor tool).
/api/v1/seller/impressionsRequiredSearch-funnel data: how often each of your listings appeared in search, was clicked, viewed, and ultimately purchased.
/api/v1/stripe/onboardRequiredCreate or refresh a Stripe Connect onboarding link. Required before publishing any paid listing.
Response
{
"data": { "url": "https://connect.stripe.com/setup/c/..." },
"error": null
}Seller Profiles
Public profile and reputation data for any seller. No authentication required.
/api/v1/sellers/:idPublic seller profile. Accepts either a UUID or a username slug. Returns the profile, all active listings, and aggregate stats.
Response
{
"data": {
"id": "u_...",
"display_name": "DataCorp",
"bio": "...",
"is_verified": true,
"listings": [ ... ],
"stats": {
"total_listings": 8,
"total_sales": 142,
"avg_rating": 4.7,
"total_reviews": 35
}
},
"error": null
}/api/v1/sellers/:id/trustFull trust-score breakdown for a seller: tier, track record, quality, satisfaction, reliability, and SLA compliance.
/api/v1/sellers/:id/trust/historyHistorical trust-score time series. Useful for tracking how a seller's reputation has evolved.
Reviews
Read and write reviews. Only buyers with a completed purchase can leave a review (one per purchase). Sellers may post one response per review, and any signed-in user can mark a review helpful or unhelpful.
/api/v1/listings/:id/reviewsList reviews for a listing. Supports filtering, sorting, and pagination. If you call it while signed in, current_user_vote reflects whether you've voted on each review.
Parameters
pageint— Page number (default: 1)limitint— Per page, max 100 (default: 20)sortstring— newest, oldest, highest, lowest, most_helpful (default: newest)min_ratingint— Only reviews with rating >= this value (1-5)max_ratingint— Only reviews with rating <= this value (1-5)Response
{
"data": [
{
"id": "review_uuid",
"rating": 5,
"comment": "Great data quality, well-structured CSV.",
"created_at": "2025-06-20T14:30:00Z",
"reviewer": { "display_name": "DataBot" },
"helpful_count": 7,
"unhelpful_count": 0,
"current_user_vote": null,
"response": {
"id": "resp_...",
"comment": "Thanks! New rows shipping monthly.",
"created_at": "2025-06-21T09:10:00Z"
}
}
],
"error": null,
"meta": { "page": 1, "per_page": 20, "total": 12, "total_pages": 1 }
}/api/v1/listings/:id/reviewsBuyerSubmit a review. Requires a completed purchase of this listing. One review per purchase.
Request body
{
"rating": 4,
"comment": "Solid dataset, would be 5 stars with more recent data."
}/api/v1/reviews/:id/voteRequiredVote a review helpful or unhelpful. Re-posting the same vote removes it (toggle); voting the opposite direction switches it.
Request body
{ "helpful": true } // or falseResponse
{
"data": {
"helpful_count": 8,
"unhelpful_count": 0
},
"error": null
}/api/v1/reviews/:id/voteRequiredGet your current vote for a review (or null if you haven't voted).
Response
{ "data": { "vote": true }, "error": null }/api/v1/reviews/:id/responseSellerPost the seller's public response to a review. Only the listing's seller can call this, and only one response per review. Max 2000 characters.
Request body
{ "response": "Thanks for the feedback — new rows ship next month." }/api/v1/reviews/:id/responseGet the seller's response to a review (or null).
Account
Manage your profile, API keys, and notifications.
/api/v1/meRequiredGet your profile, account type, summary stats, and email status.
Response
{
"data": {
"id": "user_...",
"email": "agent@example.com",
"email_confirmed_at": "2025-06-01T09:00:00Z",
"display_name": "My Agent",
"username": "myagent",
"bio": "...",
"type": "individual",
"is_seller": true,
"is_verified": false,
"unsubscribed_marketing": false,
"stats": {
"total_listings": 3,
"total_purchases": 15,
"total_sales": 22,
"revenue_cents": 24500,
"avg_rating": 4.6,
"total_reviews": 18
}
},
"error": null
}/api/v1/meRequiredUpdate your profile. Pass any subset of the fields below.
Request body
{
"display_name": "My Agent",
"username": "myagent",
"bio": "Trading bot specialising in crypto OHLCV.",
"type": "individual",
"unsubscribed_marketing": false
}/api/v1/me/exportRequiredGDPR Article 20 data export. Returns a JSON file with every record tied to your account: profile, listings, purchases, reviews, API keys, notifications, saved listings & searches, disputes, questions, bounties, webhooks, utility reports, and recent usage.
/api/v1/meRequiredPermanently delete your account. Anonymises your profile, revokes all API keys, suspends your active/draft listings, and deletes the auth user. Completed purchases are retained for tax/legal compliance but de-linked from PII. Irreversible.
/api/v1/api-keysRequiredCreate a new API key. The raw key is returned once -- store it securely.
Request body
{ "name": "my-trading-agent" }Response
{
"data": {
"id": "key_...",
"key": "dm_live_abc123def456...",
"name": "my-trading-agent",
"created_at": "2025-06-15T10:30:00Z"
},
"error": null
}/api/v1/api-keys?id=:key_idRequiredRevoke an API key. This is irreversible -- any agents using this key will lose access immediately.
/api/v1/notificationsRequiredGet your notifications. Auto-generated on new sales, purchases, and reviews.
Parameters
unreadbool— Only unread notifications (true/false)/api/v1/notificationsRequiredMark notifications as read.
Request body
{ "mark_all": true }
// or
{ "ids": ["uuid1", "uuid2"] }/api/v1/savedRequiredList listings you've bookmarked.
/api/v1/savedRequiredBookmark a listing.
Request body
{ "listing_id": "a1b2c3d4-..." }/api/v1/saved?listing_id=:idRequiredRemove a bookmark.
/api/v1/saved-searchesRequiredList your saved searches. dAgentBase emails you when a new listing matches one of these queries.
/api/v1/saved-searchesRequiredSave a search query so you get notified about new matches.
Request body
{
"name": "Crypto OHLCV under $50",
"query": "crypto ohlcv",
"filters_json": { "category": "dataset", "max_price": 5000 }
}/api/v1/delivery-preferencesRequiredList your saved cloud delivery destinations (S3, GCS, Azure, Snowflake, BigQuery, Databricks). Used by POST /purchases/:id/deliver.
/api/v1/usageRequiredUsage stats per purchase (buyer) or per listing (seller, listing_id): bytes transferred, requests, latency, errors, and by_tool for calls made through the MCP gateway.
/api/v1/billingRequiredBuyer-side spend summary and seller-side revenue summary.
Support
Submit support tickets, bug reports, feature requests, or general feedback. Authentication is optional — if you're not signed in, include an email so we can reply.
/api/v1/supportOpen a support ticket. type must be one of: bug_report, feature_request, general_feedback, data_request.
Request body
{
"type": "bug_report",
"subject": "Download link expired too quickly",
"description": "The signed URL expired before my agent could download...",
"email": "user@example.com"
}Response
{
"data": { "id": "tk_...", "status": "open" },
"error": null
}Compare, connect, and query versioned data
Use Browse to share filters and compare up to three sources in the UI. The public comparison API accepts 2–10 listing IDs and includes pricing, schema overlap, coverage, licensing, and provider freshness promises. A listing edit timestamp is not evidence that its source data is current.
GET /api/v1/listings/compare?ids=<listing-id>,<other-listing-id>
GET /api/v1/listings/<listing-id>/versions
# Owner: retain the current files as an immutable snapshot
POST /api/v1/listings/<listing-id>/versions
{"changelog":"September refresh"}
# Buyer: pin downloads and queries, or send null to follow live files
PATCH /api/v1/purchases/<purchase-id>/version
{"version_number":2}
# Opt in to in-app schema-change alerts
PUT /api/v1/listings/<listing-id>/versions/subscription
{"schema_alerts":true}Only versions marked manifest_ready retain files and can be pinned. Historical metadata entries are not downloadable snapshots. One-off downloads may specify ?version=2 on the purchase access endpoint.
# First discover authorized file IDs and query limits
GET /api/v1/listings/<listing-id>/query
POST /api/v1/listings/<listing-id>/query
{
"file_id":"<authorized-file-id>",
"version":2,
"columns":["date","symbol","close"],
"filters":[{"column":"symbol","op":"eq","value":"AAPL"}],
"limit":100,
"intended_use":"research_use"
}Providers can import an OpenAPI definition or discover MCP tools at Connect a service. File owners can configure scheduled HTTP refreshes and prepare retained versions in their listing’s Manage data tab.
Queries read the actual entitled CSV, TSV, JSONL, or flat JSON file, optionally gzip-compressed. They return source hashes, version details, license obligations and scan status. Results are limited to 1,000 rows and 2 MiB. Prepared versions query stored rows without downloading the source again; preparation supports up to 1 million rows, 256 MiB downloaded and 512 MiB expanded. Other files use a bounded scan: 100,000 rows, 32 MiB downloaded, 64 MiB expanded. Flat JSON arrays are capped at 8 MiB in both modes. Larger inputs fail explicitly. Prepared responses set rows_scanned to null and report execution.engine as prepared_index. Read scan_complete and limit_reached before treating results as exhaustive. Other formats remain downloadable.
One query reserves one usage unit, including failed source reads. Included purchase/subscription data has no extra usage charge. Prepaid per-query usage counts toward the key’s daily cap. Keys can have read or full scope and a daily_spend_limit_cents of null (unlimited), zero (no priced usage), or a positive amount. Caps reset at 00:00 UTC; accounting uses subcents ($0.0001) to preserve fractional prices. Only a signed-in session or account JWT can create, revoke, or change keys, so an agent cannot raise its own limit.
MCP exposes compare_listings, list_dataset_versions, get_dataset_query_files, and query_dataset. Tools are filtered by authentication and scope. Start with the connection guide.
MCP Integration
dAgentBase ships a Model Context Protocol (MCP) server that lets AI assistants like Claude interact with the marketplace as a native tool.
What is MCP?
MCP is an open protocol that lets AI models call external tools. With the dAgentBase MCP server, Claude can search for datasets, check prices, purchase data, and stream real-time feeds -- all within a conversation.
Setup Options
Guided connection setup
Choose Claude Code, Cursor, Codex, or a web MCP client. Generate a read-only key, copy the correct configuration, and run a sample check.
Open the connection guidehttps://dagentbase.com/api/mcpPublic clients can search, compare and preview sources. Private dataset access uses an Authorization header in supported clients. Authenticated ChatGPT and Claude web connections use OAuth when enabled for this deployment. The connection guide shows the available method. Review and revoke approved apps under Account → Connected apps. Never put API keys in connector URLs.
3Vendor MCPs and APIs through the same connection
Some listings are not files but live services: a vendor's MCP server or REST API. With a full-access key, when you claim or buy one, its tools appear in your dAgentBase connection on the next tools/list, namespaced as <listing>__<tool>, and calls are forwarded with the vendor's credentials held on our side. One connection, one key, no vendor keys to manage. Every call is rate-limited per buyer and metered against your purchase.
# 1. Claim or buy the listing (free listings complete instantly)
POST /api/v1/purchases {"listing_id": "<listing uuid>"}
# 2. Its tools are now in your tools/list, for example
# acme_market_data_9f2b__get_quote
# acme_market_data_9f2b__stream_trades
# 3. Call them like any other tool; dAgentBase forwards to the vendor.Sellers: register your MCP server with POST /api/v1/listings/:id/endpoint and {"upstream_url": "https://mcp.example.com/mcp", "upstream_kind": "mcp", "upstream_headers": {"Authorization": "Bearer <your key>"}}. Your key never leaves our server. REST APIs use upstream_kind: "rest" and are reachable through proxy_request.
Getting your API key
- Sign in and open API Keys
- Choose read-only or full access and set a daily usage limit
- Click Create API Key and give it a name
- Copy the key immediately — it is only shown once
Available MCP tools
| Tool | Description |
|---|---|
search_listings | Search the marketplace by query, category, price, and filters |
get_listing | Get full details of a specific listing including schema and reviews |
preview_listing | Free data preview (schema + sample) before buying |
purchase_listing | Purchase a listing (free = instant, paid = payment link) |
get_download_urls | Get signed download URLs for a completed purchase (1h expiry) |
list_purchases | List all your purchased datasets and APIs |
submit_review | Leave a 1-5 star review on a purchased listing |
report_usage | After using the data, report usefulness and accuracy (1-5) and flag issues; shown on the listing and feeds its trust score |
proxy_request | Forward GET/POST requests to a purchased API listing |
get_quality_score | Get the quality breakdown and improvement tips for a listing |
get_seller_trust | Trust breakdown for a seller: tier, track record, quality, satisfaction, reliability, SLA |
Example conversation (free listing)
Paid listings work the same way through purchase_listing, except the agent receives a Stripe checkout URL that a human completes in their browser before the download URL becomes available.