Developer quickstart
ParseDoc is a plain HTTP API. Every call is a single request; responses are strict JSON. Authenticate with a Bearer API key, or pay per call with x402 and skip the account entirely. This page gets you from zero to a parsed document.
Authentication
Sign up with an email to get an API key, then send it on every request as an Authorization Bearer header. The first 100 pages each month are free on the parse endpoint.
curl -X POST https://parsedoc.io/v1/signup \
-H "Content-Type: application/json" \
-d '{"email": "dev@example.com"}'
# 201 -> account_id, api_key (shown once), plan, free_pagesThe API key is returned once, at signup, and never shown again. Store it securely; you can create more from the console.
Parse a document
Send a file as multipart or a public url as JSON. Options: mode (fast or accurate) and output (json or markdown). Small documents return 200 with the result; larger ones return 202 with a poll_url you follow until the job reaches a terminal status.
# Multipart file upload.
curl -X POST https://parsedoc.io/v1/parse \
-H "Authorization: Bearer <api_key>" \
-F "file=@invoice.pdf" \
-F "mode=accurate" \
-F "output=json"
# 200 -> { "job_id", "pages", "cost_usd", "output" }
# 202 -> { "job_id", "status": "processing", "poll_url": "/v1/jobs/<job_id>" }# Or pass a public URL as JSON.
curl -X POST https://parsedoc.io/v1/parse \
-H "Authorization: Bearer <api_key>" \
-H "Content-Type: application/json" \
-d '{"url": "https://example.com/doc.pdf", "mode": "fast", "output": "markdown"}'Extract an invoice
The vertical endpoint returns a normalized French and EU invoice: SIREN, SIRET, intra-community VAT, invoice number, dates, line items and totals. Same file or url input, same job lifecycle as parse.
curl -X POST https://parsedoc.io/v1/extract/invoice \
-H "Authorization: Bearer <api_key>" \
-F "file=@invoice.pdf"
# output: normalized invoice JSON with siren, siret, tva_intracom,
# numero_facture, date_emission, date_echeance, lignes, total_ht,
# total_tva, total_ttc and ibanEnrich with AI
Send raw text or the job_id of an already-parsed document (exactly one), an optional mode (complete, acronyms or both) and an optional domain hint. Enrichment is usage-based, billed in credits from your prepaid balance, with no free tier; the exact price is returned in usage.cost_usd. Pass an Idempotency-Key to replay a call without being billed twice.
curl -X POST https://parsedoc.io/v1/enrich \
-H "Authorization: Bearer <api_key>" \
-H "Content-Type: application/json" \
-H "Idempotency-Key: 7c9e6a20" \
-d '{"text": "The API and the SDK are ready.", "mode": "both", "domain": "software"}'{
"job_id": "b1d2...",
"mode": "both",
"output": {
"markdown": "...",
"tables": [],
"metadata": { "mode": "both", "acronyms": { "API": "Application Programming Interface" } }
},
"usage": { "tokens_in": 128, "tokens_out": 64, "cost_usd": 0.004, "credits_debited": 1 }
}Poll a job
Fetch a job by its id to get its status and, once terminal, its result. Jobs are scoped to your account.
curl https://parsedoc.io/v1/jobs/<job_id> \
-H "Authorization: Bearer <api_key>"
# -> { "job_id", "status", "pages", "cost_usd", "output", "error_code" }Check usage
Read your current month page count, remaining free pages and remaining prepaid credits.
curl https://parsedoc.io/v1/usage \
-H "Authorization: Bearer <api_key>"
# -> { "month_pages", "month_cost_usd", "free_pages_remaining", "credits_remaining", "plan" }Buy credits
Buy a prepaid credit pack (starter, standard or pro) in EUR. The call returns a hosted checkout_url; credits are added to your balance once the payment is confirmed.
curl -X POST https://parsedoc.io/v1/credits/purchase \
-H "Authorization: Bearer <api_key>" \
-H "Content-Type: application/json" \
-d '{"pack_id": "standard"}'
# -> { "checkout_url", "pack_id", "credit_pages", "eur_amount" }Errors
Every error uses one shape: an error object with a code, a human message and a doc_url that points to the reference for that code. Handle the code, not the message.
{
"error": {
"code": "insufficient_credits",
"message": "The prepaid credit balance is exhausted.",
"doc_url": "https://parsedoc.io/errors#insufficient_credits"
}
}| Code | HTTP | Meaning |
|---|---|---|
| invalid_request | 400 | The request body or a parameter is invalid. |
| unauthorized | 401 | The API key is missing or invalid. |
| payment_required | 402 | Payment is required (x402 rail): pay the challenge and retry. |
| insufficient_credits | 402 | The prepaid credit balance is exhausted; buy a pack. |
| not_found | 404 | The job or resource does not exist, or is not yours. |
| rate_limited | 429 | Rate limit exceeded; retry after the Retry-After delay. |
| enrich_failed | 502 | AI enrichment upstream failed; nothing was billed. Retry. |
Machine discovery
The full contract is machine-readable. Point an agent at the OpenAPI spec or the agent summary.
MCP server
ParseDoc ships a Model Context Protocol server over Streamable HTTP at /api/mcp. Authenticate with the same API key as an Authorization Bearer header.
Tools: parse_document (url or base64), extract_invoice (url or base64) and get_job_status (job_id).
{
"mcpServers": {
"parsedoc": {
"url": "https://parsedoc.io/api/mcp",
"headers": { "Authorization": "Bearer <api_key>" }
}
}
}