The problem
PDFs describe where text appears on a page, not necessarily which business field it represents. A text dump can separate labels from values, while a free-form model answer can change shape from one request to the next.
How NativePort helps
NativePort connects your PDF to a document reader and lets you specify the facts to collect. The result combines readable page content with named fields, making it easier to hand the document’s information to another tool or database.
Technical implementation
Use Python 3 with requests installed (python -m pip install requests). Set NATIVEPORT_API_KEY in your environment to your NativePort key. Run the snippets on your server, where your key stays private.
Set DOCUMENT_URL to an HTTPS URL the document service can fetch, such as a time-limited file link. The example reads page 0 (the first page). Select only pages you need, up to 100 per request; split longer documents into batches. Send the URL, not inline file bytes.
This example extracts contract details. Rename the schema fields for your own documents.
import os
import requests
BASE = "https://api.nativeport.ai"
HEADERS = {"Authorization": f"Bearer {os.environ['NATIVEPORT_API_KEY']}"}
payload = {
"document": {"type": "document_url", "document_url": os.environ["DOCUMENT_URL"]},
"pages": [0],
}
schema = {'type': 'object',
'properties': {'document_title': {'type': ['string', 'null']},
'parties': {'type': ['string', 'null']},
'effective_date': {'type': ['string', 'null']},
'renewal_terms': {'type': ['string', 'null']}},
'required': ['document_title', 'parties', 'effective_date', 'renewal_terms'],
'additionalProperties': False}
payload["document_annotation_format"] = {
"type": "json_schema",
"json_schema": {"name": "extraction", "strict": True, "schema": schema},
}
payload["document_annotation_prompt"] = (
'Extract only what is visible. Use null for missing or unreadable values.'
)
response = requests.post(BASE + "/mistral/v1/ocr", headers=HEADERS,
json=payload, timeout=120)
response.raise_for_status()
result = response.json()
import json
fields = result.get("document_annotation")
if isinstance(fields, str):
fields = json.loads(fields)
if fields is None:
raise ValueError("No document annotation returned; inspect the OCR response")
print(fields)Only selected pages are processed. Include the pages containing the requested facts, and merge batch results deliberately for longer documents. Use null for missing information. Structured annotations use the Document AI rate.
See the Mistral request policy for document URLs, page selection, and accepted options. OCR returns recognized content; check unclear scans against the source.
Tool costs
| Tool used in the example | Price per call |
|---|---|
| Mistral — structured extraction | $0.005275 / call (1 page) |
Prices in USD. Usage-based tools have no fixed per-call price. View pricing.
Let your agent build it
You don’t need to write this code yourself. Copy this page’s link and paste it into your agent. Ask it to follow the guide and implement the feature for you.