StubParse

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 PDF
  • image: { "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" } }.

401invalid_keyMissing, malformed, or revoked key
403upgrade_requiredThe account isn't on Business
413too_largeOver the size limit
415unsupported_typeFile type not supported
422not_a_paystubThe document doesn't look like a paystub
429rate_limited · fair_useOver 60 requests a minute, or the monthly fair-use limit
502 / 503extraction_failed · busyRetry with backoff

Limits

  • 60 requests per minute per account. A Retry-After header 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.