SimplyFill.

API errors

HTTP status codes, error codes, and recommended client behaviour.

Errors

All SimplyFill API errors are JSON. Every error body shares the same minimum shape:

{
  "error": "machine_readable_code",
  "message": "Human-readable explanation."
}

Some endpoints add per-error fields (a limit for quota errors, retry_after for rate-limit errors, etc.). Those are documented on the endpoint that emits them; what follows is the cross-cutting summary.

Status codes

StatusMeaningCommon causes
400 Bad RequestValidation failedMissing required field, wrong type, unknown alias in data
401 UnauthorizedAuthentication failedMissing or invalid Bearer token
402 Payment RequiredQuota exceeded (FREE tier)Monthly PDF or AI quota at 100% on FREE
403 ForbiddenPermission denied or scope insufficientNot the resource owner; key lacks required scope; tier feature limit
404 Not FoundResource does not existWrong ID, or you don't have access
409 ConflictState conflictPromoting an already-published version; invalid plan transition
410 GoneResource expiredDownload URL older than 24 hours
422 Unprocessable EntitySchema understood but semantically invalidMapping references a deleted template version
429 Too Many RequestsRate limit exceededHourly cap reached; honor Retry-After
500 Internal Server ErrorServer-side faultRare; auto-reported to on-call. Retry with exponential backoff
503 Service UnavailableMaintenance / dependency outageStatus page will reflect; retry once Retry-After elapses

Error codes

Stable identifiers in the error field. Match on these in client code; the message is for humans and may change wording without notice.

Authentication

CodeStatusWhen
missing_authorization401No Authorization header
invalid_api_key401Key revoked, malformed, or unknown
scope_required403Key lacks the scope the endpoint requires

Resources

CodeStatusWhen
template_not_found404Template ID unknown or inaccessible
mapping_not_found404Mapping ID unknown or inaccessible
task_not_found404Async task ID unknown
file_not_found404Download file ID unknown
file_expired410Download URL older than 24 hours
envelope_not_found404Envelope ID unknown

Validation

CodeStatusWhen
validation_error400Body failed Pydantic validation. Fields listed under details.
invalid_file_type400Upload not a .pdf
file_too_large400Upload above 25 MB
invalid_csv400Bulk envelope CSV missing header or has mismatched columns

Tier / quota / rate

CodeStatusWhen
quota_exceeded402Monthly PDF quota at 100% on FREE
ai_quota_exceeded402Monthly AI quota at 100% on FREE or PRO
feature_limit_reached403Per-tier template or API-key cap
rate_limit_exceeded429Hourly cap exceeded; Retry-After set

Environment / versioning

CodeStatusWhen
template_not_deployed403Resolved version not published to the request's environment
invalid_plan_transition409Cannot downgrade mid-period for current plan

Worked examples

Validation error

HTTP/1.1 400 Bad Request
Content-Type: application/json

{
  "error": "validation_error",
  "message": "Request body failed validation.",
  "details": [
    { "field": "data.amount", "issue": "field required" }
  ]
}

Rate limit

HTTP/1.1 429 Too Many Requests
Retry-After: 247
Content-Type: application/json

{
  "error": "rate_limit_exceeded",
  "message": "Hourly rate limit reached. Try again in 247 seconds.",
  "retry_after": 247
}

Quota exceeded (FREE)

HTTP/1.1 402 Payment Required
Content-Type: application/json

{
  "error": "quota_exceeded",
  "message": "Monthly PDF quota exceeded for FREE tier.",
  "tier": "FREE",
  "limit": 100,
  "used": 100,
  "upgrade_url": "https://simplyfill.app/billing",
  "resets_at": "2026-06-01T00:00:00Z"
}

Client-side handling

A reasonable retry policy for production code:

StatusAction
4xx (except 429)Do not retry. Fix the request.
429Wait Retry-After seconds, then retry.
5xxExponential backoff with jitter, capped at ~5 attempts.
402 / 403 (tier)Surface upgrade prompt to the user. Do not retry until plan changes.

Implement this retry policy in whichever HTTP client you use against the API.

On this page