API and MCP connection
Audit and convert PDFs into an accessible format (WCAG 2.1/2.2, PDF/UA ISO 14289 and the EAA, Directive (EU) 2019/882) from your own tools. For registered customers.
Connecting an AI assistant? The MCP connection has its own documentation.
How it works
Processing a PDF can take from seconds to several minutes: conformance validation, conversion, structure tagging and image descriptions. That is why the API is asynchronous: you never wait with the connection open.
- You upload the PDF and pick the mode:
auditar(report, free) orconvertir(produces the accessible PDF/A, uses quota). - The response is immediate (
202 Accepted) and carries the documentid. The job is queued and the server processes it in the background. - You check the status with that id as often as you like (or, over MCP, wait with
wait_for_document). - Once the status is
done(done), request the report and/or download the PDF/A.
The id has the form YYYYMMDD-HHMMSS-xxxxxx and is the same identifier you see in your customer area.
Authentication
Plan requirement: the API and MCP are included from the Business plan upwards. On a lower plan you cannot create credentials and calls return 403 plan_required. See plans.
Every call (except /api/v1/ping) needs an API key created in My account → API credentials. The key identifies your account: the documents you create are yours and use your plan.
Authorization: Bearer pdfa_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
If your environment cannot send the Authorization header, use X-Api-Key: pdfa_…. The ?api_key= parameter also works, but is not recommended (it ends up in server logs).
- The key is shown only once, when you create it: store it like a password.
- Use one key per integration and revoke the ones you no longer use; revocation is immediate.
- There is no session and no cookies: every request stands alone.
- Use HTTPS in production so the key never travels in the clear.
REST API
https://pdfaccesible.com/api/v1application/pdf)| Method | Path | Description | Key |
|---|---|---|---|
| GET | /api/v1/ping |
Liveness check. No credential required. | no |
| GET | /api/v1/account |
Subscribed plan, limits and usage for the current month. | yes |
| GET | /api/v1/documents |
Lists your documents. Parameters: page, per_page, type, status. |
yes |
| POST | /api/v1/documents |
Uploads a PDF and queues it (type=audit|conversion). Returns the id used to check the status. Responds 202 Accepted. |
yes |
| GET | /api/v1/documents/{id} |
Processing status: queued, processing, done or error, with progress and score. |
yes |
| PUT | /api/v1/documents/{id} |
Updates the document metadata (filename). |
yes |
| DELETE | /api/v1/documents/{id} |
Deletes the whole document: original, PDF/A and report. Irreversible. | yes |
| GET | /api/v1/documents/{id}/report |
Full accessibility report (audit + conversion). Parameters: include_findings=0|1, max_findings. |
yes |
| GET | /api/v1/documents/{id}/audit |
Just the audit result of the original file. | yes |
| POST | /api/v1/documents/{id}/audit |
Audits the original again (for example after a change in criteria). 202 Accepted. |
yes |
| GET | /api/v1/documents/{id}/conversion |
State and result of the conversion: not_requested, processing or done. |
yes |
| POST | /api/v1/documents/{id}/conversion |
Queues a NEW conversion of the document. 409 if one is already running. |
yes |
| PUT | /api/v1/documents/{id}/conversion |
Ensures the conversion exists: idempotent, never duplicates work or quota. Use this one if your integration retries. | yes |
| DELETE | /api/v1/documents/{id}/conversion |
Deletes only the generated PDF/A; keeps the original and its audit. | yes |
| GET | /api/v1/documents/{id}/file/{original|pdfa} |
Downloads the chosen PDF (application/pdf). |
yes |
| POST | /mcp |
MCP server (JSON-RPC 2.0). It has its own documentation page. | yes |
1. Upload a document
Three ways to send the PDF: multipart with a file field (recommended for large files), JSON with file_base64 or file_url, or the raw PDF in the body.
# multipart (audit)
curl -X POST https://pdfaccesible.com/api/v1/documents \
-H "Authorization: Bearer YOUR_API_KEY" \
-F "file=@annual-report-2026.pdf" \
-F "type=audit"
# JSON with a URL (conversion to accessible PDF/A)
curl -X POST https://pdfaccesible.com/api/v1/documents \
-H "Authorization: Bearer YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{"type":"conversion","file_url":"https://example.com/annual-report-2026.pdf"}'
HTTP/1.1 202 Accepted
{
"id": "20260730-120501-a1b2c3",
"status": "queued",
"type": "conversion",
"filename": "annual-report-2026.pdf",
"size_bytes": 1048576,
"progress_pct": 0,
"step": "Queued",
"created_at": "2026-07-30T12:05:01+02:00",
"expires_at": "2026-08-29T12:05:01+02:00",
"score": null,
"error": null,
"links": { "self": "https://pdfaccesible.com/api/v1/documents/20260730-120501-a1b2c3", "web": "…" }
}
2. Check the status with the id
curl https://pdfaccesible.com/api/v1/documents/20260730-120501-a1b2c3 \
-H "Authorization: Bearer YOUR_API_KEY"
{
"id": "20260730-120501-a1b2c3",
"status": "done",
"progress_pct": 100,
"step": "Completed",
"score": 100,
"breakdown": { "overall": 100, "wcag": 100, "pdf_ua": 100, "eaa": 100 },
"converted": true,
"links": {
"self": "https://pdfaccesible.com/api/v1/documents/20260730-120501-a1b2c3",
"report": "https://pdfaccesible.com/api/v1/documents/20260730-120501-a1b2c3/report",
"original": "https://pdfaccesible.com/api/v1/documents/20260730-120501-a1b2c3/file/original",
"pdfa": "https://pdfaccesible.com/api/v1/documents/20260730-120501-a1b2c3/file/pdfa"
}
}
Poll every 5-10 s. An audit usually takes 10 to 60 s; an AI-assisted conversion, 1 to 5 min depending on size and number of images.
3. Report and download
# full report (overall score, per standard and findings)
curl "https://pdfaccesible.com/api/v1/documents/20260730-120501-a1b2c3/report?max_findings=10" \
-H "Authorization: Bearer YOUR_API_KEY"
# accessible PDF/A
curl -L -o accessible.pdf \
https://pdfaccesible.com/api/v1/documents/20260730-120501-a1b2c3/file/pdfa \
-H "Authorization: Bearer YOUR_API_KEY"
4. Convert a document you already audited
curl -X PUT https://pdfaccesible.com/api/v1/documents/20260730-120501-a1b2c3/conversion \
-H "Authorization: Bearer YOUR_API_KEY"
5. One verb, one action
Every route + verb combination is a different action. In particular: POST /documents/{id}/conversion queues a new conversion and fails with 409 if one is already running, whereas PUT on the same route is idempotent (if the PDF/A already exists, or is already being generated, it neither repeats the work nor spends quota again) — that is the one to use in integrations that retry. DELETE /documents/{id}/conversion removes only the generated PDF/A and keeps the original and its audit; DELETE /documents/{id} removes everything.
Report structure
The overall score is the average of the three accessibility dimensions. PDF/UA is checked by an automated conformance validator (authoritative); WCAG and EAA are evaluated from the document facts and the failed PDF/UA rules.
{
"id": "20260730-120501-a1b2c3",
"filename": "annual-report-2026.pdf",
"status": "done",
"audit": {
"score": 42,
"breakdown": { "overall": 42, "wcag": 20, "pdf_ua": 40, "eaa": 67 },
"pages": 24,
"pdf_version": "1.7",
"machine_validated": true,
"finding_counts": { "pass": 12, "warning": 3, "fail": 9, "info": 4, "na": 1 },
"standards": {
"wcag": { "standard": "WCAG", "verdict": "fail", "score": 20, "findings_total": 6,
"findings": [ { "severity": "fail", "title": "…", "detail": "…", "reference": "WCAG 1.3.1" } ] },
"pdf_ua": { "standard": "PDF/UA", "verdict": "fail", "score": 40, "findings_total": 3, "findings": [] },
"eaa": { "standard": "EAA", "verdict": "warning", "score": 67, "findings_total": 5, "findings": [] }
}
},
"conversion": {
"created_at": "2026-07-30T12:09:44+02:00",
"pdfa_part": 2,
"tagged": true,
"result": { "score": 100, "breakdown": { "overall": 100, "wcag": 100, "pdf_ua": 100, "eaa": 100 } }
},
"score_improvement": { "before": 42, "after": 100, "delta": 58 }
}
Document statuses
| Status | Meaning |
|---|---|
queued | Accepted and waiting for the queue worker. |
processing | Under way. progress_pct and step show which phase it is in. |
done | Finished: the report is ready and, if it was a conversion, the PDF/A can be downloaded. |
error | It failed; the error field explains why. It is retried automatically up to 3 times before giving up. |
Limits and quotas
| Limit | Value |
|---|---|
| Requests per minute per key | 120 |
| Documents per hour per key | 60 |
| Maximum upload size (server) | 128 MB |
Maximum size in file_base64 | 24 MB · above that, use multipart or file_url |
| Free audit | up to 100 MB per document |
| Conversions | according to your plan (size per document and number per month) |
Monthly usage is counted when each conversion is created and is recorded permanently: deleting a document does not give quota back. Going over the rate limit returns 429 with a Retry-After header. If your plan does not cover a conversion you get 402 quota_exceeded: auditing is still free. Check your usage any time with GET /api/v1/account or the get_account tool.
Errors
{ "error": { "code": "quota_exceeded", "message": "You have used your 3 free conversions…" } }
| Code | HTTP | When |
|---|---|---|
unauthorized | 401 | The key is missing, invalid, revoked or expired. |
quota_exceeded | 402 | Your plan does not cover this conversion (size per document, monthly limit or free conversions used up). |
email_not_verified | 403 | The account has not verified its email address. |
plan_required | 403 | The subscribed plan does not include API or MCP access (included from the Business plan upwards). The required_plan field in the response tells you which plan is needed. |
not_found | 404 | The id does not exist in your account (or the route does not exist). |
method_not_allowed | 405 | That verb is not allowed on that route; the Allow header lists the ones that are. |
already_running | 409 | A job of that kind is already running for this document (use PUT for an idempotent call). |
report_not_ready | 409 | The document has not finished processing yet. |
invalid_request | 422 | Wrong parameters: the file is not a PDF, the content is missing, unknown type… |
too_many_requests | 429 | Rate limit exceeded. Retry according to Retry-After. |
internal_error | 500 | Unexpected server error. If it persists, get in touch. |
api_disabled | 503 | The API is temporarily disabled. |
Retention and privacy
- Your PDFs are never public: they are only served to authenticated requests, and only to the owning account.
- Documents are kept for 30 days and then deleted automatically (original, PDF/A and report). Every creation and every deletion leaves a dated record (without the document content), which is what backs your plan usage count and your history. You can delete them sooner with
DELETE /api/v1/documents/{id}ordelete_document. - Conversion automatically generates the metadata and the image descriptions; the content of your documents is not used to train models.
- See the privacy notice and the terms.