Skip to content
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.

01
Concepts
Three words you will meet

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

02
Steps
Five steps

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.

  1. 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 as Authorization: Bearer on 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 401 at 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.

  2. 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 returned id, it is your entity_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.

  3. Upload a document

    Send the file with the entity_group_id from 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 the documentId for its status and the extractedDocumentId for 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"}

    Each document spends credits from your plan: see Plan & billing in the console.

  4. Read the result

    Processing is asynchronous. Poll the document's status until it reaches a terminal state: completed, or failed, too large, limit reached or insufficient 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 in data[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 (default 0) and limit (default 100, at most 500) while has_more is true. For one document alone, use GET /extracted-documents/{id} with the extractedDocumentId from step 3.

  5. 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_id when you create the template. A document refused before extraction (too large, limit reached, insufficient credits or 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.

The whole flow in one script.

Set PARSER_API_KEY, replace the file path, then run it.

03
Script
Steps 1 to 4 in one file
SCRIPT · flow.shbash
#!/usr/bin/env bashset -euo pipefailBASE="https://api.parserai.co"# 1. Authenticate: an API key from the console's API keys page: "${PARSER_API_KEY:?set PARSER_API_KEY to your API key}"# 2. Create a template and keep its idGROUP_ID=$(curl -s -X POST "$BASE/entity-groups/with-entities" \  -H "Authorization: Bearer $PARSER_API_KEY" -H 'Content-Type: application/json' \  -d '{"name":"Invoices","entities":[        {"name":"Invoice Number","prompt":"Extract the invoice number"},        {"name":"Total Amount","prompt":"Extract the total amount, digits only"}]}' \  | jq -r .id)# 3. Upload a document against the templateDOC_ID=$(curl -s -X POST "$BASE/documents/upload" \  -H "Authorization: Bearer $PARSER_API_KEY" \  -F "file=@invoice.pdf" -F "entity_group_id=$GROUP_ID" \  | jq -r .documentId)# 4. Poll until the document reaches a terminal statuswhile :; do  STATUS=$(curl -s "$BASE/documents/status/$DOC_ID" -H "Authorization: Bearer $PARSER_API_KEY" | jq -r .)  echo "status: $STATUS"  case "$STATUS" in    completed|failed|"too large"|"limit reached"|"insufficient credits") break ;;  esac  sleep 3done# 5. Fetch the structured result (only a completed document has one)if [[ "$STATUS" == "completed" ]]; then  curl -s "$BASE/extracted-documents/by-template/$GROUP_ID" \    -H "Authorization: Bearer $PARSER_API_KEY" | jq '.data[0].extracted_data'else  echo "not extracted: $STATUS"fi
04
Next
After the first file

Where to go next.

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.