Extractor
This document describes how to use the DIMARC API to interact with extraction endpoints. The API offers two approaches for extracting structured data from documents.
Prerequisites
Section titled “Prerequisites”- An active DIMARC account.
- Administrator status in your organization.
- Your authentication token
x-api-key(see Retrieving Your Authentication Token)
Two Extraction Approaches
Section titled “Two Extraction Approaches”The Extractor API offers two methods of use depending on your needs:
1. Global Extractor
Section titled “1. Global Extractor”The global extractor allows you to define the extraction schema directly in the API request, without requiring prior agent configuration.
Endpoints:
POST /v2/extractorPOST /v2/extractor/asyncUse case: Ideal for one-time extractions, testing, or when you want to dynamically define the extraction schema without going through the Dimarc interface.
2. Agent-based Extractor
Section titled “2. Agent-based Extractor”The agent-based extractor uses extraction models preconfigured in the Dimarc interface. This approach is recommended for repetitive extractions with the same schema.
Endpoints:
POST /v2/extractor/:agentReferencePOST /v2/extractor/async/:agentReferenceUse case: Recommended for production use cases where you have standardized and reusable extraction models.
Retrieving an agent reference
Section titled “Retrieving an agent reference”To use the agent-based extractor, you must first retrieve your agent’s reference:
- Click on your profile icon in the top right corner, then go to the Organization > API section or by clicking here
- In the References of your agents section, you can retrieve the reference of the Extractor agent you want to use.
Configuring extraction models
Section titled “Configuring extraction models”Extraction models are configured in the Dimarc interface. To add a new model, go to your dashboard: https://app.dimarc.ai
Go to your Extractor agent configuration and add a new model by defining the fields to extract.
Processing Modes
Section titled “Processing Modes”Each approach (Global and Agent) offers two processing modes:
- Synchronous: The request is processed immediately and the response is returned in the same HTTP connection.
- Asynchronous: The processing is queued and the results are sent to a defined webhook once the extraction is completed.
Synchronous Extraction
Section titled “Synchronous Extraction”Synchronous extraction is ideal for quick processing or when your application is directly waiting for the result.
Approach 1: Global Extractor (Synchronous)
Section titled “Approach 1: Global Extractor (Synchronous)”This method allows you to define the extraction schema directly in the request.
Request
Section titled “Request”curl --location 'https://api.dimarc.ai/v2/extractor' \--header 'Content-Type: application/json' \--header 'x-api-key: <your_api_key>' \--data '{ "filename": "invoice.pdf", "file": "<base64_encoded_file>", "params": [ { "name": "invoice_number", "format": "text", "description": "Invoice number" }, { "name": "total_amount", "format": "number", "description": "Total amount including tax" }, { "name": "products", "format": "list", "description": "List of products", "items": [ { "name": "product_name", "format": "text", "description": "Product name" }, { "name": "quantity", "format": "number", "description": "Quantity" } ] } ]}'Parameters
Section titled “Parameters”| Parameter | Type | Description |
|---|---|---|
filename |
string | Original filename (with extension) |
file |
string | File content encoded in base64 |
params |
array | Array defining the extraction schema (see Parameters Structure) |
Approach 2: Agent-based Extractor (Synchronous)
Section titled “Approach 2: Agent-based Extractor (Synchronous)”This method uses a preconfigured agent with an extraction schema defined in the Dimarc interface.
Request
Section titled “Request”curl --location 'https://api.dimarc.ai/v2/extractor/<agent_reference>' \--header 'Content-Type: application/json' \--header 'x-api-key: <your_api_key>' \--data '{ "filename": "invoice.pdf", "file": "<base64_encoded_file>"}'Parameters
Section titled “Parameters”| Parameter | Type | Description |
|---|---|---|
filename |
string | Original filename (with extension) |
file |
string | File content encoded in base64 |
thread_id |
string | (Optional) Attaches the extraction to an existing thread — the one returned in metadata.thread_id by an earlier call. The thread must belong to this agent, otherwise 404 thread_not_found |
Synchronous Response Format (common to both approaches)
Section titled “Synchronous Response Format (common to both approaches)”{ "status": "success", "data": [ { "invoice_number": "INV-2024-001", "total_amount": 1250.50, "products": [ { "product_name": "Product A", "quantity": 2 }, { "product_name": "Product B", "quantity": 1 } ] }, ], "metadata": { "filename": "invoice.pdf", "duration": 3.45, "tokens_consumed": 1, "thread_id": "01J..." }}On error
Section titled “On error”{ "status": "error", "code": "extraction_failed", "error": "Extraction stream failed", "detail": { }}code is a stable machine identifier — error remains a human-readable message that can change without notice. detail is optional and absent most of the time. See the error codes table for the full set of possible codes.
A document the engine processed without extracting anything returns 422 no_data_extracted. This is not a failure: submitting it again unchanged yields the same outcome.
Error codes
Section titled “Error codes”| Status | Code | Case |
|---|---|---|
| 401 | unauthorized |
Missing or invalid x-api-key header |
| 403 | forbidden |
API access disabled for your organization |
| 404 | agent_not_found |
Agent not found, wrong type, private, or outside your organization (agent-based extractor) |
| 404 | thread_not_found |
The thread_id provided does not belong to this agent |
| 413 | file_too_large |
File larger than 36 MB; detail carries limit and size in bytes |
| 422 | invalid_request |
Invalid request body: base64, params, or unknown field (thread_id only exists on the agent-based extractor) |
| 422 | infected_file |
File rejected by the antivirus |
| 422 | no_data_extracted |
Document processed, nothing usable to extract from it |
| 429 | rate_limit_exceeded |
More than 100 requests per minute; Retry-After carries the seconds until the next window |
| 429 | spending_limit_reached |
Organization spending limit reached |
| 429 | concurrent_limit_exceeded |
More than 4 concurrent jobs for the organization, synchronous and asynchronous alike; Retry-After carries the seconds to wait before retrying |
| 429 | queue_saturated |
The processing engine is saturated; Retry-After carries the seconds to wait before retrying |
| 500 | internal_error |
Unexpected internal error |
| 502 | extraction_failed |
The agent could not process the extraction |
| 503 | agent_unavailable |
Processing queue unavailable |
| 503 | antivirus_unavailable |
Antivirus service unavailable |
| 504 | agent_timeout |
Processing deadline exceeded (120 s) |
In asynchronous mode, only the rejections that precede queueing come back over HTTP — 401, 403, 404 agent_not_found, 413, 422 invalid_request and all four 429. Anything that happens during processing is delivered to the callback and the extraction.completed event, with the same code and detail.http_status.
Asynchronous Extraction
Section titled “Asynchronous Extraction”Asynchronous extraction is recommended for:
- Large documents
- Complex extractions requiring more time
- Systems that cannot wait for an immediate response
Approach 1: Global Extractor (Asynchronous)
Section titled “Approach 1: Global Extractor (Asynchronous)”This method allows you to define the extraction schema directly in the request.
Request
Section titled “Request”curl --location 'https://api.dimarc.ai/v2/extractor/async' \--header 'Content-Type: application/json' \--header 'x-api-key: <your_api_key>' \--data '{ "filename": "invoice.pdf", "file": "<base64_encoded_file>", "callback": "https://your-callback-endpoint.com/webhook", "params": [ { "name": "invoice_number", "format": "text", "description": "Invoice number" }, { "name": "total_amount", "format": "number", "description": "Total amount including tax" } ]}'Parameters
Section titled “Parameters”| Parameter | Type | Description |
|---|---|---|
filename |
string | Original filename (with extension) |
file |
string | File content encoded in base64 |
callback |
string | URL of the webhook that will receive the results |
params |
array | Array defining the extraction schema (see Parameters Structure) |
Approach 2: Agent-based Extractor (Asynchronous)
Section titled “Approach 2: Agent-based Extractor (Asynchronous)”This method uses a preconfigured agent with an extraction schema defined in the Dimarc interface.
Request
Section titled “Request”curl --location 'https://api.dimarc.ai/v2/extractor/async/<agent_reference>' \--header 'Content-Type: application/json' \--header 'x-api-key: <your_api_key>' \--data '{ "filename": "invoice.pdf", "file": "<base64_encoded_file>", "callback": "https://your-callback-endpoint.com/webhook"}'Parameters
Section titled “Parameters”| Parameter | Type | Description |
|---|---|---|
filename |
string | Original filename (with extension) |
file |
string | File content encoded in base64 |
thread_id |
string | (Optional) Attaches the extraction to an existing thread — the one returned in metadata.thread_id by an earlier call. The thread must belong to this agent, otherwise 404 thread_not_found |
callback |
string | URL of the webhook that will receive the results |
Immediate Response (common to both approaches)
Section titled “Immediate Response (common to both approaches)”{ "status": "started", "extract_id": "01K74Z3Q8RVN5XW2B6JHMTGD9C"}Fetching a result
Section titled “Fetching a result”The extract_id identifies the job. If you have not received the callback yet, or if your endpoint was unavailable, fetch the result with this identifier:
curl --location 'https://api.dimarc.ai/v2/turns/01K74Z3Q8RVN5XW2B6JHMTGD9C' \--header 'x-api-key: <your_api_key>'| Status | Body |
|---|---|
| 200 | The final event, identical to the one sent to the callback (status: "success" or "error"); for a successful synchronous job, its response body |
| 422, 502, 504 | Failed synchronous job: the status code and error body of its original response |
| 202 | { "status": "running", "turn_id": "…" } — processing has not finished, or its result is still being delivered; retry in a few seconds |
| 404 | turn_not_found — unknown or expired identifier, or one that belongs to another organization |
The result stays available for at least 7 days.
Webhook Response Format
Section titled “Webhook Response Format”When the extraction is complete, the results are sent to the specified callback URL.
The callback is called with a POST carrying the same JSON body as the event. If your organization has configured a webhook for this event, the request carries the x-dimarc-signature: sha256=… header, to be verified with that webhook’s secret; with no webhook configured, it is unsigned. Each attempt waits 10 s at most; on 429, 5xx or a network error, delivery is retried after 1 s, 10 s, then 60 s. A delivery can arrive twice, so deduplicate on your side.
The same result is also available via the extraction.completed event if you have configured an organization webhook — useful for centralizing delivery without depending on the per-request callback.
On success
Section titled “On success”{ "status": "success", "extract_id": "01K74Z3Q8RVN5XW2B6JHMTGD9C", "data": [ { "invoice_number": "INV-2024-001", "total_amount": 1250.50 } ], "metadata": { "filename": "invoice.pdf", "duration": 3.45, "tokens_consumed": 1, "thread_id": "01J..." }}On error
Section titled “On error”{ "status": "error", "extract_id": "01K74Z3Q8RVN5XW2B6JHMTGD9C", "code": "agent_timeout", "error": "Agent response timed out", "detail": { "http_status": 504 }}detail is an object — http_status is a number. code carries the real machine code for the error (see the error codes table). An http_status below 500, such as 422 for no_data_extracted, describes the submitted document, not a failure.
Parameters Structure
Section titled “Parameters Structure”When using the global extractor, you must define the extraction schema via the params parameter. Each element in the params array is an object with the following properties:
| Property | Type | Description |
|---|---|---|
name |
string | Name of the field to extract |
format |
string | Data type: text, number, boolean, date, or list |
description |
string | Clear description of the field to extract (helps the AI understand) |
items |
array | (Required only for format: "list") Array of sub-fields to extract for each list item |
Supported Format Types
Section titled “Supported Format Types”1. Simple Types
Section titled “1. Simple Types”For scalar values, use:
text: For text, character stringsnumber: For numeric valuesboolean: For true/false valuesdate: For dates, returned asYYYY-MM-DD(best-effort: the exact shape depends on the model, it is not normalized)
{ "name": "invoice_number", "format": "text", "description": "Invoice number"}2. Lists (list format)
Section titled “2. Lists (list format)”For complex data like arrays, series of items, etc., use the list format and define sub-elements in the items array:
{ "name": "products", "format": "list", "description": "List of products in the invoice", "items": [ { "name": "product_name", "format": "text", "description": "Product name" }, { "name": "quantity", "format": "number", "description": "Ordered quantity" }, { "name": "unit_price", "format": "number", "description": "Unit price before tax" } ]}Complete Schema Example
Section titled “Complete Schema Example”{ "params": [ { "name": "invoice_number", "format": "text", "description": "Invoice number" }, { "name": "invoice_date", "format": "date", "description": "Invoice issue date" }, { "name": "total_before_tax", "format": "number", "description": "Total amount before tax" }, { "name": "total_with_tax", "format": "number", "description": "Total amount including tax" }, { "name": "is_paid", "format": "boolean", "description": "Is the invoice paid?" }, { "name": "products", "format": "list", "description": "List of invoiced products", "items": [ { "name": "designation", "format": "text", "description": "Product or service designation" }, { "name": "quantity", "format": "number", "description": "Quantity" }, { "name": "unit_price", "format": "number", "description": "Unit price before tax" } ] } ]}Approach Comparison
Section titled “Approach Comparison”| Criteria | Global Extractor | Agent-based Extractor |
|---|---|---|
| Configuration | Schema defined in API request | Schema preconfigured in Dimarc interface |
| Flexibility | ⭐⭐⭐ Very flexible, different schema for each request | ⭐ Fixed schema, requires modification via interface |
| Maintenance | ⚠️ Schema managed client-side | ✅ Centralized |
| Use case | Testing, one-time extractions, dynamic integrations | Production, repetitive extractions, standardized processes |
| Reusability | ❌ Each client must define the schema | ✅ Schema shared across different systems |
| Request complexity | Larger (includes schema) | Lighter (file only) |
Which approach to choose?
Section titled “Which approach to choose?”Choose the Global Extractor if:
- You are testing or prototyping
- You need different extraction schemas for each document
- You want quick integration without prior configuration
- Your use case is one-time or exploratory
Choose the Agent-based Extractor if:
- You are in production with repetitive processes
- You always extract the same types of data
- You want to centralize extraction schema management
- Multiple systems need to use the same extraction schema
- You want better tracking and traceability
Limitations and Considerations
Section titled “Limitations and Considerations”- Maximum file size: 36 MB. Beyond that, the request is rejected with
413 file_too_largebefore any processing, in synchronous and asynchronous mode alike;detailcarrieslimitandsizein bytes - Supported formats: PDF, PNG, JPG, JPEG, DOCX, XLSX
- Average extraction time: 5 to 10 seconds for standard documents (without too much imagery)
- Processing deadline: 120 s, in synchronous and asynchronous mode alike. Beyond that,
504 agent_timeout(or astatus: "error"event in asynchronous mode); the document must then be resubmitted. In asynchronous mode, a job interrupted by an outage is replayed once while its deadline runs - Asynchronous mode is strongly recommended for files > 20 MB
- Concurrency: at most 4 jobs per organization, synchronous and asynchronous alike — an asynchronous call holds its place until processing actually ends, not until the HTTP response, and releases it as soon as the result is stored, without waiting for
callbackretries. Beyond that,429 concurrent_limit_exceededwithRetry-After; nothing is queued, retry once a job completes. If the engine is saturated,429 queue_saturatedwithRetry-After: retry after that delay - Rate: 100 requests per minute per key,
Retry-Afteron 429
Support and assistance
Section titled “Support and assistance”For any questions regarding the Extractor API, contact our support team at contact@dimarc.fr