API reference
One endpoint turns a paystub into structured JSON, with the math checks and integrity signals attached. Available on the Business plan.
Authentication
Create a key in Account → API keys. It's shown once, so store it somewhere safe. Send it as a bearer token:
Authorization: Bearer sp_live_...Keep keys on your server. Anyone with a key can parse documents on your account.
Parse a document
POST https://stubparse.com//api/v1/parse
Upload a file as multipart form data:
curl https://stubparse.com//api/v1/parse \
-H "Authorization: Bearer $STUBPARSE_KEY" \
-F "file=@paystub.pdf"Or send JSON with base64 content. Use exactly one of pdf, image, or text:
curl https://stubparse.com//api/v1/parse \
-H "Authorization: Bearer $STUBPARSE_KEY" \
-H "Content-Type: application/json" \
-d '{ "fileName": "maya-oct.pdf", "pdf": "'"$(base64 -i paystub.pdf)"'" }'pdf: base64-encoded PDFimage:{ "data": "<base64>", "mediaType": "image/png" | "image/jpeg" | "image/webp" }text: text you've already extracted
Keep files under 3 MB. Requests over the platform limit of 4.5 MB are rejected before they reach the API, with HTTP 413 and no JSON body. Each successful call uses one document from your plan; failed calls don't.
Response
{
"object": "paystub",
"file_name": "maya-oct.pdf",
"data": {
"name": "Maya Okafor",
"payPeriodStart": "2026-10-01",
"payPeriodEnd": "2026-10-15",
"checkDate": "2026-10-20",
"grossPay": "2319.40",
"netPay": "1614.78",
"fields": [
{ "section": "Earnings", "label": "Regular", "value": "1960.00", "ytd": "39200.00" },
{ "section": "Taxes", "label": "Federal Income Tax", "value": "231.94", "ytd": "4544.12" }
]
},
"checks": [
{ "id": "earnings", "status": "pass", "detail": "$2,319.40 = $2,319.40" },
{ "id": "net", "status": "pass", "detail": "$1,614.78 = $1,614.78" },
{ "id": "ytd", "status": "pass", "detail": "11 lines consistent" }
],
"integrity": { "risk": "low", "signals": [] },
"extracted": { "employee": { ... }, "employer": { ... }, "totals": { ... } },
"usage": { "documents_used": 128 }
}Amounts are strings without currency symbols or thousands separators. extracted holds the full structured extraction, including employer details.
Errors
Errors return a JSON body of the form { "error": { "code", "message" } }.
| 401 | invalid_key | Missing, malformed, or revoked key |
| 403 | upgrade_required | The account isn't on Business |
| 413 | too_large | Over the size limit |
| 415 | unsupported_type | File type not supported |
| 422 | not_a_paystub | The document doesn't look like a paystub |
| 429 | rate_limited · fair_use | Over 60 requests a minute, or the monthly fair-use limit |
| 502 / 503 | extraction_failed · busy | Retry with backoff |
Limits
- 60 requests per minute per account. A
Retry-Afterheader tells you when to try again. - Business includes up to 10,000 documents a month for normal use. Contact us for more.
- Documents sent to the API are processed and discarded. Nothing is stored.