Skip to content

Synchronous Extraction

Upload a document and receive the extracted data in the same request. For jobs you want to retrieve later or connect to a webhook, use Asynchronous Extraction.

POST /api/v1/extractFields

Create a template named invoice in the app, then send a file using your environment API key:

Terminal window
curl -X POST "https://api.terrafai.com/api/v1/extractFields" \
-H "Authorization: api-key $API_KEY" \
-H "X-Client-Reference: account-42:invoice-1001" \
-F "file=@invoice.pdf;type=application/pdf" \
-F "templateName=invoice"

X-Client-Reference is optional. Use it to connect the extraction to a record in your system; see Client Reference.

Send one file using multipart/form-data, or application/json with a data URL in file. Put the extraction settings at the top level of the request.

FieldValueEffect
fileRequired file part or JSON data URLThe document to extract
filenameOptional string; defaults to fileNames a JSON upload; multipart uses the file part’s filename
templateNameString; required unless using filterNameSelects a saved extraction template
filterNameOptional stringSelects a saved filter to classify documents and choose templates
documentSplittingBoolean; default falseIdentifies separate documents within the upload
returnDocumentsBoolean; default falseRequests a PDF for each document; see Returned Documents
returnTextBoolean; default falseIncludes detected text by page; see Returned Text
schemaChunkingauto (default) or combinedUses automatic field grouping, or keeps template fields together with combined
passwordOptional stringPassword for a protected document

Choose templateName when you know the document type, or filterName when a filter should choose the template. Use the saved name from your environment.

For booleans, send JSON true or false, or multipart values "true" or "false". Omit optional fields to use their defaults. To require human review, use async extraction with documentReview.

Send one file per request with an accurate filename and MIME type.

FormatExtensionsMIME type
PDF.pdfapplication/pdf
JPEG.jpg, .jpegimage/jpeg
PNG.pngimage/png
BMP.bmpimage/bmp
TIFF.tif, .tiffimage/tif, image/tiff
Microsoft Word.docapplication/msword
Microsoft Word Open XML.docxapplication/vnd.openxmlformats-officedocument.wordprocessingml.document
Plain text.txttext/plain

For multipart uploads, name the file field file. For JSON uploads, include the MIME type and Base64 prefix in the file value:

data:application/pdf;base64,JVBERi0xLjQK...
Upload formSize limit
MultipartThe file limit defaults to 50 MiB; your environment may use a different limit.
JSON data URLThe complete JSON body must fit within 50 MiB. The decoded file must also fit within the environment’s file limit.

Base64 adds about one third to the file size, so use multipart for larger files. One MiB is 1,048,576 bytes.

A file over the active limit returns 400 FILE_TOO_LARGE, with the limit in the error message. A JSON body over its limit returns HTTP 413.

A completed request returns HTTP 200. Field names inside content come from your template; these invoice fields are examples.

{
"success": true,
"requestId": "req_9d6a4f3c-0d7b-4ab1-9b1a-5b27499e9c2f",
"clientReference": "account-42:invoice-1001",
"data": {
"completionTime": 2.31,
"originalName": "invoice.pdf",
"processedPages": 1,
"documents": [
{
"extracted": true,
"documentName": "Invoice",
"averageDocumentConfidence": 98,
"sourcePages": [1],
"content": {
"invoiceNumber": { "value": "INV-1001", "confidence": 98, "page": 1 },
"supplier": {
"name": { "value": "Example Supplier", "confidence": 98, "page": 1 }
},
"lineItems": [
{
"description": { "value": "Service fee", "confidence": 98, "page": 1 },
"quantity": { "value": 1, "confidence": 98, "page": 1 },
"amount": { "value": 120, "confidence": 98, "page": 1 }
}
],
"totalAmount": { "value": 120, "confidence": 98, "page": 1 }
}
}
]
}
}
FieldMeaning
requestIdGenerated identifier for the request.
clientReferenceYour reference, included when you sent X-Client-Reference.
data.completionTimeProcessing time in seconds.
data.originalNameThe uploaded filename.
data.processedPagesPages processed across extracted documents.
data.documentsA result for each identified document, including any skipped by a filter.

Check extracted on each document before reading content. A completed request can contain both extracted and skipped documents.

For example, a filter may skip a cover letter:

{
"extracted": false,
"documentName": "Cover Letter",
"sourcePages": [1],
"message": "Document not extracted. It was classified as \"Cover Letter\" and was filtered out.",
"reason": "FILTERED_OUT_Cover Letter"
}

Keep the message and reason when present so you can see why a document was skipped or could not be extracted. A filter exclusion is intentional; review the outcome before retrying it.

For extracted documents, a field’s value is null when it was not found. Check the fields your application requires before passing the result on.

With documentSplitting=true, one upload can produce several documents or sections. sourcePages identifies the original pages used by each result. Sometimes one page contains the end of one document and the start of another. That page appears in both results, and sharedPages identifies the overlap.

For example, these two results share page 2:

{
"documents": [
{
"documentName": "Invoice",
"sourcePages": [1, 2],
"sharedPages": [2]
},
{
"documentName": "Credit Application",
"sourcePages": [2, 3],
"sharedPages": [2]
}
]
}

Use these page numbers to show the right source pages beside each extraction or to organize split files. Keep a shared page with each document that needs it, even if a filter skips another document using that page.

sharedPages is omitted when there is no overlap. It can appear on skipped documents too. processedPages counts pages across extracted documents, so a shared page can contribute to that count more than once.

A scalar field contains its value and any available confidence and location information:

{
"value": "INV-10482",
"confidence": 97,
"page": 2,
"boundingBox": {
"top": 0.1,
"left": 0.2,
"width": 0.32,
"height": 0.08
}
}
PropertyMeaning
valueA string, number, boolean, or null when no value was found.
confidenceOptional confidence from 0 to 100.
pageOptional source page number, starting at 1.
boundingBoxOptional location on the source page, with coordinates normalized from 0 to 1.

Treat 0 and false as values. Check value for null to identify missing data, and check that confidence and location information is available before using it.

Nested objects follow your template structure. Repeated rows are arrays of objects, and an array with no rows is [].

Image fields contain a PNG data URL when found, with optional crop metadata:

{
"value": "data:image/png;base64,...",
"page": 2,
"boundingBox": {
"top": 0.1,
"left": 0.2,
"width": 0.32,
"height": 0.08
},
"image": {
"mimeType": "image/png",
"width": 320,
"height": 80
}
}

Check value for null before decoding an image.

Set returnDocuments=true when you need a PDF of each identified document, for example to save separate files from a split upload.

Read returnedDocumentBase64 when it is present on a document item. Decode the Base64 value directly and save the bytes as a .pdf file with MIME type application/pdf. It contains no data URL prefix.

The returned file is a generated PDF. Check for the field before decoding, and use extracted to determine whether structured data was extracted from that document.

Set returnText=true to include detected page text in each extracted document’s returnedText field. Use it when your application needs text to display beside the extracted fields, search, or store in its own document index.

For multipart requests, add -F "returnText=true". For JSON requests, add "returnText": true. The same option works for sync and async extraction.

The document result includes an ordered array of pages:

{
"returnedText": [
{ "page": 1, "text": "Invoice Number: INV-1001\nTotal: 120.00" },
{ "page": 2, "text": "Payment is due within 30 days." }
]
}

Each entry contains the original page number and its detected text. Blank pages have an empty text string. Read your template’s structured fields from content and the page text from returnedText.

The field is omitted unless you request it. Leave returnText off when you only need structured values to keep the response smaller.

See Authentication & Errors for request, file, authentication, quota, and rate-limit errors. If a synchronous request times out, retrying can process the file again. Use async jobs with an idempotency key when safe upload retries are required.