Skip to main content

Document Import

Find unread contract documents, queue them for term extraction one by one or all at once with dry run and limit, and follow the import queue and its failures.

Documents enter the Contracts app through an import queue. The queue reads each document for its terms and files it under a contract key. Four routes drive it: the candidate list shows what is waiting to be read, POST /v1/contracts/import queues named documents, POST /v1/contracts/import/all queues every candidate under optional filters, and the status route shows the queue counts and the latest failures.

A candidate is a document that looks like a contract document (by filename or inferred type), has extracted text and has not been read for terms yet. Invoices are excluded. Candidates are grouped by the contract key their filename carries, at most 2000 documents are considered, and the groups are ordered so that keys Price Baseline already models come first, then keyed groups, then the largest groups. A group with a null contract key holds documents whose filename carries no key.

GET/v1/contracts/import/candidates

Query parameters

qstringCase-insensitive substring over the filename.

Group fields (data[])

contract_keystring | nullThe key the filenames carry; null when they carry none.
in_price_baselinebooleanWhether Price Baseline already models this key.
documents[]arraydocument_id, filename, created_at and import (the document's queue entry with status pending, running, done or failed and an error, or null when it was never queued).

Queueing Documents

POST /v1/contracts/import queues up to 500 documents by id. A failed document is queued again; a document that is waiting or done is left alone unless force is true. skipped counts every id that was not queued, including ids that are not live documents of the workspace. Use force to read documents again after a prompt change or a corrected OCR.

POST/v1/contracts/import

Body fields

document_ids*string[] (uuid)1 to 500 document ids.
forcebooleanRead documents that were already read again.

cURL: Queue two documents

curl -X POST "https://api.talonic.com/v1/contracts/import" \
  -H "Authorization: Bearer $TALONIC_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"document_ids": ["0b7d3c1e-5f2a-4c68-8a19-7e4d9b2c6a30", "5e91a7d3-4c20-4b8f-9d16-3a7c0e2b8f54"]}'

Response: 201

{ "queued": 2, "skipped": 0 }

Queueing Every Candidate

POST /v1/contracts/import/all queues every candidate, optionally narrowed by filename (query), by contract_keys or to keys Price Baseline models (only_priced), and capped by limit so that a first batch can be checked before the rest. The body is optional. With dry_run: true the route counts what would be queued and queues nothing, and queued is always 0.

POST/v1/contracts/import/all

Body fields (all optional)

querystringUp to 200 characters. Only documents whose filename contains this.
contract_keysstring[]Up to 2000 keys of up to 64 characters, as the candidates list prints them.
only_pricedbooleanOnly keys Price Baseline already models.
dry_runbooleanCount what would be queued and queue nothing.
limitinteger1 to 20000. Queue at most this many documents.

Response fields

dry_runbooleanEchoes the request.
contractsintegerCandidate groups (contract keys) after the filters.
documentsintegerDocuments selected after the filters and limit.
queuedintegerAlways 0 with dry_run.
skippedintegerDocuments selected but not queued.

cURL: Dry run, then a first batch of 50

curl -X POST "https://api.talonic.com/v1/contracts/import/all" \
  -H "Authorization: Bearer $TALONIC_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"query": "WLV", "dry_run": true}'

curl -X POST "https://api.talonic.com/v1/contracts/import/all" \
  -H "Authorization: Bearer $TALONIC_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"query": "WLV", "limit": 50}'

Following the Queue

GET /v1/contracts/import/status returns counts per queue status (pending, running, done, failed; a status with no entries is absent) and failed, the 20 failed entries updated last, each with the document id, filename, error and number of attempts. Poll it after a bulk import and re-queue the failed documents with POST /v1/contracts/import once the cause is fixed.

GET/v1/contracts/import/status

Response: Queue state

{
  "counts": { "pending": 112, "running": 4, "done": 1830, "failed": 2 },
  "failed": [
    {
      "document_id": "7ac4e0d1-3b92-4f65-8d1a-6e5b9c2f0a37",
      "filename": "1043055-WLV_Nachtrag.pdf",
      "error": "No extractable text",
      "attempts": 3
    }
  ]
}
The import queue reads documents for terms, which costs model calls. Check a first batch with dry_run and limit before queueing a whole workspace, and use force only when a re-read is intended.

Frequently asked questions

Which documents are import candidates?+
Documents that look like contract documents by filename or inferred type, have extracted text and have not been read for terms yet. Invoices are excluded. At most 2000 documents are considered, grouped by the contract key in the filename.
What does skipped count in an import response?+
Every id that was not queued: documents that are already waiting or done (unless force is true), and ids that are not live documents of the workspace.
How do I check what a bulk import would do before running it?+
Send POST /v1/contracts/import/all with dry_run set to true. The response reports the number of candidate groups and documents the filters select, and queued is always 0. Then run it with limit to queue a first batch.
How do I retry a failed document?+
Send its id to POST /v1/contracts/import. A failed document is queued again without force. The import status route lists the 20 most recently updated failures with their error and attempts.