Conventions

Patterns that apply across every endpoint. Read this once and the rest of the reference reads cleaner.

Idempotency

Any state-mutating request (POST, PATCH, DELETE) accepts an Idempotency-Key header. Re-sending the same request with the same key returns the original response — safe to retry.

curl -X POST https://api.bequest.org/v1/gifts \
  -H "Authorization: Bearer $BQ_KEY" \
  -H "Idempotency-Key: req_8x9..." \
  -d '{"from":"usr_8f3...","to":"org_a91...","amount_cents":2500}'

Idempotency keys are remembered for 24 hours. After that, the same key represents a new request.

Pagination

List endpoints return up to 25 records by default. Use limit (max 100) and cursor for paging.

GET /v1/gifts?limit=50&cursor=eyJpZCI6Imdmd...

{
  "data": [ ... ],
  "has_more": true,
  "next_cursor": "eyJpZCI6Imdmd..."
}

Money

All amounts are integer cents in USD unless a currency field is specified. We never use floats.

Timestamps

All timestamps are RFC 3339 UTC. Example: 2026-05-15T13:45:09Z.

Errors

Every error response is JSON with a stable error.type code.

HTTP/1.1 422 Unprocessable Entity
Content-Type: application/json

{
  "error": {
    "type": "validation_failed",
    "message": "amount_cents must be at least 50.",
    "field": "amount_cents",
    "request_id": "req_8x9..."
  }
}

Common error.type values:

Request IDs

Every response carries an X-Request-Id header. If you ever email support, paste it.