Jobs

Delivery vs start SLA

Delivery is controlled by client_wait — independently of the start SLA processing_lane. See Start SLA.

Pipeline slug

Job paths use handler___command with three underscores. OCR: POST /job/add/paperoffice_aiocr___generate. IDP: POST /job/add/workflow. No dot and no po-* in the path.

Dot notation (handler.command) returns HTTP 400 (JOB_CONFIG_INVALID).

IDP POST /job/add/workflow accepts only multipart file or pofid — no JSON URL arrays.

Default — hold the connection

POST /job/add/{pipeline}  →  hold the connection until ~295s  →  200 result OR HTTP 202 + job_id + poll_url

After the hold window the job keeps running. Poll GET /job/get/{job_id} every 5–10 seconds or use poll_url from the response.

Queued, running and completed API jobs: Account → API → Job queue (/paperoffice-account/api-queue).

Immediate job_id

client_wait=false  OR  async_only=true

1. POST /job/add/{pipeline}     → job_id immediately (~100ms)
2. GET  /job/get/{job_id}        → poll every 5–10 s until job_status = "completed"
3. GET  /job/download/{token}    → only when job_result contains a download URL

HTTP 202 — the job continues

HTTP 202 is a success path, not an error. The job stays active. Poll job_id and poll_url until job_status is completed. The result is in job_result.

On connection hold the finished result is in result. When polling it is in job_result. Clients must read the stable code field, not the localised message text.

Response format

All responses are JSON and include processing_time.

Success:

{
  "status": "success",
  "job_id": "abc123",
  "result": { "text": "…" },
  "processing_time": "45.12ms"
}

Polling / HTTP 202:

{
  "status": "success",
  "job_id": "abc123",
  "poll_url": "/job/get/abc123",
  "client_wait": false,
  "max_wait_seconds": 60,
  "message": "Job queued — poll for result",
  "processing_time": "45.12ms"
}

Error:

{
  "status": "error",
  "code": "INSUFFICIENT_CREDITS",
  "message": "Not enough credits for this job",
  "processing_time": "12.04ms"
}

Error codes

HTTPCodeMeaningWhat to do
400INVALID_REQUESTMissing / invalid parametersCheck the request body
400JOB_CONFIG_INVALIDInvalid pipeline slugUse handler___command, not dot notation
401AUTH_REQUIREDNo Bearer tokenSet Authorization: Bearer YOUR_TOKEN
401INVALID_TOKENToken invalidCheck prefix (po_sk_, po_ut_, po_gt_, po_pk_)
401BEARERTOKEN_EXPIREDToken expiredRequest a new token
402INSUFFICIENT_CREDITSNot enough creditsTop up or choose a lower lane
402BUDGET_EXHAUSTEDPublishable-key budget reachedCreate a new po_pk_ or raise the cap
403FORBIDDENAction not allowedCheck scope, origin or licence
403TIER_RESTRICTEDProduct API without token (VISITOR)Set a Bearer token — this is not HTTP 401
403JOB_REQUIRES_PAID_TIERFree tier not allowedUse a paid plan
404NOT_FOUNDNot foundCheck the URL path
429RATE_LIMIT_EXCEEDEDToo many requestsHonour Retry-After
429QUEUE_LIMIT_REACHEDQueue fullRetry later
500INTERNAL_ERRORServer errorRetry after a short pause
503SERVICE_UNAVAILABLEService unreachableRetry with backoff

Related