Errors, limits, and idempotency

This page documents error handling expectations for Fictix integrations.

Error shape

FastAPI routes may return simple string details:

{
  "detail": "No data. Generate first."
}

or structured details:

{
  "detail": {
    "code": "project_dataset_limit_exceeded",
    "message": "Project dataset exceeds current blob storage safety budget"
  }
}

Clients should handle both.

POST /api/v1/demo-jobs can also return a credit envelope when admission or credit settlement fails:

{
  "error": "insufficient_credits",
  "message": "A valid credit run or sufficient credits are required."
}

Common status codes

Status Meaning Client action
400 Bad request, invalid delta, missing confirmation, no generated data Fix request or create/generate data first.
401 Missing or expired auth Refresh credentials and retry once.
402 No valid credit run or insufficient credits for a demo-job create Fund or resolve the server-side credit run; do not retry blindly.
403 Authenticated but not allowed Check org membership, role, or credential scope.
404 Job, project, entity, matrix, run, event, or checkpoint not found Verify id and tenant scope.
409 Idempotency conflict or active generation conflict Use a new idempotency key or wait for active run.
413 Bundle or dataset too large Page entities or export per entity.
422 Invalid request body, priced generation shape, or credit validation failure Fix request fields or resolve credit state before retrying.
429 Generation, rate, plan, or concurrency limit Back off and retry after the applicable limit clears.
500 Internal failure Retry safely when idempotent; otherwise contact support with request id.
503 Service not ready Retry with backoff; check readiness.

Idempotency

POST/api/v1/demo-jobs

POST /api/v1/demo-jobs requires:

Idempotency-Key: <key>

If a network failure occurs after the server creates a job, retry the exact same request with the exact same idempotency key. Fictix returns the cached response.

If you send a different body with the same key, Fictix returns:

409 Conflict

Native writes

Native writes require a nonempty idempotency key. Send Idempotency-Key unless the provider workflow documents another header or body field for that route. Give each new operation a new key; reuse the original key and payload when retrying it. Read operations, including POST requests modeled as reads, do not require a native-write idempotency key.

For Mercury recipient creation (POST /api/v1/recipients), send the key in the Idempotency-Key header. The recipient JSON does not accept idempotencyKey; that body field is supported for Mercury payment and transfer requests.

Bundle limit

GET/api/v1/demo-jobs/{job_ref}/bundle

GET /api/v1/demo-jobs/{job_ref}/bundle is intentionally capped.

When requested entity records exceed the cap:

{
  "detail": "Bundle too large for one response. Requested 30001 records across 15 entities, which exceeds the partner bundle cap of 25000. Use the entity or export endpoints instead."
}

The active cap is deployment-configurable. Do not parse the number from an error message; handle 413 by paging or exporting instead.

Switch to:

GET /api/v1/demo-jobs/{job_ref}/entities/{entity}
GET /api/v1/demo-jobs/{job_ref}/entities/{entity}/export

Generation budget limit

Large generation shapes can be rejected before expensive work starts.

The error explains:

  • weighted load
  • estimated records
  • quality preset
  • connector count
  • budget
  • safe employees/months suggestions

To fix:

  • lower generation.employees
  • lower generation.months_of_history
  • reduce selected_services
  • choose a less aggressive quality preset
  • create multiple smaller jobs

Retry guidance

Safe to retry with same idempotency key:

  • network timeout during POST /demo-jobs
  • 503
  • 500 before receiving a response body

Safe to retry without idempotency key:

  • GET requests
  • DELETE after verifying semantics are acceptable

Do not blindly retry:

  • reset
  • clone
  • publish if your client cannot tolerate duplicate side effects
  • test run submission unless your client can dedupe by matrix/run id

Request IDs

When available, capture response headers such as request id or trace id from errors and include them in support tickets.

Recommended client logging:

  • request method
  • path, without secrets
  • status code
  • job id
  • entity
  • idempotency key hash, not raw key
  • response request id header
  • response body detail