Document Extraction

Submit a document to Document Insights and read structured field output

Document Insights extracts structured field values from a document. The flow is asynchronous: you submit a document, receive an extraction ID, then read the result once processing finishes.

A typical integration looks like this:

  1. Submit a document.
  2. Poll or subscribe for the terminal state.
  3. Read the output.
  4. Optionally submit feedback.

All requests require an API key in the Authorization header. See Authentication for how to obtain and send one.

Configuration, routing, and output

An extraction request selects a source document. It does not define the fields to extract. Your workspace’s Document Insights configuration determines:

  • which documents it accepts;
  • how a document is routed;
  • which fields, types, and nested structures appear in output.fields.

Before integrating, review the relevant Document Insights configuration in Plextera to identify the expected output schema and routing mode. If you do not know how to access it, ask your workspace administrator or Plextera.

If default routing is configured, omit docType. Other custom labels remain valid and are still returned for correlation. If docType routing is configured, use the exact value from the Document Insights configuration in Plextera. If you do not know where to find it, ask your workspace administrator or Plextera. The v1 API does not currently expose a discovery endpoint for available configurations or docType values.

When no configuration matches, the extraction reaches FAILED with error.code set to DOCUMENT_NOT_ROUTED. See Handle failures for the corrective action.

Submit a document

Choose one of two submission styles, depending on whether you want to manage the file separately.

The examples below use default routing. If your workspace requires docType, add it as shown in Labels and docType.

Option A: Extract from a file or URL

Use this when the document already lives in Plextera File Service or is reachable at an HTTPS URL. This is also the right choice when you want a reusable fileId you can extract from more than once.

To extract from a stored file, first upload it with POST /files, then reference the returned id.

$# 1. Upload the file
$curl -X POST https://api.plextera.com/api/public/v1/files \
> -H "Authorization: api-key YOUR_API_KEY" \
> -F "file=@invoice.pdf"
1{
2 "id": "file_01JY7M4ZVX5R1P3M3Q0TA1S7ZM",
3 "fileName": "invoice.pdf",
4 "mimeType": "application/pdf",
5 "size": 63877
6}
$# 2. Start the extraction
$curl -X POST https://api.plextera.com/api/public/v1/document-insights/extractions \
> -H "Authorization: api-key YOUR_API_KEY" \
> -H "Content-Type: application/json" \
> -d '{
> "document": {
> "fileId": "file_01JY7M4ZVX5R1P3M3Q0TA1S7ZM"
> }
> }'

Option B: Upload and extract in one request

Use this when you do not need a reusable fileId and want a single round trip. Send the file as multipart/form-data to POST /document-insights/extractions/upload.

$curl -X POST https://api.plextera.com/api/public/v1/document-insights/extractions/upload \
> -H "Authorization: api-key YOUR_API_KEY" \
> -F "file=@invoice.pdf"

The file part is required. To add routing or correlation labels, send the optional labels part as a JSON object as shown below.

What you get back

Every submission method returns the same extraction object, accepted asynchronously with status QUEUED.

1{
2 "id": "69654f0bc073ef404baec649",
3 "status": "QUEUED",
4 "outputAvailable": false,
5 "createdAt": "2026-04-07T10:05:04Z",
6 "updatedAt": "2026-04-07T10:05:04Z",
7 "document": {
8 "fileId": "file_01JY7M4ZVX5R1P3M3Q0TA1S7ZM",
9 "fileName": "invoice.pdf"
10 }
11}

Store the id. This is the extractionId you use to poll for results, submit feedback, and correlate events.

All timestamps in extraction responses are UTC ISO 8601 strings, for example 2026-04-07T10:22:00Z.

Labels and docType

Both submission methods accept optional labels. Custom labels are string key-value pairs that you define for correlation, such as a case ID or source system. Plextera returns them on every response and event for the extraction. Custom labels do not change which fields are extracted.

For a JSON extraction request:

1{
2 "document": {
3 "fileId": "file_01JY7M4ZVX5R1P3M3Q0TA1S7ZM"
4 },
5 "labels": {
6 "customerDocumentId": "doc-42",
7 "sourceSystem": "erp"
8 }
9}

docType is different: it is a reserved label that drives document routing. Do not invent this value. Use the exact value from the relevant Document Insights configuration in Plextera. If you do not know where to find it, ask your workspace administrator or Plextera. When your workspace uses default routing, omit docType; you can still send any custom labels you need for correlation.

1{
2 "labels": {
3 "customerDocumentId": "doc-42",
4 "docType": "YOUR_CONFIGURED_DOCUMENT_TYPE"
5 }
6}

For a multipart upload, encode the same object as the JSON labels part:

$curl -X POST https://api.plextera.com/api/public/v1/document-insights/extractions/upload \
> -H "Authorization: api-key YOUR_API_KEY" \
> -F "file=@invoice.pdf" \
> -F 'labels={"docType":"YOUR_CONFIGURED_DOCUMENT_TYPE","customerDocumentId":"doc-42"};type=application/json'

You can attach up to 50 labels. Keys are limited to 64 characters and values to 512 characters; keys and values must be non-empty after trimming.

Get the result

An extraction moves through one of these lifecycles:

COMPLETED, FAILED, and REJECTED are terminal. You can receive the result by polling or by subscribing to events.

Poll for output

Call GET /document-insights/extractions/{extractionId} until the status is terminal. A reasonable cadence is every 2-5 seconds for the first minute, then every 15-30 seconds. Most documents finish within a couple of minutes; large or multi-page documents can take longer.

$curl https://api.plextera.com/api/public/v1/document-insights/extractions/69654f0bc073ef404baec649 \
> -H "Authorization: api-key YOUR_API_KEY"

When status is COMPLETED, outputAvailable is true and the response carries the output object. When status is FAILED or REJECTED, it carries an error object instead.

Read the output

A completed extraction returns output.fieldCount and an output.fields array. Each field carries its extracted value plus extraction details such as confidence, page, and placement.

1{
2 "id": "69654f0bc073ef404baec649",
3 "status": "COMPLETED",
4 "outputAvailable": true,
5 "createdAt": "2026-04-07T10:05:04Z",
6 "updatedAt": "2026-04-07T10:22:00Z",
7 "completedAt": "2026-04-07T10:22:00Z",
8 "document": {
9 "fileId": "file_01JY7M4ZVX5R1P3M3Q0TA1S7ZM",
10 "fileName": "invoice.pdf",
11 "mimeType": "application/pdf",
12 "size": 63877,
13 "pageCount": 1,
14 "contentUrl": "https://files.plextera.com/acme/2026/04/07/invoice_9f1c8b2e.pdf?Expires=1775900000&KeyName=cdn-key&Signature=Zm9vYmFyc2lnbmF0dXJl"
15 },
16 "output": {
17 "fieldCount": 3,
18 "fields": [
19 {
20 "id": "field_01",
21 "name": "vendorName",
22 "type": "text",
23 "value": "Acme Industries Ltd",
24 "metadata": {
25 "extracted": true,
26 "confidence": 1.0,
27 "page": 1,
28 "placement": { "x": 43, "y": 12, "width": 22, "height": 4 }
29 }
30 },
31 {
32 "id": "field_02",
33 "name": "invoiceNumber",
34 "type": "text",
35 "value": "INV-0042",
36 "metadata": {
37 "extracted": true,
38 "confidence": 0.98,
39 "page": 1,
40 "placement": { "x": 316, "y": 48, "width": 147, "height": 10 }
41 }
42 },
43 {
44 "id": "field_03",
45 "name": "totalAmount",
46 "type": "text",
47 "value": "1,024.33 USD",
48 "metadata": {
49 "extracted": true,
50 "confidence": 0.99,
51 "page": 1,
52 "placement": { "x": 316, "y": 209, "width": 147, "height": 10 }
53 }
54 }
55 ]
56 }
57}

Each field’s id is what you pass as fieldId when submitting feedback. For the full field schema, see the API reference.

Download the source document

The document object carries file metadata, including a standard MIME value such as application/pdf, plus contentUrl - a short-lived pre-signed link to download the original document straight from storage. The MIME value is omitted when Document Insights cannot determine it. The download link is minted on each Get extraction request and expires, so fetch it promptly and don’t persist it; request the extraction again to get a fresh one. Extraction events carry the same contentUrl, minted when the event is created. It is not returned by List extractions, and is omitted when the link cannot be resolved. The Files guide shows the same download pattern for files fetched by fileId.

Delete an extraction

Delete an extraction you no longer need with DELETE /document-insights/extractions/{extractionId}.

$curl -X DELETE https://api.plextera.com/api/public/v1/document-insights/extractions/69654f0bc073ef404baec649 \
> -H "Authorization: api-key YOUR_API_KEY"

A successful delete returns 204 No Content. Only terminal extractions can be deleted - deleting one that is still QUEUED or PROCESSING returns 409 CONFLICT; wait for a terminal status first. Deletion is permanent: the extraction disappears from GET and list responses and from Plextera review tooling.

Handle failures

FAILED and REJECTED both return an error object with a machine-readable code and a human-readable message. The distinction matters when deciding whether to retry.

StatusWhat it meansRetry guidance
REJECTEDThe document could not be accepted. Causes include duplicate content, a broken, empty, or oversized file, an unsupported format, or an unsupported language.Read error.message and correct the document before retrying.
FAILEDRouting, processing, or extracted-data validation could not complete.Use error.code to distinguish a configuration problem from a potentially temporary processing failure.

Common terminal error codes:

CodeStatusWhat to do
DOCUMENT_NOT_ROUTEDFAILEDVerify the exact labels.docType value. If you omitted docType, ask your workspace administrator whether default routing exists. Retrying the unchanged request will not help.
DOCUMENT_REJECTEDREJECTEDRead error.message for the concrete reason. For a duplicate, reuse the existing extraction or submit different content. For an invalid document, correct the file before retrying.
DOCUMENT_EXTRACTION_FAILEDFAILEDRetry once with backoff if the failure may be transient. If it repeats, contact Plextera support.
1{
2 "id": "69654f0bc073ef404baec649",
3 "status": "REJECTED",
4 "outputAvailable": false,
5 "completedAt": "2026-04-07T10:05:20Z",
6 "error": {
7 "code": "DOCUMENT_REJECTED",
8 "message": "Duplicate document. Original document ID: 69654f0bc073ef404baec600"
9 }
10}

When contacting support, include the extraction id plus error.code and error.message. These values give support enough context to locate the extraction and diagnose the reason.

Receive events instead of polling

If your application exposes a webhook endpoint, subscribe to extraction events and let Plextera push the terminal result to you. The completed event payload contains the same extraction model returned by GET /document-insights/extractions/{extractionId}, including output.

Recommended event types:

  • document-insights.extraction.completed includes output.
  • document-insights.extraction.failed includes error.
  • document-insights.extraction.rejected includes error.

See Event Subscriptions for endpoint setup, signature verification, and retry behavior.

List extractions

Use GET /document-insights/extractions to review history or build a status view. It returns a paged summary of each extraction without the full output, and the document summary here does not include the contentUrl download link. Fetch a single extraction by ID when you need the field values or a download link.

$curl "https://api.plextera.com/api/public/v1/document-insights/extractions?status=COMPLETED&from=2026-04-01T00:00:00Z&to=2026-04-30T23:59:59Z&sortBy=createdAt&sort=desc" \
> -H "Authorization: api-key YOUR_API_KEY"

Filter by status, narrow by a from / to created-time window, and order with sortBy and sort. Results are paged with zero-based page and size, and every response includes a pageInfo object. See the API reference for the complete parameter list and defaults.

Filter by labels

Filter on the labels you submitted with each extraction using the labels[key]=value parameter. Use labels[key]= (empty value) to match extractions that have the label, or labels[key]=value for an exact match. Multiple keys are combined with AND.

$curl --get https://api.plextera.com/api/public/v1/document-insights/extractions \
> -H "Authorization: api-key YOUR_API_KEY" \
> --data-urlencode "labels[docType]=YOUR_CONFIGURED_DOCUMENT_TYPE" \
> --data-urlencode "labels[customerDocumentId]=doc-42"

This returns extractions with your configured docType and customerDocumentId=doc-42. Label filters combine with the other filters above.

Submit feedback

When an extracted value is wrong or needs review, submit feedback against the extraction. Feedback is surfaced to the team that configures your workspace and is used to improve extraction quality.

$curl -X POST https://api.plextera.com/api/public/v1/document-insights/extractions/69654f0bc073ef404baec649/feedback \
> -H "Authorization: api-key YOUR_API_KEY" \
> -H "Content-Type: application/json" \
> -d '{
> "type": "ERROR",
> "fieldId": "field_01",
> "message": "Vendor name should be Acme Industries Ltd."
> }'
FieldDescription
messageRequired feedback text. Maximum length: 1024 characters.
typeOptional feedback type. Use ERROR for corrections and INFO for notes. Defaults to ERROR.
fieldIdOptional extracted field id. Include it when feedback applies to one field, or omit it for general feedback.