Skip to content
StatusSupportDashboard
Using the Data API

Request Status and Polling

Track request progress and retrieve request-level outputs.

While webhooks are the primary completion mechanism, polling is useful when:

  • validating integration health
  • running backfills or migrations
  • reconciling missed webhook deliveries

Use GET /v1/data/{namespace}/requests/{requestId} for both checking for request status and retreiving request-level outputs. You can poll this endpoint during long-running imports and stop as soon as the request reaches a terminal state.

Endpoint: GET /v1/data/{namespace}/requests/{requestId}

Example response:

{
"namespace": "products",
"request_id": "req_01h2m7qdmdjckc30e1mnq6xqfd",
"status": "ingesting",
"data": []
}

The data attribute is always empty while data is being ingested and processed (i.e., status != "succeeded"). status can be one of queued, uploading (import only), ingesting, succeeded, and failed.

Endpoint: GET /v1/data/{namespace}/requests/{requestId}

Example response shape for add requests:

{
"namespace": "products",
"request_id": "req_01h2m7qdmdjckc30e1mnq6xqfd",
"status": "succeeded",
"data": [
{
"id": "product_12345",
"output": {
"actions": [],
"labels": [{ "label": "policy.example_violation" }],
"fields": {}
},
"metadata": {},
"url": "https://app.safetykit.com/..."
}
]
}

For import requests, you’ll receive a temporary download URL instead of inline data:

{
"namespace": "products",
"request_id": "req_01h2m7qdmdjckc30e1mnq6xqfd",
"status": "succeeded",
"data_url": "https://s3.amazonaws.com/...",
"data_count": 1200,
"data_expires_at": "2026-01-15T12:30:00.000Z"
}

For import requests, the data_url file is JSONL with one result object per line. Each line follows the same structure as request-level object outputs in the data array:

{"id":"product_12345","output":{"actions":[],"labels":[{"label":"policy.example_violation"}],"fields":{}},"metadata":{"source":"backfill"},"url":"https://app.safetykit.com/..."}
{"id":"product_67890","output":{"actions":[{"action":"manual_review","queue":"high_risk"}],"labels":[],"fields":{}},"metadata":{},"url":"https://app.safetykit.com/..."}

When parsing this file:

  • read line by line (streaming), not as one large JSON document
  • treat metadata as optional
  • treat output as potentially nullable
  • map rows to your original content with id
  • poll every 3-10 seconds
  • stop polling when status is succeeded or failed
  • treat polling as a complement, not replacement, for webhooks