API Reference
Interactive Swagger documentation with all endpoints, request/response schemas, and authentication details.
Authentication
Learn how to authenticate with JWT tokens or API keys. Includes code examples for cURL, Node.js, and Python.
Webhooks
Set up webhooks to receive real-time notifications when documents are processed, failed, or need review.
Quick Start
Upload and remediate a PDF in three API calls.
1. Get an API key
Go to Settings → API Keys and create a new key with upload and documents:read scopes.
2. Initialize an upload
curl -X POST https://api.trueaccessibility.com/api/upload/init \
-H "X-API-Key: ta_sk_your_api_key_here" \
-H "Content-Type: application/json" \
-d '{
"filename": "report.pdf",
"fileSize": 1024000,
"contentType": "application/pdf"
}'This returns a uploadUrl (presigned S3 URL) and documentId. Upload your file to the presigned URL with a PUT request.
3. Complete the upload
curl -X POST https://api.trueaccessibility.com/api/upload/complete \
-H "X-API-Key: ta_sk_your_api_key_here" \
-H "Content-Type: application/json" \
-d '{"documentId": "DOCUMENT_ID"}'Processing starts automatically. Poll GET /api/documents/DOCUMENT_ID to check status, or set up a webhook.
4. Download the accessible PDF
curl https://api.trueaccessibility.com/api/documents/DOCUMENT_ID/download \
-H "X-API-Key: ta_sk_your_api_key_here"Returns a presigned URL to download the WCAG 2.2 / PDF/UA-1 compliant PDF.
Authentication
TrueAccessibility supports two authentication methods:
API Keys (recommended for integrations)
Create API keys in Settings with specific scopes. Pass them in the X-API-Key header:
X-API-Key: ta_sk_your_api_key_hereJavaScript Example
const response = await fetch('https://api.trueaccessibility.com/api/documents', {
headers: {
'X-API-Key': 'ta_sk_your_api_key_here',
'Content-Type': 'application/json',
},
});
const data = await response.json();Available Scopes
documents:read-- Read document data and download filesdocuments:write-- Create and modify documentsdocuments:remediate-- Trigger remediation processingupload-- Upload new PDF filesprojects:read-- Read project dataprojects:write-- Create and modify projectsanalytics:read-- Access analytics and reportswebhooks:manage-- Create, update, and delete webhooks
JWT Tokens (for browser sessions)
Obtained via POST /api/auth/login. Tokens expire after 24 hours. Used automatically by the web dashboard.
API Endpoints
All endpoints are prefixed with https://api.trueaccessibility.com/api
/api/v1/documents/uploadUpload a PDF
Initialize a document upload. Returns a presigned S3 URL for direct upload and a documentId.
Required scope: upload
/api/v1/documents/:idGet document status
Retrieve the current status, metadata, and progress of a document.
Required scope: documents:read
/api/v1/documents/:id/downloadDownload remediated PDF
Get a presigned download URL for the WCAG 2.2 / PDF/UA-1 compliant output.
Required scope: documents:read
/api/v1/documents/:id/remediateTrigger remediation
Re-trigger remediation on a failed or completed document with new settings.
Required scope: documents:remediate
/api/v1/documentsList documents
List all documents in your organization with pagination and status filtering.
Required scope: documents:read
/api/v1/webhooksRegister webhook
Register a webhook endpoint to receive real-time event notifications.
Required scope: webhooks:manage
Code Examples
cURL -- Upload and remediate a document
# 1. Initialize upload
INIT=$(curl -s -X POST https://api.trueaccessibility.com/api/upload/init \
-H "X-API-Key: $API_KEY" \
-H "Content-Type: application/json" \
-d '{"filename":"report.pdf","fileSize":'$(stat -f%z report.pdf)',"contentType":"application/pdf"}')
UPLOAD_URL=$(echo $INIT | jq -r '.uploadUrl')
DOC_ID=$(echo $INIT | jq -r '.documentId')
# 2. Upload the file to S3
curl -X PUT "$UPLOAD_URL" \
-H "Content-Type: application/pdf" \
--data-binary @report.pdf
# 3. Signal upload complete (triggers processing)
curl -X POST https://api.trueaccessibility.com/api/upload/complete \
-H "X-API-Key: $API_KEY" \
-H "Content-Type: application/json" \
-d '{"documentId":"'$DOC_ID'"}'
# 4. Poll status until completed
curl -s https://api.trueaccessibility.com/api/documents/$DOC_ID \
-H "X-API-Key: $API_KEY" | jq '.status'
# 5. Download the remediated file
curl -s https://api.trueaccessibility.com/api/documents/$DOC_ID/download \
-H "X-API-Key: $API_KEY" | jq -r '.url'JavaScript / Node.js
const API_KEY = 'ta_sk_your_api_key_here';
const BASE_URL = 'https://api.trueaccessibility.com/api';
const headers = {
'X-API-Key': API_KEY,
'Content-Type': 'application/json',
};
// 1. Initialize upload
const initRes = await fetch(`${BASE_URL}/upload/init`, {
method: 'POST',
headers,
body: JSON.stringify({
filename: 'report.pdf',
fileSize: fileBuffer.byteLength,
contentType: 'application/pdf',
}),
});
const { documentId, uploadUrl } = await initRes.json();
// 2. Upload file to presigned URL
await fetch(uploadUrl, {
method: 'PUT',
headers: { 'Content-Type': 'application/pdf' },
body: fileBuffer,
});
// 3. Signal upload complete
await fetch(`${BASE_URL}/upload/complete`, {
method: 'POST',
headers,
body: JSON.stringify({ documentId }),
});
// 4. Poll until complete
let status = 'detecting';
while (!['completed', 'failed'].includes(status)) {
await new Promise(r => setTimeout(r, 5000));
const res = await fetch(`${BASE_URL}/documents/${documentId}`, { headers });
const doc = await res.json();
status = doc.status;
console.log(`Status: ${status} (${doc.progress || 0}%)`);
}
// 5. Download result
const dlRes = await fetch(`${BASE_URL}/documents/${documentId}/download`, { headers });
const { url } = await dlRes.json();
console.log('Download URL:', url);Register a webhook
curl -X POST https://api.trueaccessibility.com/api/webhooks \
-H "X-API-Key: $API_KEY" \
-H "Content-Type: application/json" \
-d '{
"url": "https://your-server.com/webhook",
"events": ["document.completed", "document.failed"]
}'Rate Limits
Rate limits are applied per API key and vary by subscription tier. Exceeding the rate limit returns HTTP 429.
| Tier | Rate Limit | Concurrent Jobs | Processing Priority |
|---|---|---|---|
| Free Trial | 100/hour | 3 | Basic |
| Starter | 1,000/hour | 10 | Standard |
| Professional | 5,000/hour | 20 | High |
| Enterprise | Unlimited | 50 | Highest |
Webhooks
Receive real-time HTTP POST notifications when events occur.
Available events
document.uploaded-- A new document has been uploadeddocument.processing-- Document processing has starteddocument.completed-- Processing finished successfullydocument.failed-- Processing failed with an errorreview.needed-- Document requires manual reviewreview.submitted-- An OCR review task was submitted
Payload format
{
"event": "document.completed",
"data": {
"documentId": "550e8400-e29b-41d4-a716-446655440000",
"orgId": "org_abc123",
"status": "completed",
"filename": "report.pdf",
"pageCount": 42,
"downloadUrl": "https://..."
},
"timestamp": "2026-04-10T12:00:00.000Z",
"webhookId": "wh_xyz789"
}Signature verification
Each webhook delivery includes an X-Webhook-Signature header containing an HMAC-SHA256 signature of the payload using your webhook secret. Verify this to ensure the payload is authentic.
const crypto = require('crypto');
function verifyWebhook(payload, signature, secret) {
const expected = crypto
.createHmac('sha256', secret)
.update(JSON.stringify(payload))
.digest('hex');
return crypto.timingSafeEqual(
Buffer.from(signature),
Buffer.from(expected)
);
}
// In your Express handler:
app.post('/webhook', (req, res) => {
const signature = req.headers['x-webhook-signature'];
if (!verifyWebhook(req.body, signature, WEBHOOK_SECRET)) {
return res.status(401).send('Invalid signature');
}
const { event, data } = req.body;
switch (event) {
case 'document.completed':
console.log('Document ready:', data.documentId);
break;
case 'document.failed':
console.error('Processing failed:', data.documentId);
break;
}
res.status(200).send('OK');
});Retry policy
Failed webhook deliveries (non-2xx response or timeout) are retried up to 3 times with exponential backoff: 2 seconds, then 4 seconds. Delivery attempts and responses are logged and visible in the webhook settings panel.
Need help? Contact support or visit the interactive API reference.