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
Example Request
Section titled “Example Request”Create a template named invoice in the app, then send a file using your
environment API key:
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.
Request Schema
Section titled “Request Schema”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.
| Field | Value | Effect |
|---|---|---|
file | Required file part or JSON data URL | The document to extract |
filename | Optional string; defaults to file | Names a JSON upload; multipart uses the file part’s filename |
templateName | String; required unless using filterName | Selects a saved extraction template |
filterName | Optional string | Selects a saved filter to classify documents and choose templates |
documentSplitting | Boolean; default false | Identifies separate documents within the upload |
returnDocuments | Boolean; default false | Requests a PDF for each document; see Returned Documents |
returnText | Boolean; default false | Includes detected text by page; see Returned Text |
schemaChunking | auto (default) or combined | Uses automatic field grouping, or keeps template fields together with combined |
password | Optional string | Password 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.
Files And Upload Limits
Section titled “Files And Upload Limits”Send one file per request with an accurate filename and MIME type.
| Format | Extensions | MIME type |
|---|---|---|
.pdf | application/pdf | |
| JPEG | .jpg, .jpeg | image/jpeg |
| PNG | .png | image/png |
| BMP | .bmp | image/bmp |
| TIFF | .tif, .tiff | image/tif, image/tiff |
| Microsoft Word | .doc | application/msword |
| Microsoft Word Open XML | .docx | application/vnd.openxmlformats-officedocument.wordprocessingml.document |
| Plain text | .txt | text/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 form | Size limit |
|---|---|
| Multipart | The file limit defaults to 50 MiB; your environment may use a different limit. |
| JSON data URL | The 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.
Response Schema
Section titled “Response Schema”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 } } } ] }}| Field | Meaning |
|---|---|
requestId | Generated identifier for the request. |
clientReference | Your reference, included when you sent X-Client-Reference. |
data.completionTime | Processing time in seconds. |
data.originalName | The uploaded filename. |
data.processedPages | Pages processed across extracted documents. |
data.documents | A result for each identified document, including any skipped by a filter. |
Document Outcomes
Section titled “Document Outcomes”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.
Shared Pages When Splitting
Section titled “Shared Pages When Splitting”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.
Extracted Content
Section titled “Extracted Content”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 }}| Property | Meaning |
|---|---|
value | A string, number, boolean, or null when no value was found. |
confidence | Optional confidence from 0 to 100. |
page | Optional source page number, starting at 1. |
boundingBox | Optional 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.
Returned Documents
Section titled “Returned Documents”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.
Returned Text
Section titled “Returned Text”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.
Errors
Section titled “Errors”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.