Skip to content
Zaraftis API
Esc
↑↓navigate↵open⌘Jpreview
On this page

How requests work

Authentication, response shapes, paging, retries, long-running work, and rate limits in the Zaraftis v1 API.

Every route in the API reference follows the rules on this page.

Base URL and authentication

Send every request to https://api.zaraftis.com/v1 with your API key in the Authorization header:

curl https://api.zaraftis.com/v1/me \
  --header "Authorization: Bearer $ZARAFTIS_API_KEY"

A key belongs to one workspace. It has scopes, such as scans:read or scans:write, and can be limited to some brands. A request outside its scopes answers 403 forbidden. A key can read the wallet but cannot buy credits; that happens in the dashboard.

Response shape

Every response is JSON with success, data, and request_id:

{
  "success": true,
  "data": { "scan_id": "4f0d2c7e-1b5a-4f7e-9a51-0c6f3d2b8e14", "status": "completed" },
  "request_id": "d3b0e28f-89a4-4c1c-a68b-11b0d5886f45"
}

A failed request has success: false and an error object instead of data. See Errors for every code and what to do about it.

An id you cannot see always answers 404 not_found: an unknown id, an id in another workspace, and an id outside your key’s brands look the same.

Request IDs

Every response has a request_id in the body and an X-Request-ID header. To use your own id, send an X-Request-ID header of 1 to 64 letters, digits, -, ., or _. Any other value is replaced with a new id. Log the request_id and quote it when you report a problem.

Paging through lists

List routes return items and pagination:

{
  "success": true,
  "data": {
    "items": [],
    "pagination": { "next_page_token": "c29tZQ", "has_more": true }
  },
  "request_id": "d3b0e28f-89a4-4c1c-a68b-11b0d5886f45"
}

Pass next_page_token as page_token to get the next page, with the same filters and limit as the first request. limit defaults to 25 and goes up to 100; a route can set lower values, shown on its reference page. When has_more is false, there is no next_page_token. Lists are sorted newest first.

Treat the token as an opaque string. A token that is changed, too old, or sent with different filters answers 400 invalid_page_token; start the list again without a token.

Safe retries with Idempotency-Key

Every POST that creates something needs an Idempotency-Key header: 1 to 64 printable characters with no spaces. Use a new value, such as a UUID, for each new request.

curl https://api.zaraftis.com/v1/scans \
  --request POST \
  --header "Authorization: Bearer $ZARAFTIS_API_KEY" \
  --header "Content-Type: application/json" \
  --header "Idempotency-Key: 7b1e4a2c-5d3f-4e8a-9c0b-2f6d8e1a3b5c" \
  --data @scan.json

If the request times out or fails on the network, send it again with the same key and body. You get the first response back, and the work runs and is charged only once. If the first request is still running, the retry answers 202. Sending the same key with a different body answers 409 idempotency_conflict.

Long-running work

Scans, site audits, scan reports, exports, and connection syncs run in the background. Their POST answers 202 Accepted with a task_id and task_url. Poll GET /v1/tasks/{task_id} until status is completed, partial, failed, or cancelled; the task then links to what it made, such as scan_url. Wait a few seconds between polls.

POST /v1/visibility/checks waits for the result and answers 200 when every query finishes in time. Otherwise it answers 202 with a task, like a scan.

A partial scan finished, but some of its queries failed. Its results use only the queries that succeeded, and failed queries are not charged.

Compact and detailed views

Some routes return a short view by default. Add detail=detailed to a GET, or "response_detail": "detailed" to a check request, to get more fields; the route’s reference page says which. Scan reports use detail=summary, evidence, or full. Asking for another view of a resource never runs or charges the work again.

Rate limits

Each API key has three limits per 60 seconds:

Kind of request Limit
Reads (GET) 120
Paid work (POST /v1/scans, POST /v1/visibility/checks, POST /v1/site-audits) 10
Other writes 30

Every response to a valid key shows where you are:

X-RateLimit-Limit: 30
X-RateLimit-Remaining: 0
X-RateLimit-Reset: 1790470860000
Retry-After: 12

X-RateLimit-Reset is a Unix time in milliseconds. Over the limit, the API answers 429 rate_limited with Retry-After in seconds; wait that long before you try again. The numbers can change, so read the headers instead of hard-coding them.

A workspace can also run only a set number of scans at the same time. GET /v1/capabilities shows the number in limits.concurrent_work. A scan over that number answers 503 capacity_unavailable; retry after a running scan finishes.

Versions

The version is in the URL (/v1). New fields and new routes can appear in /v1 at any time, so ignore fields you do not know. A change that breaks existing code gets a new version and a notice in the changelog.

Was this page helpful?