Skip to content

General integration guide

This guide describes the request-flow shape Priority.vote expects from an external script. The patterns here apply regardless of whether you are syncing from Jira, Linear, a custom CSV pipeline, or anything else.

Authentication

Send every request with a Bearer token:

Authorization: Bearer pv_pat_<your-secret>

If the token is unknown, revoked, or expired you get 401 invalid_token. If the token is valid but does not have the required scope or the path is outside the token's backlog allow-list, you get 403.

Polling cadence

The API is pull-based. A typical adapter polls a backlog once every few minutes and reacts to changes. There are no webhooks.

If your adapter polls at >1 request per second per token you may hit the per-token rate limit. The API returns 429 too_many_requests with a Retry-After header in seconds. Honour that header — retrying earlier will not help.

Avoiding bandwidth waste with ETag

GET /api/v1/backlogs/{id}/initiatives returns an ETag header on every 200. Save it, and pass it back on the next request as If-None-Match:

GET /api/v1/backlogs/{id}/initiatives HTTP/1.1
Authorization: Bearer pv_pat_...
If-None-Match: "abc123…"

If nothing changed the API returns 304 Not Modified with no body. Treat that as "no work to do this tick".

Idempotency on writes

POST and PATCH accept an optional Idempotency-Key header (16–255 ASCII characters). The first successful request under a key is cached for 24 hours; identical retries replay the same response without creating duplicates. If you reuse the same key with a different body the API returns 422 idempotency_key_conflict.

Use this whenever your adapter retries after a network failure — you cannot be certain whether the original request landed.

Error matrix

Status Code When What your script should do
400 invalid_idempotency_key Idempotency-Key malformed Regenerate the key
401 invalid_token Token missing, unknown, revoked, or expired Reissue and rotate; do not retry
403 pat_scope_required / pat_scope_insufficient Endpoint not reachable with current scopes Reissue with the right scopes
403 backlog_out_of_scope Token restricted to other backlogs Reissue with the right backlog allow-list
404 (various) Resource does not exist Create it, or fail — depends on your sync logic
409 external_ref_conflict This external_source/external_ref already exists PATCH the existing initiative instead
409 limit_reached Per-user PAT limit Revoke an unused token
422 idempotency_key_conflict Reused Idempotency-Key with a different body Pick a fresh key for this body
422 validation_error Field-level validation failed Read errors in the response, fix, retry
429 too_many_requests Rate-limit budget exhausted Sleep Retry-After seconds, retry
5xx Server error Exponential back-off, retry

What not to do

  • Do not poll faster than once per second per token.
  • Do not store the raw token in source control. Use a secret manager.
  • Do not bypass the external_source/external_ref lookup pattern — re-enumerating the backlog on every sync is wasteful and racy.