Skip to main content
POST
Extract

Overview

The /extract endpoint runs Named Entity Recognition (NER) over a block of text. Unlike standard NER, you define the entity types you want in plain English - the model uses your descriptions to find matching spans, returning each one with a confidence score and surrounding context. Every result includes surrounding text on each side of the matched span, so you can validate or use the extracted value without going back to the source. The amount of context returned is controlled by the context_chars parameter (default: 500 characters per side).

Request

string
The input text to extract entities from. Can be a full document, web page content, article, or any plain text string. Either text or document must be provided. If both are given, the OCR text is appended after text.
string
A base64-encoded file to extract entities from. Supported formats: JPEG, PNG, TIFF, single-page PDF, multi-page PDF. The file is processed via AWS Textract OCR and the extracted text is used as input. Either text or document must be provided.
string
MIME type of the document (e.g. "image/jpeg", "application/pdf"). Required when document is provided.
string
Optional global instruction prepended to the text before extraction. Use this to provide rules that apply across all entity types - for example, deduplication logic, ranking constraints, or output format requirements. This is separate from per-entity descriptions.
number
default:500
Number of characters of surrounding text to include on each side of a matched entity span in the context response field. Set to 0 to omit context entirely, or increase for wider windows on long documents.
object
required
A mapping of entity type names to their definition. Each value can be one of:
  • A plain string - a description of what to look for
  • An object - with optional description, threshold, and top_n fields
  • A nested object - defining a structured sub-schema (object with named fields)
  • An array of objects - defining a repeated structured schema (e.g. a list of line items)
  • A classification key - an object with a labels list, routed to the classifier (see below)
number
Global confidence threshold (0–1). Entities below this score are filtered out. Can be overridden per entity type.
number
default:0
Global limit on how many results to return per entity type, ranked by confidence descending. 0 returns all results above the threshold. Can be overridden per entity type.

Response

array
List of extracted scalar entities, sorted by confidence descending within each type. For nested or array entity types, values appear in structured_result instead.
object | null
Present when any entity in the request uses a nested object or array schema. Contains the full structured extraction result keyed by entity name. Scalar fields from the same request also appear here alongside their nested counterparts. null for flat extraction requests.
string | null
The raw text extracted from the document via OCR. null if no document was provided.

Error responses

Authentication

Include your API key in every request using the x-api-key header.

Examples

Basic extraction

Response:

Extracting from an image (OCR)

Extract works directly on photos and scans, not just plain text. Pass a base64-encoded image (or PDF) in the document field - we run OCR via AWS Textract, then extract your entities from the recovered text. This is the path to use for receipts, invoices, IDs, forms, business cards, and any photographed or scanned page. The raw OCR output is returned as ocr_text so you can audit exactly what the model read.
Supported formats: JPEG, PNG, TIFF, and single- or multi-page PDF. document_mime_type is required whenever document is set - use the file’s real MIME type (e.g. image/jpeg, image/png, application/pdf) so Textract decodes the bytes correctly. You can also send text and document together; the OCR output is appended after your text.
The example below extracts fields from a photographed receipt:
Response:

Extracting from a PDF

PDFs (single- or multi-page) work the same way - just set document_mime_type to application/pdf.

Structured (nested) extraction

For more complex documents, you can define nested schemas to extract structured objects or arrays of objects. Use a nested object to extract a single structured group of fields, or an array of objects to extract a repeated structure such as invoice line items. The full structured output is returned in the structured_result field. Scalar fields in the same request are also included there, alongside any nested values. Nested object example - extract a single structured address:
Response:

Array schema example - extract invoice line items:
Response:
When using array schemas, array fields appear only in structured_result. The entities array contains only scalar fields from the same request that could be matched to a span in the text.

Classification keys

Some of the fields you want are not really extraction targets - they are decisions. “Is this account past due?” or “Is this an electric or gas meter?” have no verbatim span to pull; they require judging the text against a fixed set of options. The extraction model is tuned to copy spans out of the source, so it is a poor fit for these, and mixing them into an extraction call drags down accuracy for every key. To handle these, mark the key as a classification key by giving it a labels list. Any key whose object contains labels is split out of the extraction call and routed to our classification model instead - a model purpose-built for categorical and boolean decisions, using constrained decoding over your labels with calibrated confidence scores. The rest of the request extracts as normal, and classified values are merged back into the same response so nothing changes on your side. Labels can be plain strings, or objects with a name and a rubric describing when that label applies. Rubrics meaningfully improve accuracy - prefer them over bare strings for anything non-obvious. An optional per-key description adds context about the decision.
Response:
The classified value is returned as the entity text, and confidence is the calibrated probability of the chosen label. The label itself is usually not a verbatim span in the source (it was inferred), so start/end and context instead point at the evidence the model used for the decision - here, "90 days past due" for is_delinquent, not the word “delinquent”. If no relevant evidence is found, start/end fall back to 0 and context is empty. In a structured (nested) request, classified values also appear in structured_result under their key.
A classification key still counts as part of your single /extract call - one request in, one response out, billed as one extract call. Each classification key needs at least 2 and at most 26 labels; outside that range the request returns 422.
To locate the evidence span, each classification key runs a brief follow-up pass that pulls the verbatim phrase backing the decision. This is transparent - the span and context are populated for you - but it does add to the token usage reported for the call. If you don’t need spans for a boolean/categorical field, you can ignore start/end/context on those entities.

With per-entity overrides

Use per-entity threshold and top_n when different entity types need different precision, or when you only want the single best match for a given type.
In this example:
  • Name uses threshold 0.3 and returns at most 1 result
  • Company uses threshold 0.7 and returns up to 5 results (global top_n)
  • Email uses the global threshold 0.5 and returns up to 5 results

Writing good entity labels

The entity name and description are both used as part of the model’s search criteria - wording them well is the biggest lever you have on extraction quality. Use lowercase or Title Case. The model was trained with lowercase labels. Keeping your entity names lowercase (e.g. person, company) or Title Case (e.g. Person, Company) produces better results than ALL_CAPS or other conventions. Be specific with names, and test synonyms. The entity name itself influences what the model looks for. person and full name will find slightly different things. If results are missing or noisy, try rephrasing the name - person name, individual, or full name may all behave differently on your data. Labels can be descriptive phrases, not just single words. Instead of city, use capital city and population center. The extra context helps the model distinguish between entity types that might otherwise overlap. Descriptions can be full instructions. Rather than "Name of the person", write "Find the first and last name of the person mentioned in the text". Instruction-style descriptions consistently outperform short noun phrases on complex or ambiguous entities. Avoid mixing overlapping granularities in the same call. If you include both location and city, the model has to decide which label to assign to a city - and will often split results unpredictably between them. Pick one level of granularity per concept. Examples:

Notes

  • Results within each entity type are ranked by confidence descending before top_n is applied.
  • The context field is always derived from the original text input - it is not generated by the model.
  • Character offsets (start, end) refer to byte positions in the original text string.
  • There is no fixed limit on the number of entity types you can define in a single request.
  • Classification keys (any entity object with a labels list) are routed to the classification model rather than extracted. Use them for boolean or categorical fields - keeping them out of the extraction path improves accuracy for both.
  • threshold and top_n do not apply to classification keys - the value is a single chosen label, always returned.

Authorizations

x-api-key
string
header
required

Body

application/json
text
string
required

The input text to extract entities from.

entities
object
required

A mapping of entity type names to their definition.

threshold
number
default:0.5

Global confidence threshold (0–1).

top_n
number
default:0

Global limit on results per entity type. 0 returns all above threshold.

Response

Successful extraction

entities
object[]