Skip to content
DocumentationAPI reference

API reference.

Start production from your own tools, track progress and spending, and download approved work. Continue creative reviews in the studio.

Authentication

Create an API key in Settings → Integrations (org admins only) and send it as a bearer token. Keys stay within their workspace and resource scopes. Request writes need requests:write or all; reads also accept requests:read. The creator must retain editor access for request operations. Keys are shown once at creation; only a hash is stored.

Safe request retries and spending

Save a UUID before creating a request. Send it in Idempotency-Key and reuse the same key and body after a timeout or lost response. You receive the original request; changed instructions return 409. Briefs can contain up to 20,000 characters and the body must fit in 100,000 bytes.

curl https://fabrik.ai/api/v1/requests \
  -H "Authorization: Bearer fbk_your_key_here" \
  -H "Content-Type: application/json" \
  -H "Idempotency-Key: 7cb5629b-b2fa-4388-83af-177a0fb5c583" \
  -d '{"project_id":"YOUR_PROJECT_UUID","brief":"Create a woodland courier character.","credit_limit":100}'

The limit authorizes available Fabrik credits for the entire request, including charges and holds. It does not buy credits or approve creative work. Omitting it starts with zero. To change it, send PATCH with action: "budget", credit_limit and the latest budget.revision as expected_revision. Pause, resume and stop use control_revision instead. Each new command needs its own saved UUID; exact retries preserve newer decisions.

curl https://fabrik.ai/api/v1/projects \
  -H "Authorization: Bearer fbk_your_key_here"

Requests are rate-limited per key and per org by plan. A 429 includes a Retry-After header.

Endpoints

The machine-readable spec lives at docs/openapi.yaml in the repository. Summary:

  • GET /api/v1/projects — List the key's org projects (newest first, max 100).
  • POST /api/v1/requests — Start production: { project_id, brief, credit_limit? }. Send a UUID Idempotency-Key. Returns 202 with request_id and the exact chat_url; the default spending limit is zero.
  • GET /api/v1/requests/:id — Request progress, spending, initial planning state and paginated project assets. Use asset_offset and asset_limit (1–100); job totals cover the entire request.
  • PATCH /api/v1/requests/:id — Approve a total credit limit or pause, resume or stop. Send action, expected_revision and a UUID Idempotency-Key; budget also requires credit_limit.
  • GET /api/v1/assets/:id — Asset metadata + AI-disclosure provenance + a 300-second signed download URL.
  • POST /api/v1/exports — Create an approved export: { project_id, format, engine_target?, categories?, selection?, file_structure?, naming_convention?, include_originals?, include_demos?, atlas? }. Send a UUID Idempotency-Key header to retry safely. manifest-json contains metadata only.
  • GET /api/v1/exports/:id — Export status + a 300-second signed download URL once completed.

Typical flow

  1. Create a request with a project id, brief, saved retry UUID and an approved credit limit. Follow the returned chat_url to answer questions and review creative direction.
  2. Receive asset.created webhooks (or poll GET /api/v1/requests/:id) as saved asset versions become available.
  3. POST /api/v1/exports when the pack is ready; the export.ready webhook identifies the export and its artifact hash, and GET /api/v1/exports/:id returns a signed download URL. ZIP and sprite-sheet packs include a file/version manifest,disclosure.json and README. Metadata-only exports keep provenance inside their manifest. Missing provenance is marked unknown. Review current disclosure requirements for your distribution platform.

Check initial_turn when the first reply is missing. Use its planner status and the recovery controls in the saved chat when planning needs attention. Repeating the original POST keeps the same request. A may_be_interrupted flag indicates an unknown response or an expired worker lease; older requests use the age of their initial claim. Revoking a key prevents further planning under that key. Use Stop to cancel unstarted work; submitted operations may still finish and use their held credits.

Webhooks

Open Settings → Integrations → Manage webhooks and choose a workspace. Administrators can register up to 20 public HTTPS receivers, choose events, reveal signing secrets, inspect history, and retry failed deliveries. Private addresses and redirects are rejected; use the final URL.

Events are captured with their source transaction. asset.created identifies a newly published asset version; export.ready includes the export ID, artifact hash and authenticated API path; request.completed records a request entering Delivered; job.failed records a failed job run. Use the test button for test.ping. New subscriptions receive future events.

Each delivery has three automatic attempts: immediately, after one minute, and after another five minutes. Actual timing depends on worker availability. Administrators can start up to three additional runs within seven days. Every attempt retains the original delivery ID, destination and raw body. Delivery means an HTTP 2xx acknowledgment; an interrupted connection can cause duplicates. Persist the delivery ID and deduplicate before processing.

Pausing or archiving cancels pending sends and keeps history. Rotating a secret also pauses the endpoint: update your receiver, then resume. Canceled events require an explicit retry with the current secret. A request already in flight may still arrive.

Verify x-fabrik-signature-v2 against the timestamp and exact raw body, before parsing JSON. Accept timestamps within five minutes of your server clock:

import { createHmac, timingSafeEqual } from "node:crypto";

function verify(rawBody: Buffer, timestamp: string,
                signature: string, secret: string) {
  const time = Date.parse(timestamp);
  if (!Number.isFinite(time) || Math.abs(Date.now() - time) > 300_000
      || !/^[a-f0-9]{64}$/.test(signature)) return false;
  const expected = createHmac("sha256", secret)
    .update(timestamp + ".").update(rawBody).digest();
  return timingSafeEqual(expected, Buffer.from(signature, "hex"));
}

// x-fabrik-timestamp: ISO 8601 send time, refreshed per attempt.
// x-fabrik-delivery and x-fabrik-event match body.id and body.event.
// After verification, deduplicate using body.id.
// Acknowledge only after durably saving the event for processing.

The legacy x-fabrik-signature header remains HMAC-SHA256 over the raw body alone. Use v2 for timestamp authentication. Secrets are revealed explicitly and never included in endpoint lists. Historical deliveries predating frozen envelopes remain visible but cannot be replayed.