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.

  1. You upload the PDF and pick the mode: auditar (report, free) or convertir (produces the accessible PDF/A, uses quota).
  2. The response is immediate (202 Accepted) and carries the document id. The job is queued and the server processes it in the background.
  3. You check the status with that id as often as you like (or, over MCP, wait with wait_for_document).
  4. 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).

REST API

Basehttps://pdfaccesible.com/api/v1
FormatJSON UTF-8 (downloads return application/pdf)
MethodPathDescriptionKey
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

StatusMeaning
queuedAccepted and waiting for the queue worker.
processingUnder way. progress_pct and step show which phase it is in.
doneFinished: the report is ready and, if it was a conversion, the PDF/A can be downloaded.
errorIt failed; the error field explains why. It is retried automatically up to 3 times before giving up.

Limits and quotas

LimitValue
Requests per minute per key120
Documents per hour per key60
Maximum upload size (server)128 MB
Maximum size in file_base6424 MB · above that, use multipart or file_url
Free auditup to 100 MB per document
Conversionsaccording 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…" } }
CodeHTTPWhen
unauthorized401The key is missing, invalid, revoked or expired.
quota_exceeded402Your plan does not cover this conversion (size per document, monthly limit or free conversions used up).
email_not_verified403The account has not verified its email address.
plan_required403The 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_found404The id does not exist in your account (or the route does not exist).
method_not_allowed405That verb is not allowed on that route; the Allow header lists the ones that are.
already_running409A job of that kind is already running for this document (use PUT for an idempotent call).
report_not_ready409The document has not finished processing yet.
invalid_request422Wrong parameters: the file is not a PDF, the content is missing, unknown type…
too_many_requests429Rate limit exceeded. Retry according to Retry-After.
internal_error500Unexpected server error. If it persists, get in touch.
api_disabled503The API is temporarily disabled.

Retention and privacy