- Page
- API guide
- Steps
- API key · Template · Upload · Result · Webhook
- Base URL
https://api.parserai.co
Your first integration
Create an API key, define the fields you want, upload a file and read the JSON. Every snippet is ready to copy.
How Parser works.
You describe the fields once, send files, and read the same fields back.
- 1.1
Template
A named set of the fields you want from a document (an “entity group” in the API). Each field has a plain-language prompt that tells the model what to extract.
API names entity_group_id entities prompt
- 1.2
Document
A file you send to be read against a template. The upload takes PDF, TXT, JSON, DOCX, CSV and XLSX files, and Parser reads the whole file.
API names file documentId
- 1.3
Extraction
The structured result: a list of objects keyed by your field names, and a status. Poll for it when the document finishes, or have Parser call your server by webhook.
API names extracted_data extraction_status
From API key to JSON.
Every call goes to https://api.parserai.co with your API key as Authorization: Bearer YOUR_API_KEY; replace the other words in capitals with your own values.
Create an API key
On the console's API keys page choose New API key and name it after the integration: one key per integration, so each can be revoked on its own. The key starts with
prs_and is shown once, so copy it right away. Send it asAuthorization: Beareron every request. No account yet? REST API and webhooks are included in every plan, Free too (no card required). Sign up free.REQUEST · GET /profiles/mecurl # The key from API keys > New API key (shown once). Keep it out of your code.export PARSER_API_KEY='prs_...'# Check it: returns the account the key belongs tocurl 'https://api.parserai.co/profiles/me' \ -H "Authorization: Bearer $PARSER_API_KEY"Keep it secret. A key acts as your account. Keep it on your server, in an environment variable or a secret store: never in browser or mobile code, a repository, tickets or chat. If one leaks, revoke it and create a new one.
A key does not expire: it works until you revoke it on the API keys page, and a revoked key gets
401at once. An account holds up to 10 active keys. To rotate one with no downtime, create the new key and deploy it, wait until the old key's Last used stops changing in the console, then revoke the old one.Already signing in with
POST /auth/login? It keeps working. Its token lasts 1 hour, so your script has to keep your password and sign in again: move to a key when you can, nothing else in your integration changes.Create a template
A template (an entity group) is the list of fields you want back. Give each field a short, explicit
prompt: that is what the model follows. Keep the returnedid, it is yourentity_group_id.REQUEST · POST /entity-groups/with-entitiescurl curl -X POST 'https://api.parserai.co/entity-groups/with-entities' \ -H "Authorization: Bearer $PARSER_API_KEY" \ -H 'Content-Type: application/json' \ -d '{ "name": "Invoices", "description": "Fields to pull from every invoice", "entities": [ { "name": "Invoice Number", "description": "The invoice number", "prompt": "Extract the invoice number" }, { "name": "Total Amount", "description": "The grand total", "prompt": "Extract the total amount, digits only" }, { "name": "Issue Date", "description": "When the invoice was issued", "prompt": "Extract the issue date as YYYY-MM-DD" } ]}'RESPONSE · 201 Created · abridgedJSON { "id": "your-entity-group-id", "name": "Invoices", "description": "Fields to pull from every invoice", "user_id": "your-user-id", "entities": [ { "id": "your-entity-id-1", "name": "Invoice Number", "prompt": "Extract the invoice number" }, { "id": "your-entity-id-2", "name": "Total Amount", "prompt": "Extract the total amount, digits only" }, { "id": "your-entity-id-3", "name": "Issue Date", "prompt": "Extract the issue date as YYYY-MM-DD" } ]}Tip. Say the format you want (dates, digits, currency) in the field's prompt, as the examples do.
Upload a document
Send the file with the
entity_group_idfrom step 2. The simple upload sends it in one request. For large files, ask for a signed URL and send the bytes to it: PDFs up to 200 MB, other files up to 50 MB.The response is
202 Accepted: the document is queued, not finished. Keep thedocumentIdfor its status and theextractedDocumentIdfor its result.REQUEST · POST /documents/uploadcurl curl -X POST 'https://api.parserai.co/documents/upload' \ -H "Authorization: Bearer $PARSER_API_KEY" \ -F 'file=@invoice.pdf' \ -F 'entity_group_id=YOUR_ENTITY_GROUP_ID'RESPONSE · 202 AcceptedJSON { "message": "Document accepted for processing.", "documentId": "your-document-id", "extractedDocumentId": "your-extracted-document-id", "entityGroupId": "your-entity-group-id"}Ask for a signed URL; the document record is created then. Send the raw bytes to
signed_urlwithPUTand aContent-Typeheader. The URL is valid for 30 minutes and carries its own credential, so that request has noAuthorizationheader. When it completes, extraction starts.REQUEST · POST /documents/upload/generate-signed-urlcurl curl -X POST 'https://api.parserai.co/documents/upload/generate-signed-url' \ -H "Authorization: Bearer $PARSER_API_KEY" \ -H 'Content-Type: application/json' \ -d '{ "file_name": "invoice.pdf", "entity_group_id": "YOUR_ENTITY_GROUP_ID"}'RESPONSE · 200 OK · abridgedJSON { "signed_url": "https://api.parserai.co/uploads/YOUR_UPLOAD_TOKEN", "document_id": "your-document-id", "extracted_document_id": "your-extracted-document-id"}REQUEST · PUT signed_urlcurl curl -X PUT 'SIGNED_URL_FROM_THE_RESPONSE' \ -H 'Content-Type: application/pdf' \ --data-binary '@invoice.pdf'Each document spends credits from your plan: see Plan & billing in the console.
Read the result
Processing is asynchronous. Poll the document's status until it reaches a terminal state:
completed, orfailed,too large,limit reachedorinsufficient credits. The response is a bare JSON string, such as"processing"and then"completed".REQUEST · GET /documents/status/{document_id}curl curl 'https://api.parserai.co/documents/status/YOUR_DOCUMENT_ID' \ -H "Authorization: Bearer $PARSER_API_KEY"RESPONSE · 200 OKJSON "completed"Once it is
completed, fetch the results of your template, newest first. Each result is indata[i].extracted_data, a list of rows keyed by your field names.REQUEST · GET /extracted-documents/by-template/{entity_group_id}curl curl 'https://api.parserai.co/extracted-documents/by-template/YOUR_ENTITY_GROUP_ID' \ -H "Authorization: Bearer $PARSER_API_KEY"SampleRESULT · 200 OK · abridgedJSON { "data": [ { "id": "your-extracted-document-id", "document_id": "your-document-id", "entity_group_id": "your-entity-group-id", "extraction_status": "success", "extracted_data": [ { "Invoice Number": "INV-2024-0042", "Total Amount": "1899.00", "Issue Date": "2024-01-15" } ], "document_title": "invoice.pdf" } ], "total_count": 1, "skip": 0, "limit": 100, "has_more": false}Page through them with
skip(default0) andlimit(default100, at most500) whilehas_moreis true. For one document alone, useGET /extracted-documents/{id}with theextractedDocumentIdfrom step 3.Skip polling with a webhook (optional)
Register your endpoint, then attach the webhook to the template: it fires only for the templates it is attached to. Parser then POSTs each extraction of that template to your URL when it completes or fails. You can also pass
webhook_idwhen you create the template. A document refused before extraction (too large,limit reached,insufficient creditsor an unsupported file) sends no webhook: poll its status.REQUEST · POST /webhooks/ · PUT /entity-groups/{entity_group_id}curl # 1. Register your endpointcurl -X POST 'https://api.parserai.co/webhooks/' \ -H "Authorization: Bearer $PARSER_API_KEY" \ -H 'Content-Type: application/json' \ -d '{ "name": "My integration", "url": "https://your-domain.com/parser-webhook", "is_active": true }'# -> { "id": "YOUR_WEBHOOK_ID", ... }# 2. Attach it to the template: its documents are POSTed to your endpointcurl -X PUT 'https://api.parserai.co/entity-groups/YOUR_ENTITY_GROUP_ID' \ -H "Authorization: Bearer $PARSER_API_KEY" \ -H 'Content-Type: application/json' \ -d '{ "webhook_id": "YOUR_WEBHOOK_ID" }'Each delivery is logged: read the log with
GET /webhooks/logs, or manage webhooks in the console.
Where to go next.
- 4.1
API reference
API reference, open the referenceEvery endpoint, parameter and response, read from the OpenAPI spec.
- 4.2
Webhooks
Webhooks, see the endpointsCreate, list and update webhook endpoints, and read the log of their deliveries.
- 4.3
Try it on one file
Try it on one file, open the playgroundTry one file of your own, no account or card.
- 4.4
Security
Security, read the pageHow documents are stored, deleted and protected.
See it on your own documents.
In the demo we process your documents live — no slides, no fluff.
30 minutes · no commitment
Self-serve
Free, Starter ($9.90/month) and Pro ($100/month) start when you sign up. No card required for Free.
Enterprise
By contract · your own model key · an engineer for your team · setup done for you if you want it · POC on your documents.