Skip to content
nexqdata
Developers

NexqData, from your code.

Trigger agents, search multiple sources, monitor execution, and retrieve structured data — from your own systems, with no browser in the loop.

Request
POST/api/scraper-agents/{externalAgentId}/start-job
X-Api-Key: nxd_live_••••••••3f9a
Content-Type: application/json
Response
200 OK184 ms
{  "success": true,  "message": "Job started.",  "data": {    "startedAt": "2026-09-23T02:00:04Z"  }}
The job continues in the background — keep its id, poll its status, then download its data.
Style
REST · JSON
Auth
X-Api-Key or Bearer
Runs
Asynchronous
Limit
60 runs / min

Quick start

From key to dataset in three calls.

  1. 1

    Create an API key

    In your workspace, open API keys and create one. It's shown once — store it as NEXQDATA_API_KEY.

  2. 2

    Start a job

    POST to an agent you have access to. The job starts at once and completes in the background.

  3. 3

    Collect the results

    When the job finishes, download its data as CSV, JSON, or Excel.

Step by step, in cURL, C#, JavaScript, and Python: the Quickstart.

~/integrations — zsh — 96×28
# 1 · Use the key you created in your workspace$ export NEXQDATA_API_KEY=nxd_live_••••••••3f9a# 2 · Start a job, and keep its id$ JOB_ID=$(curl -s -X POST "https://api.nexqdata.io/api/scraper-agents/$EXTERNAL_AGENT_ID/start-job" \>   -H "X-Api-Key: $NEXQDATA_API_KEY" \>   -H "Content-Type: application/json" \>   -d '{"inputParameters": "{\"LastName\":\"Doe\"}"}' | jq -r '.data.agentJobHistoryId')# 3 · Check on it until it's done$ curl -s "https://api.nexqdata.io/api/scraper-agents/jobs?jobId=$JOB_ID" \>   -H "X-Api-Key: $NEXQDATA_API_KEY" | jq '.data.items[0] | {statusName, isTerminal, totalDataCount}'{  "statusName": "Succeeded",  "isTerminal": true,  "totalDataCount": 1248}# 4 · Collect the results$ curl -s "https://api.nexqdata.io/api/scraper-agents/jobs/$JOB_ID/export" \>   -H "X-Api-Key: $NEXQDATA_API_KEY" -o results.csv$ wc -l results.csv    1249 results.csv$ 

Webhooks

Know the moment a job finishes.

Add an HTTPS endpoint, choose its events, and NexqData POSTs a signed JSON event when a job, pipeline run, or group run finishes — or when a schedule can’t start. Then download the data. Poll when you want to; subscribe when you’d rather be told.

job.succeeded
A job finished and its data is ready to download.
job.failed
A job finished without succeeding; the event says why.
pipeline_run.succeeded
Every stage of a pipeline run succeeded.
pipeline_run.failed
A pipeline run stopped at a failed stage.
group_run.completed
Every agent in a group run has finished; the event says how many succeeded.
schedule.failed
A schedule came due but couldn't start its run; the event says why.
Signed
Every delivery carries an HMAC-SHA256 signature over its timestamp and body, so you can check it came from us and wasn't replayed.
Retried
A delivery that isn't answered with a 2xx is retried 6 more times over about a day: after 1m, 5m, 30m, 2h, 6h, and 12h.
Traceable
Every attempt is logged with its status and timing. Send a test event, or redeliver one, from the dashboard or the API.
HTTPS only
Endpoints must use https://. Each user can have up to 5, each subscribed to the events it needs.

Set endpoints up in your dashboard under Profile → Webhooks, or with POST /api/webhooks. Each endpoint’s signing secret starts with whsec_ and is shown once.

Payloads, headers, and verification in Python and C#: Webhooks.

Deliveryabridged
POST /your/endpointContent-Type: application/jsonNexqData-Event-Type: job.succeededNexqData-Delivery-Attempt: 1NexqData-Signature: t=1790139851,v1=5f2c9e…
{  "type": "job.succeeded",  "createdAt": "2026-09-23T05:04:11Z",  "data": {    "agentName": "Court records · TX",    "statusName": "Succeeded",    "triggerSource": "Schedule",    "totalDataCount": 1248  }}
Verify the signatureNode.js
import { createHmac, timingSafeEqual } from "node:crypto" const { t, v1 } = Object.fromEntries(  header.split(",").map((part) => part.split("=")),)// secret: the endpoint's whsec_… signing secretconst expected = createHmac("sha256", secret)  .update(`${t}.${rawBody}`)  .digest("hex") const valid = expected.length === v1.length &&  timingSafeEqual(Buffer.from(expected), Buffer.from(v1))

Authentication

One key, in one header.

Per-user keys
Each key belongs to one user and can do only what that user can.
Shown once
Keys are stored as a hash. Copy yours when it's created — it can't be shown again.
Scoped
Limit a key to specific permissions — agents.run covers running agents and collecting their data.
Revocable
Revoke a key at any time. Creating a new key replaces your active one by default.

Creating, scoping, and rotating keys: Authentication. How keys are stored is covered on our Security page.

Send your keyeither form works
# Header
X-Api-Key: nxd_live_••••••••3f9a

# Or bearer
Authorization: Bearer nxd_live_••••••••3f9a

# The scope an integration needsagents.run

API concepts

Six things you’ll work with.

Agent
Collection for one source, engineered and maintained by us. You run it; it has a version.
Job
One start of an agent. It returns immediately and finishes in the background; its runs and data are grouped under it.
Agent group
Agents that cover the same kind of record, run together with one set of inputs. One status per source.
Pipeline
Agents in a fixed order. Each stage starts after the last succeeds; a failure stops the chain.
Dataset
A run's structured output. Private to you by default, shareable with your company.
API key
How your code authenticates. Per-user, scoped, revocable.

Errors & rate limits

Predictable when things go wrong.

Every error uses the same envelope: a readable message and a stable code your code can branch on.

Error envelope404
{  "success": false,  "message": "Run not found.",  "errorCode": "RUN_NOT_FOUND"}
Rate limited429
HTTP/1.1 429 Too Many RequestsRetry-After: 23
StatusCodeMeaning
400—The request is invalid, or the agent couldn't be started; the message says why.
401—Missing, invalid, or revoked API key.
402PAYMENT_REQUIREDThe run's data exists, but its final payment hasn't settled.
404RUN_NOT_FOUNDThe run doesn't exist, or you don't have access to it.
410EXPORT_EXPIREDThe export was removed by your retention period.
429—Rate limited. Wait for the Retry-After seconds, then retry.

Rate limits

Starting jobs and runs60 per minute · per user

The platform default, counted separately for each user. Over the limit, requests get a 429 with a Retry-After header — wait that many seconds, then retry.

Every error code, and retry examples: Errors and Rate limits.

Start building.

Create a key and make your first call. The docs cover every endpoint, with examples in cURL, C#, JavaScript, and Python.

Need an agent for a new source? Talk to an engineer.