Getting started

API reference

Every endpoint at a glance, plus the base URL, auth, versioning, request tracing, and the rate and quota model.

The Sprouts Data Platform API is a JSON HTTP API over companies, people, and seven document corpora. Pick an endpoint below, or read the essentials further down: the base URL, the one auth header, versioning and request tracing apply to every endpoint, so if you read one reference page before integrating, make it this one.

Endpoints#

Every route, with its scope and metering
Method & pathWhat it doesScopeMetered
POST /v1/searchSearch one categorydsp.search.readYes (dsp.search.fast / .auto / .deep)
POST /v1/similarCompany look-alikes from anchorsdsp.search.readYes (dsp.similar)
POST /v1/entities/{category}Records by id — 9 routes (companies, persons, documents)dsp.entities.readYes (dsp.entities)
POST /v1/relationshipsPeople connecting two companies, across the affiliation graphdsp.search.readYes (dsp.relationships)
POST /v1/relationships/reachWho one named person can reach at a companydsp.search.readYes (dsp.relationships)
POST /v1/relationships/institutionsThe employers and schools two companies sharedsp.search.readYes (dsp.relationships)
POST /v1/relationships/askA relationship question in words, routed for youdsp.search.readYes (dsp.relationships.ask)
POST /v1/org-chartOne company's people by department × seniority — plus /departments and /locationsdsp.search.readYes (dsp.org_chart)
POST /v1/agents/runsStart an agent run (async)dsp.agents.writeYes (dsp.agent.run.* — held on create, settled when the finished run is read)
POST /v1/agents/runs/{run_id}/cancelCancel a rundsp.agents.writeFree (a cancelled run is not charged)
GET /v1/agents/runs…List runs, read one, page its results or stream its eventsdsp.agents.read or dsp.agents.writeFree (the run pays once, at settle)
GET /v1/coverageWhat the index holds, per corpusdsp.search.readFree
GET /v1/search/filters/{name}Values a company/person filter accepts — plus /{category}/{name} for documentsdsp.search.readFree
GET /v1/sorts/{category}Fields a search can be ordered bydsp.search.readFree
GET /v1/creditsTenant credit balancedsp.usage.readFree
GET /v1/keys/usageCalling key's spend (key-only)dsp.usage.readFree
POST /v1/billing/top-up/intentsStart a credit top-up, paid in the browser — plus GET …/intents/{topup_id} for its statusdsp.usage.readFree (the top-up itself is a purchase)
POST /v1/members/resolveResolve one email address to a member of your organisationdsp.search.read or dsp.agents.writeFree
GET /v1/usage/historyYour own runs, newest firstdsp.usage.readFree
GET /v1/usage/history/{run_id}One run, with its stored snapshotdsp.usage.readFree
GET /v1/usage/metricsYour run counts and credits per daydsp.usage.readFree
POST /v1/feedbackReport a wrong, missing or stale result — plus GET /v1/feedback and /tags (/tags needs no credential)dsp.search.read or dsp.usage.readFree
PUT /v1/feedback/votesVote on a result set, or flag one record — plus GET /v1/feedback/votesdsp.search.read or dsp.usage.readFree
/v1/lists*Create, rename and delete saved lists; add, remove and read their itemsdsp.search.read or dsp.entities.readFree
POST /v1/lists/{list_id}/export, POST /v1/search/exportCSV export — not switched on yet (404 export.not_enabled)dsp.search.read or dsp.entities.read—

Base URL#

https://api.sproutsdata.ai

All paths are relative to it. The OpenAPI document lives at /openapi.json (interactive docs at /docs) and is generated from the running service, so it is always current. It lists only the routes an API key can call, declares the optional Idempotency-Key header on every billed route, and names each operation's accepted scopes in x-scopes. Its info.version is the API contract version, currently 1.0.0.

Versioning#

Every endpoint is under /v1. Within v1, changes are additive only:

  • New fields may appear in responses; existing fields never change meaning or disappear.
  • Fields reserved for future use are present from day one and serialize as explicit null (e.g. attribution[].url) — the day they carry values is a data change, not an API change.
  • Enums (category, error code, degradation reason) are closed sets; members are added deliberately and never removed.

If something does have to be removed or changed in a way that isn't additive, it is announced in the changelog at least 90 days before the change, and the old behaviour keeps working until then. Two such removals have already been made, both recorded in the changelog: the prior_company filter and from_my_company.

Authentication#

One header on every request:

X-API-Key: $SPROUTS_API_KEY

A key goes in X-API-Key only: Authorization: Bearer is for OAuth tokens, and a key sent there gets the generic 401 auth.unauthorized. See Authentication for prefixes, scopes, and key management.

Content types#

  • Requests: application/json. Request bodies reject unknown fields with a 422: a parameter the API silently ignored would let you believe you asked for something you didn't.
  • Success responses: application/json.
  • Error responses: application/problem+json (RFC 9457) — see Errors.

Request tracing#

Every response, success and error, carries a request id: in the body (meta.request_id / request_id) and as the X-Request-Id response header.

You may send your own X-Request-Id (≤128 chars, [A-Za-z0-9_.:-]) and it is echoed back, so your logs and ours share a key.

Rates, quotas, and credits#

Three separate mechanisms, with distinct answers:

MechanismStatusFamilyFixed by
Rate/quota limits429quota.*Waiting — honour Retry-After
Credits402credits.insufficientBuying — never retry
Upstream failures503/504upstream.*Retrying after Retry-After — nothing was charged
  • Metered endpoints charge only once the response is ready, so an error, including a 503 or 504, is not charged. The one exception is 503 credits.unavailable: the billing service could not confirm the charge, so the request may have been charged. Retry it with the same Idempotency-Key and rows already paid for are not charged again. See credits.unavailable.
  • Test keys (sk_dsp_test_) are metered at zero cost.

Rate limits

There is no per-key rate limit on the REST API today, for live or test keys. Build your client to honour a 429 with Retry-After anyway: back off, then retry after the number of seconds the header gives. Limits may be introduced later, and they will be announced in the changelog first.

The limits that do exist today:

  • Agent runs. POST /v1/agents/runs refuses a start with 429 quota.entity_ceiling once a credential has been shown 5,000,000 distinct entities in the last 30 days, and with 429 quota.concurrency_exceeded (Retry-After: 30) when more than five runs are being started at the same moment on one credential. See Agent runs.
  • Dashboard sessions. Playground traffic is throttled per signed-in session at 30 requests/minute and 500/day (429 quota.burst_exceeded), and sign-in attempts are throttled too.
  • MCP server. 60 tool calls per minute per credential, answered with a 429 and Retry-After. See MCP limits.

The response envelope is shared by every list-returning endpoint.