Skip to main content
POST /v1/parse (or an email) creates a job and answers 202 at once. The job runs in the background:
Every finished job sends a webhook event. A job still running after an hour fails, with its event.

Waiting for a result

  • Webhooks are the recommended way.
  • Long polling: GET /v1/jobs/{id}?wait=60 holds the request until the job finishes or the seconds pass (at most 600). POST /v1/parse?wait=60 does the same at submission.
  • Listing: GET /v1/jobs lists jobs newest first, filtered by status, source and since, and paged with cursor (the previous page’s next_cursor).

Idempotency

Send an Idempotency-Key header (for example your deal id) with POST /v1/parse. Resending with the same key returns the same job: 202 with created: false while it runs, the finished job once it is done. The same key with different files, file order, metadata or options is refused with 409; use a new key for a new packet.

Options

The multipart field options takes JSON:

Limits

  • A tenant may have max_active_jobs (20 by default) jobs queued or running; one more is 429 with Retry-After.
  • Each job has a spend cap (max_cost_usd_per_job, $2.00 by default), and a tenant can have a monthly budget; once it is spent, new jobs are 429 until the month turns.

Erasure

DELETE /v1/jobs/{id} (jobs:delete) erases a finished job and everything derived from it, at once: its request and result, its input files, the cached reads of its documents, the model answers it paid for, its metering, email thread entries and webhook events. This is how a merchant’s deletion request is honoured: erase each of its jobs. Erasures are recorded in the audit log. A tenant can also set a retention period (PATCH /v1/tenant/settings), after which old jobs are erased automatically.

Re-running the underwriting

POST /v1/underwriting/withhold recomputes withhold, EBITDA and capacity from months and positions you send, for example after an underwriter excludes a month or edits a position, without reading the documents again.