Conventions

Behaviors that hold across the entire API: the response envelope, error shape, rate limits, and pagination. Everything here applies to every endpoint in the reference.

Success envelope

Every 2xx response wraps its payload in the same three-field envelope. The interesting part is always data:

{
    "success": true,
    "data": {
        "id": "9b2f8c34-5e1a-4f0b-8c5d-2a7e9d1c6b43",
        "originalFileName": "consulting-agreement.pdf",
        "pageCount": 4
    },
    "timestamp": "2026-06-11T09:31:02.143Z"
}

success is always true on the success path, and timestamp is the server time of the response. Endpoints that return nothing (e.g. DELETE) answer 204 No Content with an empty body.

Errors

Errors are not wrapped in the envelope — they are flat objects:

{
    "statusCode": 402,
    "timestamp": "2026-06-11T09:32:10.512Z",
    "path": "/api/v1/signing-processes",
    "method": "POST",
    "message": "Plan limit reached for signingProcessesPerMonth (limit 5, current 5). Upgrade or add a seat to continue.",
    "code": "QUOTA_EXCEEDED"
}
  • statusCode, timestamp, path, method, and message are always present.
  • message is a single string for application errors, and an array of strings for validation failures (400) — one entry per violated rule.
  • code is a stable, machine-readable identifier and is present only on application errors. Validation 400s and generic authentication/authorization errors have no code.
  • Some framework-emitted errors add an error field (the HTTP error name, e.g. "Bad Request"), and some errors add a structured details object.

Match on code, not on message. Messages are human-readable and may be reworded at any time; codes are contractual. The codes you are most likely to encounter:

CodeStatusMeaning
QUOTA_EXCEEDED402A plan quota (storage, monthly signing volume, PDF size, templates) would be exceeded.
BILLING_ORG_READ_ONLY402The organization is locked to read-only because of an unpaid invoice.
SMS_RETRY_LIMIT429A signer requested too many SMS one-time codes for one signing.

Rate limits and quotas

A burst request throttle can answer 429 (no code): 100 requests per 60 seconds per client IP. Throttled responses carry the standard headers — Retry-After plus the X-RateLimit-* family — so back off for the indicated duration and retry. PDF upload endpoints (initiate and commit) additionally enforce 30 requests per 60 seconds per organization.

Pagination

Paginated collections — GET /templates and GET /signing-processes — use page-number pagination via query parameters:

ParameterDefaultNotes
page11-based page index.
pageSize20Maximum 100; larger values are rejected as a validation error.

The paginated payload lives inside the usual data envelope:

{
    "success": true,
    "data": {
        "items": [
            {
                "id": "5b8e2f01-9c4d-4a6e-b7f3-1d2c8a9e0f45",
                "name": "Consulting agreement",
                "status": "PUBLISHED"
            }
        ],
        "total": 41,
        "page": 1,
        "pageSize": 20
    },
    "timestamp": "2026-06-11T09:30:12.481Z"
}

total is the number of matching items across all pages, so the last page is ceil(total / pageSize).

Filters combine with AND — e.g. GET /templates?status=PUBLISHED&categoryId=… returns templates that match both. Array-valued parameters such as tagIds accept both forms interchangeably:

# repeated key
curl "https://api.smartdocs.de/api/v1/templates?tagIds=<uuid-1>&tagIds=<uuid-2>" \
  -H "X-API-Key: $SMARTDOCS_API_KEY"

# comma-separated
curl "https://api.smartdocs.de/api/v1/templates?tagIds=<uuid-1>,<uuid-2>" \
  -H "X-API-Key: $SMARTDOCS_API_KEY"

Within tagIds itself a template matches if it carries at least one of the given tags; that tag match then ANDs with the other filters.