Skip to content

API overview

The Puck API is a JSON REST API. Every call requires an API key, returns JSON, and uses standard HTTP status codes. Autonomous investigations, webhook management, and graph queries are all available programmatically — everything the console does, the API does too.

Base URL

https://api.puck.security

All paths are versioned under /v1. There is no unversioned alias; always include the version segment.

Authentication

Pass your API key in the Authorization header on every request:

Authorization: Bearer pck_live_…

Keys are issued per account and carry named scopes. See Authentication for the full list of scopes and how to issue or rotate keys.

Content type

Requests with a body must set Content-Type: application/json. The API only accepts JSON; application/x-www-form-urlencoded is not supported.

Responses are always Content-Type: application/json; charset=utf-8, including error bodies.

Idempotency

POST /v1/investigations supports idempotent retries. Pass an Idempotency-Key header (or the idempotency_key body field) — any string up to 256 characters that is unique to this logical request. If you send the same key and the same body within 24 hours, you get the same response. If you send the same key with a different body, the server returns 409 Conflict.

No other endpoints currently support idempotency keys, but the pattern is safe to send on any POST; extra headers are ignored.

Rate limits

TierInvestigations / minuteAPI calls / minute
Free260
Pro20600
Enterprisecustomcustom

When a limit is exceeded the server returns 429 Too Many Requests with a Retry-After header (seconds until the window resets) and an X-RateLimit-Remaining header.

Versioning

The current stable version is v1. Breaking changes always get a new version prefix; v1 paths are stable indefinitely. When a v2 exists, v1 continues to work for at least 12 months after the deprecation notice.

Non-breaking additions — new optional fields, new enum values on non-discriminated fields, new endpoints — ship without a version bump.

Pagination

List endpoints return cursor-based pages. The response always includes a next_cursor field: null when there are no more results, or an opaque string to pass as ?cursor= on the next request. There is no previous_cursor; cursors are forward-only.

Common questions

Can I use the API key from a CI secret? Yes. The key is just a bearer token. Store it as a CI secret and pass it via the Authorization header in your workflow steps.

Does the API support webhook push instead of polling? Yes. Pass webhook_url in the investigation trigger body, or configure a persistent subscription via Webhooks. The polling model (polling GET /v1/investigations/{id}) is also available if you prefer pull.

What happens if I exceed the rate limit mid-investigation? The POST /v1/investigations call that hits the limit is rejected. Any investigation already queued continues to completion — rate limits affect the trigger, not the run.

Is there an OpenAPI spec I can import into Postman or Insomnia? Yes. The spec lives at docs/openapi.yaml in the monorepo and is served at https://api.puck.security/openapi.yaml in production.