The Remediate API
Anything you can do in the app, you can do over HTTPS. Send a PDF and get back the report, or the fixed PDF itself.
curl https://api.remediate.now/v1/orgs/$ORG/remediate \
-H "Authorization: Bearer $REMEDIATE_KEY" \
-H "Content-Type: application/pdf" \
--data-binary @report.pdf \
-o report-accessible.pdf
Add ?format=json for the report, with the PDF as pdf_base64.
Start in three steps
-
Get a key
In the app, open API keys and create one. Keys start rmd_live_ and act only in their own org. Your org id is on the same page.
export REMEDIATE_KEY=rmd_live_… export ORG=org_… -
Check a PDF
Send the file. You get one issue for each rule it fails, explained in a sentence, with how to fix it by hand. Checking is part of your plan.
profile is auto, ua1 or ua2. Auto checks the version the file says it follows.
curl "https://api.remediate.now/v1/orgs/$ORG/validate?profile=ua1" \ -H "Authorization: Bearer $REMEDIATE_KEY" \ -H "Content-Type: application/pdf" \ --data-binary @report.pdf{ "profile": "PDF/UA-1", "compliant": false, "issues": [{ "rule": "7.3-t01", "title": "Images have no description", "count": 6, "wcag": "WCAG 1.1.1", "how_to_fix": "In Acrobat Pro, open Fix reading order, …" }, …] } -
Fix it
Send it to /remediate. With format=json you get the report and the PDF together. Without it, you get the PDF. We don't keep a copy.
curl "https://api.remediate.now/v1/orgs/$ORG/remediate?format=json" \ -H "Authorization: Bearer $REMEDIATE_KEY" \ -H "Content-Type: application/pdf" \ --data-binary @report.pdf{ "compliant": true, "issues_before": [ … ], "issues_after": [], "changes": [ { "area": "images", "message": "…", "by": "claude" }, { "area": "structure", "message": "…", "by": "engine" } ], "pages": 24, "pdf_base64": "JVBERi0x…" }
Endpoints
Everything you do with PDFs is under /v1/orgs/{org}. Send a PDF as the body, or as a multipart field named file.
| Method | Path | What it does |
|---|---|---|
| POST | / | Check a PDF. ?profile=auto, ua1 or ua2. Part of your plan. |
| POST | / | Fix a PDF and get it back right away. ?format=pdf or json. Not stored. |
| POST | / | Upload a PDF. We check it and keep it for 30 days. 201. |
| GET | / | List documents. ?limit up to 200; pass next as ?before for more. |
| GET | / | One document: its check and, once fixed, its report. |
| POST | / | Fix a kept document. 202, then poll; or ?wait=true to answer when done. |
| PATCH | / | Correct image descriptions, then fix it again. 202, or ?wait=true. No more pages that month. |
| GET | / | One image from the document, cropped from its page, as a PNG. |
| GET | / | The file you uploaded. |
| GET | / | The accessible PDF. 409 not_remediated until it's fixed. |
| DELETE | / | Delete it now, before the 30 days are up. 204. |
| GET | / | Your plan and this period's usage. |
| GET | / | The plans. |
| GET | / | Who is calling. |
{org} is your org id, like org_01k7…
Keep a file and its report
Upload it to /documents and we'll check it and keep it for 30 days with its report. Fixing runs in the background, so poll the document until its status is remediated or failed, or add ?wait=true.
Stored documents also show up in the app for everyone on your team.
# Upload: checked, then kept for 30 days
curl https://api.remediate.now/v1/orgs/$ORG/documents \
-H "Authorization: Bearer $REMEDIATE_KEY" \
-F file=@report.pdf
# 201 {"id": "…", "status": "validated", "issues_found": 6, …}
# Fix it, and answer when it's done
curl -X POST \
"https://api.remediate.now/v1/orgs/$ORG/documents/$DOC/remediate?wait=true" \
-H "Authorization: Bearer $REMEDIATE_KEY"
# 200 {"status": "remediated", "issues_remaining": 0, …}
# Download the accessible PDF
curl https://api.remediate.now/v1/orgs/$ORG/documents/$DOC/remediated \
-H "Authorization: Bearer $REMEDIATE_KEY" \
-o report-accessible.pdf
Keys
Send an org API key as Authorization: Bearer rmd_live_…. A key acts only in its own org. Make and revoke keys on the API keys page.
Billing
Every call needs a plan. When you fix a file, its pages count once a month, however many times you run it. Checks don't use pages, but they have a monthly safety limit, and failed checks don't count toward it.
Errors
Every error has the same shape, and the codes don't change.
{"error": {"code": "subscription_required", "message": "…"}}| Status | Code | What it means |
|---|---|---|
| 400 | not_pdf | The file isn't a PDF. |
| 401 | missing_key | No key was sent. |
| 401 | invalid_key | The key is wrong or revoked. |
| 402 | subscription_required | The org needs a plan. |
| 404 | document_not_found | No such document in this org, or it was deleted. |
| 409 | already_remediating | It's being fixed now. Check again in a moment. |
| 409 | not_remediated | Fix it before you download the accessible PDF. |
| 413 | too_many_pages | More than 2,000 pages. |
| 422 | unreadable_pdf | We couldn't read the file as a PDF. |
| 429 | quota_exceeded | This month's checking limit is used up. Ask us to raise it. |
The OpenAPI spec lists every code for every route.