For AI agents: this page is also available as Markdown at https://docs.refabric.com/quick-start.md, and the index of every page is https://docs.refabric.com/llms.txt.

Quickstart

Run your first job: find a task, check its cost, submit it, get the files.

1. Get a key

Create a key in Panel › Developers › Keys. The key is shown once — store it in a secret manager or an environment variable.

export REFABRIC_API_KEY="<key>"
export REFABRIC_API="https://api.refabric.com/v1"

2. Find a task

curl -s "$REFABRIC_API/tasks" -H "Authorization: Key $REFABRIC_API_KEY"

Each entry has a name, a title, a summary, a category, and — on GET /v1/tasks/{name} — the full inputSchema and outputSchema, every field explained.

category says what kind of work the task does: generation makes new content (its inputs, including a file from an earlier result, guide it — image.generate, moodboard.create); edit makes another version of the one image or record you give it (image.<verb>, e.g. image.change_background; and fabric.add_colour, a new colour of your fabric) (Files).

curl -s "$REFABRIC_API/tasks/image.glam" -H "Authorization: Key $REFABRIC_API_KEY"

image.glam changes one feature of a finished image; the published list of tasks is what GET /v1/tasks returns.

3. Check the cost

curl -s -X POST "$REFABRIC_API/tasks/image.glam/estimate" \
  -H "Authorization: Key $REFABRIC_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"prompt": "make the lipstick red", "image": "https://example.com/look.png"}'
{ "task": "image.glam", "ceiling": <credits>, "credit_type": "<credit type>", "is_ceiling": true }

credit_type is one of the values at GET /v1/vocab/credit_type.

4. Submit

curl -s -X POST "$REFABRIC_API/tasks/image.glam" \
  -H "Authorization: Key $REFABRIC_API_KEY" \
  -H "Content-Type: application/json" \
  -H "Idempotency-Key: $(uuidgen)" \
  -d '{"prompt": "make the lipstick red", "image": "https://example.com/look.png"}'
HTTP/1.1 202 Accepted
X-Request-ID: req_…
X-Refabric-Credits: <credits held>
X-Refabric-Credit-Type: <credit type>

{
  "job_id": "j_…",
  "lifecycle": "queued",
  "status_url": "https://api.refabric.com/v1/jobs/j_…",
  "result_url": "https://api.refabric.com/v1/jobs/j_…/result",
  "cancel_url": "https://api.refabric.com/v1/jobs/j_…/cancel"
}

5. Get the result

Poll the status until it is terminal, then read the result:

curl -s "$REFABRIC_API/jobs/j_…" -H "Authorization: Key $REFABRIC_API_KEY"
curl -s "$REFABRIC_API/jobs/j_…/result" -H "Authorization: Key $REFABRIC_API_KEY"
{
  "job_id": "j_…",
  "files": [
    { "file": "art:x1", "url": "https://…", "media_type": "image/png",
      "task": "image.glam", "job_id": "j_…", "created_at": "2026-09-28T10:00:00Z" }
  ],
  "has_more": false
}

Short jobs can skip polling with Prefer: wait=N (see Jobs); long ones should use a webhook.

The same in Python

import os, time, uuid
import requests

API = os.environ.get("REFABRIC_API", "https://api.refabric.com/v1")
s = requests.Session()
s.headers["Authorization"] = f"Key {os.environ['REFABRIC_API_KEY']}"

body = {"prompt": "make the lipstick red", "image": "https://example.com/look.png"}

job = s.post(f"{API}/tasks/image.glam", json=body,
             headers={"Idempotency-Key": str(uuid.uuid4()), "Prefer": "wait=30"})
job.raise_for_status()

if job.status_code == 200:            # finished within the wait
    result = job.json()
else:                                 # 202: still running — poll
    handle = job.json()
    while True:
        status = s.get(handle["status_url"]).json()
        if status["lifecycle"] == "terminal":
            break
        time.sleep(5)
    if status["outcome"] != "succeeded":
        raise RuntimeError(status.get("error"))
    result = s.get(handle["result_url"]).json()

for f in result["files"]:
    print(f["file"], f["media_type"], f["url"])

Continue from a result

Pass a file back as the input of the next job — no ids needed:

{ "prompt": "now add a white collar", "image": "art:x1" }

Next: Authentication · Jobs · Files.