Skip to content

Classification

This document describes how to use the DIMARC API to classify a document into page ranges according to business categories. The API does not split the file and does not emit any binary: the deliverable is a JSON indicating where each category starts and ends.

Fenêtre de terminal
POST /v2/classification
POST /v2/classification/async

Use case: Sorting a batch of scanned pages mixing several document types (e.g. invoices, delivery notes, contracts) without manually splitting them beforehand.

  1. Synchronous: The request is processed immediately and the response is returned in the same HTTP connection.
  2. Asynchronous: The processing is queued and the results are sent to a defined webhook once the classification is completed.
Fenêtre de terminal
curl --location 'https://api.dimarc.ai/v2/classification' \
--header 'Content-Type: application/json' \
--header 'x-api-key: <your_api_key>' \
--data '{
"filename": "document-batch.pdf",
"file": "<base64_encoded_file>",
"classes": [
{
"name": "invoice",
"description": "Invoice issued by a supplier"
},
{
"name": "delivery_note",
"description": "Delivery note accompanying an order"
}
]
}'
Parameter Type Description
filename string Original filename (with extension)
file string File content encoded in base64
classes array Categories to detect (see Classes Structure) — can be empty only if options.guess is true
options object Optional options (see Options)

Each element in the classes array is an object with the following properties:

Property Type Description
name string Category name
description string Category description (helps the AI tell documents apart)
Property Type Description
guess boolean Guess the categories instead of relying on classes — the only case where classes can be empty. Proposed categories are returned in discovered_classes
per_page boolean Classify page by page instead of by document range (reflected in the response’s data.mode)
system string Additional system instruction passed to the classification model
{
"status": "success",
"data": {
"source_name": "document-batch.pdf",
"mode": "document",
"segments": [
{
"start": 1,
"end": 3,
"label": "invoice",
"title": "Invoice #2024-001",
"confidence": 0.92
},
{
"start": 4,
"end": 5,
"label": "delivery_note",
"title": "Delivery note",
"confidence": 0.87
}
],
"discovered_classes": [],
"pages_count": 5
},
"metadata": {
"filename": "document-batch.pdf",
"duration": 4.12,
"tokens_consumed": 1,
"thread_id": "01J..."
}
}
{
"status": "error",
"code": "classification_failed",
"error": "Classification 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.

Status Code Case
422 invalid_request Invalid request body, or classes empty without options.guess
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
413 file_too_large File larger than 36 MB; detail carries limit and size in bytes
422 infected_file File flagged by the antivirus
503 antivirus_unavailable Antivirus service unavailable
503 agent_unavailable Processing queue unavailable
502 classification_failed The agent could not process the classification
504 agent_timeout Processing deadline exceeded (120 s synchronous, 5 min asynchronous)

Asynchronous mode raises the processing deadline to 5 min (120 s in synchronous mode): use it from a few dozen pages upward.

Fenêtre de terminal
curl --location 'https://api.dimarc.ai/v2/classification/async' \
--header 'Content-Type: application/json' \
--header 'x-api-key: <your_api_key>' \
--data '{
"filename": "document-batch.pdf",
"file": "<base64_encoded_file>",
"classes": [
{
"name": "invoice",
"description": "Invoice issued by a supplier"
}
],
"callback": "https://your-callback-endpoint.com/webhook"
}'
Parameter Type Description
filename string Original filename (with extension)
file string File content encoded in base64
classes array Categories to detect — same rules as synchronous
options object Optional options (see Options)
callback string URL of the webhook that will receive the result
{
"status": "started",
"classification_id": "01K74Z3Q8RVN5XW2B6JHMTGD9C"
}

The classification_id identifies the job. If you have not received the callback yet, or if your endpoint was unavailable, fetch the result with this identifier:

Fenêtre de terminal
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.

When the classification is complete, the result is sent to the 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 classification.completed event if you have configured an organization webhook — useful for centralizing delivery without depending on the per-request callback.

{
"status": "success",
"classification_id": "01K74Z3Q8RVN5XW2B6JHMTGD9C",
"data": {
"source_name": "document-batch.pdf",
"mode": "document",
"segments": [
{
"start": 1,
"end": 3,
"label": "invoice",
"title": "Invoice #2024-001",
"confidence": 0.92
}
],
"discovered_classes": [],
"pages_count": 3
},
"metadata": {
"filename": "document-batch.pdf",
"duration": 4.12,
"tokens_consumed": 1,
"thread_id": "01J..."
}
}
{
"status": "error",
"classification_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).

  • Supported format: PDF only
  • Maximum file size: 36 MB (413 file_too_large beyond that, before any processing, in synchronous and asynchronous mode alike)
  • Processing deadline: 120 s synchronous, 5 min asynchronous. Beyond that, 504 agent_timeout (or a status: "error" event in asynchronous mode); the document must then be resent. In asynchronous mode, a job interrupted by an outage is replayed once while its deadline runs
  • Large documents: beyond 5 min of processing (several hundred pages), split the PDF into batches of 30 to 50 pages, one asynchronous call per batch, then reassemble the segments by shifting start and end by the batch offset
  • Classes: no limit on their number; keep descriptions short, they are injected into every model call. options.system is capped at 4000 characters
  • 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 callback retries. Beyond that, 429 concurrent_limit_exceeded with Retry-After; nothing is queued, retry once a job completes. If the engine is saturated, 429 queue_saturated with Retry-After: retry after that delay
  • Rate: 100 requests per minute per key, Retry-After on 429

For any questions regarding the Classification API, contact our support team at contact@dimarc.fr