IntELIEDocs API
Documents in, extracted fields out. Your system uploads a file into an orchestrator someone already set up in the workspace, polls until it settles, and takes the result. The API calls an orchestrator a workqueue.
Everything on this page needs an API key and the 15-minute pass it exchanges for:
how to get both. Every path below is relative to /external/v1/inteliedoc.
The shape of an integration
GET /workqueues once at start-up, then cache the name to id map
POST /workqueues/{id}/documents per file
GET /documents/{id} poll until the status settles
GET /documents/{id}/result take the fields
Those four calls are the whole loop. Everything else on this page handles a particular case: corrections, re-runs, deletion and export.
Every endpoint
The Scope column is what an administrator must tick on the key. A missing scope is a 403
that names it; a workqueue outside the key's reach is a 404, the same as one that does not
exist.
Sending and finding documents
| Method | Path | Scope | What it does |
|---|---|---|---|
GET | /workqueues | workqueues:read | The workqueues this key may send to, id and name only. |
POST | /workqueues/{wqId}/documents | documents:write | Upload one file and start processing. multipart/form-data. |
GET | /documents | documents:read | Your documents, newest first, cursor-paged. Filter with workqueue_id and status. |
GET | /documents/{id} | documents:read | One document's current status. This is what you poll. |
Workqueue ids are opaque, so call /workqueues once at start-up and keep the mapping in memory;
it changes only when someone edits the account. A workqueue the key cannot reach, or one saved
as a draft, is absent from the list rather than an error, so the response is always safe to
show your own users.
Taking the result
| Method | Path | Scope | What it does |
|---|---|---|---|
GET | /documents/{id}/result | extractions:read | Classification, every extracted field, corrections and recognised text. |
GET | /documents/{id}/content | documents:read | A short-lived link to the original file. |
GET | /documents/{id}/content/redacted | documents:read | The same, for the redacted copy. |
GET | /documents/{id}/export | extractions:read | One document as CSV, XLSX or JSON, chosen with ?format=. Returns the file, not JSON. |
POST | /documents:export | extractions:read | Many documents in one file, up to 50; more returns 413. |
/result answers 409 while the document is still processing. Treat that as not yet.
Links come back in the response body, never as a 302. Your HTTP client never has to follow
a redirect, and never risks forwarding your Authorization header to storage. Links are made
per request and expire, so fetch promptly rather than storing them.
Redaction only exists on workqueues set up to redact; anywhere else /content/redacted answers
422 schema_invalid, and retrying will not change that. On a redacting workqueue, asking before
the redacted copy exists answers 409: ask again once the document has settled.
Acting on what you sent
| Method | Path | Scope | What it does |
|---|---|---|---|
PATCH | /documents/{id}/fields | documents:write | Stage corrected values. Up to 25 fields per call. |
POST | /documents/{id}:review | documents:review | Mark it reviewed. This is what makes corrections real. |
POST | /documents/{id}:rerun | documents:rerun | Run the document again without uploading it again. |
DELETE | /documents/{id} | documents:delete | Remove a document from the API's view. 204, no body. |
documents:review, documents:rerun and documents:delete are separate opt-in scopes,
not part of documents:write. Each does something an administrator should agree to on purpose:
closing the human review step, spending money, and removing a document.
What a delete does. The document drops out of the document list, and every call on its id
answers 404 from then on. The record and the original file are kept in the workspace, so a
delete through the API does not erase the stored file, and there is no call to undo it. A
document that is processing or being exported cannot be deleted yet; that answers 409, so wait
for it to settle and try again.
Your own usage
| Method | Path | Scope | What it does |
|---|---|---|---|
GET | /usage/daily | (any valid key) | Calls per day, per endpoint, between the from and to you give. |
GET | /usage/summary | (any valid key) | All-time totals, busiest endpoint first. |
Useful for spotting a runaway polling loop before a rate limit does. The counts cover every key in your account, not only the one asking. Daily counts are kept for about 13 months; the summary totals outlive them. The workspace shows the same figures under Developers, then Usage.
Statuses, and the one that does not move on its own
Poll /documents/{id} every 2 seconds for the first minute, then every 10 seconds. Small
files settle in seconds; large ones take minutes.
While a document is moving it reads PROCESSING, EXPORTING, or EXPORT_QUEUE (waiting for a
scheduled delivery). These are the ones to stop polling at:
| Status | Meaning |
|---|---|
COMPLETED | Processed. Fetch the result. If the workqueue has connectors bound, it can still move on to one of the export statuses. |
EXPORTED · PARTIALLY_EXPORTED · EXPORT_FAILED | Processed and delivered to the workqueue's connectors, to some of them, or to none. The result is ready either way. |
EXCEPTION | Processing failed. failed_stage and error_code say where and why. |
PASSWORD_REQUIRED | The PDF is encrypted, and no password, or the wrong one, was sent. No API call supplies a password afterwards: upload the file again with the password field, or have someone enter it in the workspace. |
REVIEW_PENDING | Extracted, and waiting for a person to decide, for as long as it takes. |
On a workqueue set up for review, every document stops here and stays until someone acts.
Treat it as a result you can read, correct, and then release by calling :review. A poll loop
that waits for COMPLETED on such a workqueue never ends.
Uploading safely
curl -X POST "$BASE/external/v1/inteliedoc/workqueues/$WQ/documents" \
-H "Authorization: Bearer $PASS" \
-H "Idempotency-Key: $(uuidgen)" \
-F "file=@invoice.pdf"
The response is a 202 with document_id, job_id, status (received for a new document) and
status_url; the work continues in the background, so poll status_url rather than holding the
connection open. A file over 25 MB is refused with 413 file_too_large.
Word and OpenDocument files take longer to answer. A .doc, .docx or .odt is converted to
PDF before the call returns, which can take up to about 45 seconds, so give the request a timeout
of at least 60 seconds. If the conversion is still running when time is up, you get
503 document_still_converting with Retry-After: send the same request again with the same
Idempotency-Key. A file that cannot be converted gets 422 document_unconvertible.
Always send Idempotency-Key. It is the only thing that makes a retry safe. Every upload
without it creates a new document, even when the bytes match a file you sent a moment ago.
Networks fail mid-request, and a timeout looks exactly like a success you never heard about; with
the header, a retry with the same key and the same file replays the original response (marked
Idempotency-Replayed: true) instead of creating a second document. Reusing a key for a
different file is refused with 409 idempotency_key_reused. Generate one key per file, and
reuse it only to retry that file.
Optional form fields alongside file:
| Field | What it does |
|---|---|
name | Display name. Defaults to the uploaded filename. |
group_id | An existing document group inside the workqueue. |
group_name | A document group by name, created if it does not exist. The only way the API creates anything. |
password | The password for an encrypted PDF. Used to open the file; never stored. |
correlation_id | Your own trace id, carried through our logs. |
Elie checks your credit before it accepts the document, and a workspace without credit gets
402 billing_denied with nothing run. The pages are charged once processing reaches review or
completion; a document that fails is not charged.
Corrections take two calls
PATCH /documents/{id}/fields, with{"fields":[{"field_id":"...","value":"..."}]}, stages corrected values. They are recorded against the document but do not reach the results store or anything downstream.POST /documents/{id}:review, with{"review_status":"reviewed"}, applies them. This is the step that makes them real, and it only applies them while the document isREVIEW_PENDING.
Stopping after step 1 leaves the corrections invisible to everything except the document itself.
Each correction realigns its own field, which is why a request is capped at 25 fields; more is a
400, so send several calls for larger batches. An unknown field_id is a 422. If required
fields are still empty, :review answers 422, and its message names every one of them, so you
can fix them and retry without guessing.
Re-running
curl -X POST "$BASE/external/v1/inteliedoc/documents/${DOC}:rerun?version=active" \
-H "Authorization: Bearer $PASS"
Reach for it when a document failed, or when the workqueue's configuration has improved and you
want the better result. By default a re-run uses the exact configuration used the first time;
pass version=active to use the workqueue's current configuration instead. Any other value is
treated as the default.
Two things to know:
- A re-run is charged when you start it, per page, like a fresh upload, which is why it needs
the opt-in
documents:rerunscope. It counts against the writes budget. - It discards the previous result and every correction, reviewed or not. Correct after re-running, not before.
A document that is still processing or being exported answers 409.
What is not here, and will not be
No endpoint creates or edits a workqueue, a classification schema, an extraction schema, a redaction rule, a visibility scope or a connector binding, and no endpoint lists, renames or deletes document groups. That is not an oversight, and no scope unlocks it: configuration stays in the workspace, where a person can see what they are changing.
Full schemas
Field-level request and response shapes, with every property, type and example, are in the workspace: open Developers, then API explorer. The API reference there is generated from the running service, so it cannot drift from what the API accepts. This page is the capability reference: what exists, what it costs, and what each call needs.