API reference

Limits and versioning

Rate limits, idempotent retries, and how the API changes.

How much you can send, how to retry safely, and how the API changes.

Rate limits

  • 120 requests a minute per key, across every route.
  • 10 scan starts a minute per key, on top of that.
  • One scan at a time per workspace. A start while another scan is running answers 429 ORG_IN_FLIGHT_CAP with Retry-After: 30; the CLI waits for it on its own.

Over a limit, the API answers 429 with a Retry-After header (seconds) and retryAfter in the body:

JSON
{ "error": "Too many requests with this API key. Try again in 12s.", "code": "RATE_LIMITED", "retryAfter": 12 }

Wait that long, then retry. A CI job polling a scan every 10 seconds is well inside the limits.

Idempotency

A network error after POST /scans leaves you not knowing whether the scan started. Send an Idempotency-Key header, and retrying the same request returns the scan it already started instead of starting, and billing, a second one:

Terminal
$ curl -X POST https://www.valiqai.com/api/v1/scans \    -H "Authorization: Bearer $VALIQAI_API_KEY" \    -H "Idempotency-Key: deploy-4817-attempt-1" \    -H "Content-Type: application/json" \    -d '{"url": "https://staging.example.com"}'
  • The key: 1 to 255 printable characters, no spaces, unique to the thing you're doing, like a CI job attempt's id. The CLI sends one per job attempt on its own.
  • Kept for 24 hours, per API key.
  • The same key and the same request answer 200 with the scan it started, its current status, and idempotentReplay: true. Nothing is held or queued again.
  • The same key with a different request (another url, type, options, …) answers 409 IDEMPOTENCY_KEY_REUSED.
  • While the first request is still starting the scan, a retry answers 409 IDEMPOTENCY_IN_PROGRESS with Retry-After: 2.
  • A start that failed (not enough credits, say) frees the key, so retrying it after fixing the cause starts the scan.

source and label aren't part of "the same request", so a retry may change them.

Versioning

The API is version 1, at /api/v1.

  • Within v1, changes are additive: new endpoints, new fields in responses, new optional parameters, new error code values. Write clients that ignore fields they don't know.
  • Nothing is removed, renamed or changed in meaning within v1. A change like that would come as a new version, at a new path, announced ahead of time, with v1 kept running alongside it.
  • Error messages are for people and can be reworded at any time. Match on status codes and code.