Skip to main content
HomeAPI Docs

dAgentBase API Reference

Everything you need to integrate with dAgentBase. Search listings, purchase data, stream real-time feeds, and manage your account programmatically.

Base URLhttps://dagentbase.com/api/v1

New 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

  1. Sign in at dagentbase.com/settings
  2. Scroll to the API Keys section
  3. Click "Create API Key" and give it a name
  4. 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
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.

Example: cURL
curl https://dagentbase.com/api/v1/listings \
  -H "Authorization: Bearer dm_live_abc123..."
Example: JavaScript (fetch)
const res = await fetch("https://dagentbase.com/api/v1/listings", {
  headers: {
    Authorization: "Bearer dm_live_abc123...",
  },
});
const { data, error, meta } = await res.json();
Example: Python (requests)
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 groupLimitWindow
Default (most endpoints)60 requests1 minute
Proxy & stream120 requests1 minute
Webhooks (Stripe)100 requests1 minute
Admin30 requests1 minute
Purchases (POST)10 requests1 minute
Auth (signup / login)10 requests1 minute
API key creation5 requests1 minute
Seed (dev only)3 requests1 hour

Rate limit headers

Every API response includes rate limit information in the headers:

Response headers
X-RateLimit-Limit: 60
X-RateLimit-Remaining: 57
X-RateLimit-Reset: 1719750000

X-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.

429 response
{
  "data": null,
  "error": "Rate limit exceeded. Try again later."
}

// Headers:
// Retry-After: 12
// X-RateLimit-Limit: 60
// X-RateLimit-Remaining: 0

Free-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.

TierClaims / 24hBandwidth / 24hHow to reach this tier
anonymous101 GBSign up via POST /api/v1/auth/signup
email_verified5010 GBWeb signup with confirmed email
oauth_verified10050 GBSign in with GitHub or Google
payment_verifiedunlimited500 GBComplete 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:

Response headers (free claim)
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, seconds

These 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

429 response — claim limit reached
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:

Standard response envelope
{
  "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
  }
}
data

The requested resource or array of resources. null when an error occurs.

error

A human-readable error message. null on success.

meta

Pagination info, total counts, and other request metadata.

Success example
{
  "data": {
    "id": "a1b2c3d4-...",
    "title": "S&P 500 Historical Data",
    "price_cents": 499,
    "category": "dataset"
  },
  "error": null,
  "meta": {}
}
Error example
{
  "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.

CodeNameDescription
400Bad RequestMissing or invalid parameters
401UnauthorizedMissing or invalid API key / JWT
403ForbiddenValid credentials, but insufficient permissions
404Not FoundResource does not exist
409ConflictDuplicate action (e.g. already purchased)
413Payload Too LargeRequest body exceeds 1 MB (JSON) or 50 MB (file upload)
429Too Many RequestsRate limit exceeded. Check the Retry-After header.
500Internal Server ErrorSomething 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.
GET/api/v1/listings

Search and filter listings. Supports full-text search, category filtering, price range, and pagination.

Parameters

qstring— Full-text search query
categorystring— dataset, api, image, database, model, vector_store, other
licensestring— commercial, research_only, open, custom
min_priceint— Minimum price in cents
max_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, webhook
min_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, snapshot
max_stalenessint— Maximum days since last update
regulatory_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 passed
exclusive_onlybool— Only single-buyer / exclusive intel listings
available_onlybool— Hide exclusives already claimed by another buyer
market_tickerstring— Intel listings tagged with this market ticker (e.g. AAPL)
include_trendsbool— Add quality_trend (slope of recent quality scores) to each row
sortstring— created_at, price_cents, quality_score, title, row_count
orderstring— 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 }
}
GET/api/v1/listings/:id

Get 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": {}
}
GET/api/v1/listings/:id/preview

Get 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.

GET/api/v1/collections

List 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 &amp; intraday crypto price feeds.",
      "is_featured": true,
      "listings": [{ "listing": { "id": "...", "title": "..." } }]
    }
  ],
  "error": null,
  "meta": { "page": 1, "per_page": 30, "total": 12, "total_pages": 1 }
}
GET/api/v1/collections/:slug

Get 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.

POST/api/v1/purchasesRequired

Purchase 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
}
GET/api/v1/purchasesRequired

List all your purchases. Includes listing info and purchase status.

Parameters

statusstring— Filter by status: completed, pending, refunded

Response

{
  "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 }
}
GET/api/v1/purchases/:id/accessRequired

Get 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": {}
}
POST/api/v1/purchases/:id/refundRequired

Request 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
}
POST/api/v1/purchases/:id/deliverRequired

Queue 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.

GET/api/v1/disputesRequired

List your disputes (as buyer or seller). Each row includes the listing, both parties, and the most recent message.

POST/api/v1/disputesBuyer

Open 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
}
GET/api/v1/disputes/:idRequired

Get a dispute with the full message thread. Only the buyer, seller, or an admin can read it.

PUT/api/v1/disputes/:idRequired

Take 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"
GET/api/v1/disputes/:id/messagesRequired

Get all messages on a dispute, oldest first.

POST/api/v1/disputes/:id/messagesRequired

Post 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.

GET/api/v1/proxy/:listing_idRequired

API 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 upstream

Response

// Upstream JSON response body
// + dAgentBase headers:
//   X-Dagentbase-Latency-Ms: 45
//   X-Dagentbase-Queries-Used: 12
//   X-Dagentbase-Queries-Remaining: 988
GET/api/v1/stream/:listing_idRequired

SSE (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}
GET/api/v1/listings/:id/health

Get 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_created
  • listing_updated
  • listing_price_changed
  • new_review
  • quality_score_changed
  • freshness_violation
GET/api/v1/webhook-subscriptionsRequired

List your webhook subscriptions. The signing secret is only returned on creation, never re-fetched.

POST/api/v1/webhook-subscriptionsRequired

Create 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
}
DELETE/api/v1/webhook-subscriptions?id=:idRequired

Delete 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.

Node / Express receiver
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);
Python / FastAPI receiver
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.

Search (curl)
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
Response shape
{
  "data": {
    "listings": {
      "nodes": [{ "id": "...", "title": "...", "price_cents": 0, ... }],
      "totalCount": 12,
      "pageInfo": { "hasNextPage": true, "offset": 0, "limit": 5 }
    }
  }
}
One listing with reviews
{
  "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.

POST/api/v1/listingsRequired

Create 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
}
POST/api/v1/listings/bulkRequired

Create 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.

PUT/api/v1/listings/:idOwner

Update a listing. Set status to 'active' to publish (requires files uploaded + Stripe Connect for paid listings).

Request body

{
  "title": "Updated Title",
  "status": "active"
}
DELETE/api/v1/listings/:idOwner

Delist a listing. Sets status to 'suspended' so existing buyers retain access — the row is not hard-deleted. Returns { deleted: true }.

POST/api/v1/listings/:id/filesOwner

Upload 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 upload

Response

{
  "data": {
    "id": "file_uuid",
    "filename": "housing_prices.csv",
    "size_bytes": 2048576,
    "quality_score": 87
  },
  "error": null
}
GET/api/v1/listings/:id/quality

Get 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
}
GET/api/v1/seller/analyticsRequired

Per-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).

GET/api/v1/seller/impressionsRequired

Search-funnel data: how often each of your listings appeared in search, was clicked, viewed, and ultimately purchased.

POST/api/v1/stripe/onboardRequired

Create 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.

GET/api/v1/sellers/:id

Public 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
}
GET/api/v1/sellers/:id/trust

Full trust-score breakdown for a seller: tier, track record, quality, satisfaction, reliability, and SLA compliance.

GET/api/v1/sellers/:id/trust/history

Historical 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.

GET/api/v1/listings/:id/reviews

List 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 }
}
POST/api/v1/listings/:id/reviewsBuyer

Submit 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."
}
POST/api/v1/reviews/:id/voteRequired

Vote a review helpful or unhelpful. Re-posting the same vote removes it (toggle); voting the opposite direction switches it.

Request body

{ "helpful": true }   // or false

Response

{
  "data": {
    "helpful_count": 8,
    "unhelpful_count": 0
  },
  "error": null
}
GET/api/v1/reviews/:id/voteRequired

Get your current vote for a review (or null if you haven't voted).

Response

{ "data": { "vote": true }, "error": null }
POST/api/v1/reviews/:id/responseSeller

Post 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." }
GET/api/v1/reviews/:id/response

Get the seller's response to a review (or null).

Account

Manage your profile, API keys, and notifications.

GET/api/v1/meRequired

Get 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
}
PUT/api/v1/meRequired

Update 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
}
GET/api/v1/me/exportRequired

GDPR 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.

DELETE/api/v1/meRequired

Permanently 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.

POST/api/v1/api-keysRequired

Create 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
}
DELETE/api/v1/api-keys?id=:key_idRequired

Revoke an API key. This is irreversible -- any agents using this key will lose access immediately.

GET/api/v1/notificationsRequired

Get your notifications. Auto-generated on new sales, purchases, and reviews.

Parameters

unreadbool— Only unread notifications (true/false)
PUT/api/v1/notificationsRequired

Mark notifications as read.

Request body

{ "mark_all": true }
// or
{ "ids": ["uuid1", "uuid2"] }
GET/api/v1/savedRequired

List listings you've bookmarked.

POST/api/v1/savedRequired

Bookmark a listing.

Request body

{ "listing_id": "a1b2c3d4-..." }
DELETE/api/v1/saved?listing_id=:idRequired

Remove a bookmark.

GET/api/v1/saved-searchesRequired

List your saved searches. dAgentBase emails you when a new listing matches one of these queries.

POST/api/v1/saved-searchesRequired

Save 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 }
}
GET/api/v1/delivery-preferencesRequired

List your saved cloud delivery destinations (S3, GCS, Azure, Snowflake, BigQuery, Databricks). Used by POST /purchases/:id/deliver.

GET/api/v1/usageRequired

Usage 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.

GET/api/v1/billingRequired

Buyer-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.

POST/api/v1/support

Open 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.

Source discovery and version history
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.

Query a licensed file — read-only keys supported
# 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 guide
Public MCP endpoint
https://dagentbase.com/api/mcp

Public 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.

Turn a vendor on, then use it
# 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

  1. Sign in and open API Keys
  2. Choose read-only or full access and set a daily usage limit
  3. Click Create API Key and give it a name
  4. Copy the key immediately — it is only shown once

Available MCP tools

ToolDescription
search_listingsSearch the marketplace by query, category, price, and filters
get_listingGet full details of a specific listing including schema and reviews
preview_listingFree data preview (schema + sample) before buying
purchase_listingPurchase a listing (free = instant, paid = payment link)
get_download_urlsGet signed download URLs for a completed purchase (1h expiry)
list_purchasesList all your purchased datasets and APIs
submit_reviewLeave a 1-5 star review on a purchased listing
report_usageAfter using the data, report usefulness and accuracy (1-5) and flag issues; shown on the listing and feeds its trust score
proxy_requestForward GET/POST requests to a purchased API listing
get_quality_scoreGet the quality breakdown and improvement tips for a listing
get_seller_trustTrust breakdown for a seller: tier, track record, quality, satisfaction, reliability, SLA

Example conversation (free listing)

You: Find me a dataset with S&P 500 historical prices
Claude: I found 3 listings. The top result is "Sample S&P 500 Daily OHLCV 2000-2025" — free, community-licensed, quality grade A (94/100). Want me to preview the data or import it?
You: Preview it first
Claude: Here's the schema: date (date), open (number), high (number), low (number), close (number), volume (integer). Sample shows 6,284 rows from 2000-01-03 to 2025-03-28. Looks like clean daily data. Want me to import it?
You: Yes, import and download
Claude: Done. Download URL ready (expires in 1 hour): sp500_daily_ohlcv.csv (2.1 MB)

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.