Skip to documentation content

API reference

Request fields, response objects, and status codes.

In this guide
  1. 1Canonical OpenAPI contract
  2. 2Endpoints
  3. 3Request fields
  4. 4Response objects
In this guide
  1. 1Canonical OpenAPI contract
  2. 2Endpoints
  3. 3Request fields
  4. 4Response objects

OpenAPI contract

The canonical REST API 1.0.0 contract is an OpenAPI 3.1.0 document. The reference, contract tests, and SDK implementations consume the same source.

Endpoints

MethodPathPurposeSuccess
POST/v1/scrapeCreate a scraping job202
GET/v1/jobsList jobs200
GET/v1/jobs/{job_id}Get a job200
DELETE/v1/jobs/{job_id}Cancel a job200
GET/v1/jobs/{job_id}/streamStream completed job data200
GET/v1/eventsList delivery events200
GET/v1/webhooks/deliveriesList webhook deliveries200
GET/v1/observability/metricsRead API metrics200
GET/v1/datasets/{dataset_id}Get a materialized dataset200
POST/v1/datasets/{dataset_id}/exportsCreate a dataset export202
GET/v1/datasets/{dataset_id}/exports/{export_id}Get a dataset export200
GET/v1/downloads/{export_id}Download a completed dataset export200

Scrape request fields

FieldTypeRequired
urlstringyes
formatsstring[]yes
webhook_urlstringno
metadataobjectno

Request examples

cURL
curl -X POST https://api.nordicdevhouse.com/v1/scrape \\
  -H "Authorization: Bearer api_live_••••••••" \\n  -H "Content-Type: application/json" \\n  -H "Idempotency-Key: docs-example-001" \\
  -d '{
  "url": "https://example.com/products",
  "formats": [
    "json"
  ],
  "metadata": {
    "import_id": "catalog-2026-08-11"
  }
}'
TypeScript
const result = await ndh.request({
  method: 'POST',
  path: '/v1/scrape',
  body: { url: "https://example.com/products", formats: ["json"], metadata: { import_id: "catalog-2026-08-11" } }
});
Python
result = ndh.request(
    method="POST",
    path="/v1/scrape",
    body={
  "url": "https://example.com/products",
  "formats": [
    "json"
  ],
  "metadata": {
    "import_id": "catalog-2026-08-11"
  }
}
)

Job response object

FieldTypeRequired
idstringyes
statusJobStatusyes
created_atstringyes
completed_atstring | nullno
retention_expires_atstring | nullno
request_idstringyes
recordsintegerno
dataset_idstring | nullno
dataobjectno
warningsarrayno
last_event_idstring | nullno
metadataobjectno

Create a scraping job details

POST /v1/scrapeSandbox
Create a scraping job

Creates one idempotent scraping job. The response is asynchronous; use the returned job ID or a verified webhook to observe completion.

Responses
202 Job accepted
""
400
{
  "error": {
    "code": "request_failed",
    "message": "Request failed with HTTP 400",
    "request_id": "req_example"
  }
}
Generated from the status contract
401
{
  "error": {
    "code": "unauthorized",
    "message": "Request failed with HTTP 401",
    "request_id": "req_example"
  }
}
Generated from the status contract
429
{
  "error": {
    "code": "rate_limited",
    "message": "Request failed with HTTP 429",
    "request_id": "req_example"
  }
}
Generated from the status contract
500
{
  "error": {
    "code": "server_error",
    "message": "Request failed with HTTP 500",
    "request_id": "req_example"
  }
}
Generated from the status contract
cURL
curl -X POST https://api.nordicdevhouse.com/v1/scrape \\
  -H "Authorization: Bearer api_live_••••••••" \\n  -H "Content-Type: application/json" \\n  -H "Idempotency-Key: docs-example-001" \\
  -d '{
  "url": "https://example.com/products",
  "formats": [
    "json"
  ],
  "metadata": {
    "import_id": "catalog-2026-08-11"
  }
}'
TypeScript
const result = await ndh.request({
  method: 'POST',
  path: '/v1/scrape',
  body: { url: "https://example.com/products", formats: ["json"], metadata: { import_id: "catalog-2026-08-11" } }
});
Python
result = ndh.request(
    method="POST",
    path="/v1/scrape",
    body={
  "url": "https://example.com/products",
  "formats": [
    "json"
  ],
  "metadata": {
    "import_id": "catalog-2026-08-11"
  }
}
)

List jobs details

GET /v1/jobsSandbox
List jobs

Returns jobs in reverse creation order with cursor pagination.

Responses
200 Job page
""
400
{
  "error": {
    "code": "request_failed",
    "message": "Request failed with HTTP 400",
    "request_id": "req_example"
  }
}
Generated from the status contract
401
{
  "error": {
    "code": "unauthorized",
    "message": "Request failed with HTTP 401",
    "request_id": "req_example"
  }
}
Generated from the status contract
429
{
  "error": {
    "code": "rate_limited",
    "message": "Request failed with HTTP 429",
    "request_id": "req_example"
  }
}
Generated from the status contract
500
{
  "error": {
    "code": "server_error",
    "message": "Request failed with HTTP 500",
    "request_id": "req_example"
  }
}
Generated from the status contract

Get a job details

GET /v1/jobs/{job_id}Sandbox
Get a job

Returns the current state and, when completed, the validated result.

Responses
200 Current job
""
400
{
  "error": {
    "code": "request_failed",
    "message": "Request failed with HTTP 400",
    "request_id": "req_example"
  }
}
Generated from the status contract
401
{
  "error": {
    "code": "unauthorized",
    "message": "Request failed with HTTP 401",
    "request_id": "req_example"
  }
}
Generated from the status contract
404
{
  "error": {
    "code": "not_found",
    "message": "Request failed with HTTP 404",
    "request_id": "req_example"
  }
}
Generated from the status contract
429
{
  "error": {
    "code": "rate_limited",
    "message": "Request failed with HTTP 429",
    "request_id": "req_example"
  }
}
Generated from the status contract
500
{
  "error": {
    "code": "server_error",
    "message": "Request failed with HTTP 500",
    "request_id": "req_example"
  }
}
Generated from the status contract

Cancel a job details

DELETE /v1/jobs/{job_id}Sandbox
Cancel a job

Cancels queued or running work. Completed, failed, and already canceled jobs are returned unchanged.

Responses
200 Canceled or already terminal job
""
400
{
  "error": {
    "code": "request_failed",
    "message": "Request failed with HTTP 400",
    "request_id": "req_example"
  }
}
Generated from the status contract
401
{
  "error": {
    "code": "unauthorized",
    "message": "Request failed with HTTP 401",
    "request_id": "req_example"
  }
}
Generated from the status contract
404
{
  "error": {
    "code": "not_found",
    "message": "Request failed with HTTP 404",
    "request_id": "req_example"
  }
}
Generated from the status contract
409
{
  "error": {
    "code": "conflict",
    "message": "Request failed with HTTP 409",
    "request_id": "req_example"
  }
}
Generated from the status contract
429
{
  "error": {
    "code": "rate_limited",
    "message": "Request failed with HTTP 429",
    "request_id": "req_example"
  }
}
Generated from the status contract
500
{
  "error": {
    "code": "server_error",
    "message": "Request failed with HTTP 500",
    "request_id": "req_example"
  }
}
Generated from the status contract

Stream completed job data details

GET /v1/jobs/{job_id}/streamSandbox
Stream completed job data

Returns one JSON record per line using application/x-ndjson after the job has completed.

Responses
200 NDJSON result stream
""
400
{
  "error": {
    "code": "request_failed",
    "message": "Request failed with HTTP 400",
    "request_id": "req_example"
  }
}
Generated from the status contract
401
{
  "error": {
    "code": "unauthorized",
    "message": "Request failed with HTTP 401",
    "request_id": "req_example"
  }
}
Generated from the status contract
404
{
  "error": {
    "code": "not_found",
    "message": "Request failed with HTTP 404",
    "request_id": "req_example"
  }
}
Generated from the status contract
409
{
  "error": {
    "code": "conflict",
    "message": "Request failed with HTTP 409",
    "request_id": "req_example"
  }
}
Generated from the status contract
410
{
  "error": {
    "code": "request_failed",
    "message": "Request failed with HTTP 410",
    "request_id": "req_example"
  }
}
Generated from the status contract
413
{
  "error": {
    "code": "request_failed",
    "message": "Request failed with HTTP 413",
    "request_id": "req_example"
  }
}
Generated from the status contract
429
{
  "error": {
    "code": "rate_limited",
    "message": "Request failed with HTTP 429",
    "request_id": "req_example"
  }
}
Generated from the status contract
500
{
  "error": {
    "code": "server_error",
    "message": "Request failed with HTTP 500",
    "request_id": "req_example"
  }
}
Generated from the status contract

List delivery events details

GET /v1/eventsSandbox
List delivery events

Returns signed webhook-worthy events in cursor-paginated order.

Responses
200 Event page
""
400
{
  "error": {
    "code": "request_failed",
    "message": "Request failed with HTTP 400",
    "request_id": "req_example"
  }
}
Generated from the status contract
401
{
  "error": {
    "code": "unauthorized",
    "message": "Request failed with HTTP 401",
    "request_id": "req_example"
  }
}
Generated from the status contract
429
{
  "error": {
    "code": "rate_limited",
    "message": "Request failed with HTTP 429",
    "request_id": "req_example"
  }
}
Generated from the status contract
500
{
  "error": {
    "code": "server_error",
    "message": "Request failed with HTTP 500",
    "request_id": "req_example"
  }
}
Generated from the status contract

List webhook deliveries details

GET /v1/webhooks/deliveriesSandbox
List webhook deliveries

Returns delivery attempts and dead-letter state for local or test webhook endpoints.

Responses
200 Webhook delivery list
{
  "data": []
}
400
{
  "error": {
    "code": "request_failed",
    "message": "Request failed with HTTP 400",
    "request_id": "req_example"
  }
}
Generated from the status contract
401
{
  "error": {
    "code": "unauthorized",
    "message": "Request failed with HTTP 401",
    "request_id": "req_example"
  }
}
Generated from the status contract
429
{
  "error": {
    "code": "rate_limited",
    "message": "Request failed with HTTP 429",
    "request_id": "req_example"
  }
}
Generated from the status contract
500
{
  "error": {
    "code": "server_error",
    "message": "Request failed with HTTP 500",
    "request_id": "req_example"
  }
}
Generated from the status contract

Read API metrics details

GET /v1/observability/metricsSandbox
Read API metrics

Returns in-process request counters and durations for the fake API runtime.

Responses
200 Metrics snapshot
""
400
{
  "error": {
    "code": "request_failed",
    "message": "Request failed with HTTP 400",
    "request_id": "req_example"
  }
}
Generated from the status contract
401
{
  "error": {
    "code": "unauthorized",
    "message": "Request failed with HTTP 401",
    "request_id": "req_example"
  }
}
Generated from the status contract
429
{
  "error": {
    "code": "rate_limited",
    "message": "Request failed with HTTP 429",
    "request_id": "req_example"
  }
}
Generated from the status contract
500
{
  "error": {
    "code": "server_error",
    "message": "Request failed with HTTP 500",
    "request_id": "req_example"
  }
}
Generated from the status contract

Get a materialized dataset details

GET /v1/datasets/{dataset_id}Sandbox
Get a materialized dataset

Returns the immutable dataset created by a completed scrape job.

Responses
200 Materialized dataset
""
400
{
  "error": {
    "code": "request_failed",
    "message": "Request failed with HTTP 400",
    "request_id": "req_example"
  }
}
Generated from the status contract
401
{
  "error": {
    "code": "unauthorized",
    "message": "Request failed with HTTP 401",
    "request_id": "req_example"
  }
}
Generated from the status contract
404
{
  "error": {
    "code": "not_found",
    "message": "Request failed with HTTP 404",
    "request_id": "req_example"
  }
}
Generated from the status contract
429
{
  "error": {
    "code": "rate_limited",
    "message": "Request failed with HTTP 429",
    "request_id": "req_example"
  }
}
Generated from the status contract
500
{
  "error": {
    "code": "server_error",
    "message": "Request failed with HTTP 500",
    "request_id": "req_example"
  }
}
Generated from the status contract

Create a dataset export details

POST /v1/datasets/{dataset_id}/exportsSandbox
Create a dataset export

Creates an immutable export from a dataset version.

Responses
202 Export accepted
""
400
{
  "error": {
    "code": "request_failed",
    "message": "Request failed with HTTP 400",
    "request_id": "req_example"
  }
}
Generated from the status contract
401
{
  "error": {
    "code": "unauthorized",
    "message": "Request failed with HTTP 401",
    "request_id": "req_example"
  }
}
Generated from the status contract
404
{
  "error": {
    "code": "not_found",
    "message": "Request failed with HTTP 404",
    "request_id": "req_example"
  }
}
Generated from the status contract
429
{
  "error": {
    "code": "rate_limited",
    "message": "Request failed with HTTP 429",
    "request_id": "req_example"
  }
}
Generated from the status contract
500
{
  "error": {
    "code": "server_error",
    "message": "Request failed with HTTP 500",
    "request_id": "req_example"
  }
}
Generated from the status contract
cURL
curl -X POST https://api.nordicdevhouse.com/v1/datasets/{dataset_id}/exports \\
  -H "Authorization: Bearer api_live_••••••••" \\n  -H "Content-Type: application/json" \\n  -H "Idempotency-Key: docs-example-001" \\
  -d '{
  "format": "json",
  "mode": "snapshot"
}'
TypeScript
const result = await ndh.request({
  method: 'POST',
  path: '/v1/datasets/{dataset_id}/exports',
  body: { format: "json", mode: "snapshot" }
});
Python
result = ndh.request(
    method="POST",
    path="/v1/datasets/{dataset_id}/exports",
    body={
  "format": "json",
  "mode": "snapshot"
}
)

Get a dataset export details

GET /v1/datasets/{dataset_id}/exports/{export_id}Sandbox
Get a dataset export

Returns export state and a short-lived download URL when ready.

Responses
200 Current export
""
400
{
  "error": {
    "code": "request_failed",
    "message": "Request failed with HTTP 400",
    "request_id": "req_example"
  }
}
Generated from the status contract
401
{
  "error": {
    "code": "unauthorized",
    "message": "Request failed with HTTP 401",
    "request_id": "req_example"
  }
}
Generated from the status contract
404
{
  "error": {
    "code": "not_found",
    "message": "Request failed with HTTP 404",
    "request_id": "req_example"
  }
}
Generated from the status contract
429
{
  "error": {
    "code": "rate_limited",
    "message": "Request failed with HTTP 429",
    "request_id": "req_example"
  }
}
Generated from the status contract
500
{
  "error": {
    "code": "server_error",
    "message": "Request failed with HTTP 500",
    "request_id": "req_example"
  }
}
Generated from the status contract

Download a completed dataset export details

GET /v1/downloads/{export_id}Sandbox
Download a completed dataset export

Streams the completed export as JSON, CSV, or opaque Parquet bytes. Download URLs expire independently from export metadata.

Responses
200 Export bytes
[]
400
{
  "error": {
    "code": "request_failed",
    "message": "Request failed with HTTP 400",
    "request_id": "req_example"
  }
}
Generated from the status contract
401
{
  "error": {
    "code": "unauthorized",
    "message": "Request failed with HTTP 401",
    "request_id": "req_example"
  }
}
Generated from the status contract
404
{
  "error": {
    "code": "not_found",
    "message": "Request failed with HTTP 404",
    "request_id": "req_example"
  }
}
Generated from the status contract
409
{
  "error": {
    "code": "conflict",
    "message": "Request failed with HTTP 409",
    "request_id": "req_example"
  }
}
Generated from the status contract
410
{
  "error": {
    "code": "request_failed",
    "message": "Request failed with HTTP 410",
    "request_id": "req_example"
  }
}
Generated from the status contract
413
{
  "error": {
    "code": "request_failed",
    "message": "Request failed with HTTP 413",
    "request_id": "req_example"
  }
}
Generated from the status contract
429
{
  "error": {
    "code": "rate_limited",
    "message": "Request failed with HTTP 429",
    "request_id": "req_example"
  }
}
Generated from the status contract
500
{
  "error": {
    "code": "server_error",
    "message": "Request failed with HTTP 500",
    "request_id": "req_example"
  }
}
Generated from the status contract
Was this page helpful?