Tracking jobs

Creating a form and filling from context are asynchronous — the API returns right away with a job_id (or form_id) and a status of processing, then the real work runs in the background. You track a job to completion by polling.

You can track a job two ways: poll for the result (below), or have Emboss call you when the job finishes — see Callbacks. This guide covers polling.

Poll for a form's status

curl https://api.getemboss.ai/forms/6c47f7f5-f921-4698-910f-95dd7d81310b \
  -H "Authorization: Bearer sk_live_yourkey"

status moves from processing to either ready or failed:

{ "id": "6c47f7f5-f921-4698-910f-95dd7d81310b", "status": "ready" }

For a context-fill job, poll GET /forms/with-context/{job_id} the same way — it returns processing, then ready with a session_id, or failed with an error.

A simple polling loop

Poll every second or two, and stop as soon as the status is terminal. A little backoff keeps you well under the rate limit on long jobs.

async function waitForForm(formId, key) {
  let delay = 1000; // start at 1s
  while (true) {
    const res = await fetch(`https://api.getemboss.ai/forms/${formId}`, {
      headers: { Authorization: `Bearer ${key}` },
    });
    const { status } = await res.json();
    if (status === "ready") return "ready";
    if (status === "failed") throw new Error("detection failed");
    await new Promise((r) => setTimeout(r, delay));
    delay = Math.min(delay * 1.5, 5000); // back off to 5s max
  }
}

When a job fails

A failed status comes with an error describing why (for example, an unreadable PDF). Surface it, fix the input, and resubmit — a failed job isn't retried automatically.

For the bigger picture of what runs between processing and ready, see How Emboss works.