Skip to main content

Documentation Index

Fetch the complete documentation index at: https://docs.spitshake.io/llms.txt

Use this file to discover all available pages before exploring further.

Error Response Format

When a request fails, the API returns a JSON object with an error key. The value is either a single string or an array of strings describing what went wrong. Single error:
{
  "error": "Template not found"
}
Multiple errors (typically validation failures):
{
  "error": [
    "Email can't be blank",
    "Role must match a template submitter",
    "Name is too long (maximum is 255 characters)"
  ]
}

HTTP Status Codes

Status CodeMeaningDescription
400Bad RequestThe request body is malformed, a required parameter is missing, or a parameter has an invalid type. Check the error message for specifics.
401UnauthorizedThe X-Auth-Token header is missing, empty, or contains an invalid API token.
403ForbiddenThe API token is valid but lacks permission for this action. This can occur when a token’s scopes do not include the requested resource, when your plan does not support the feature, or when IP allowlisting blocks the request.
404Not FoundThe requested resource does not exist or is not accessible to your account.
422Unprocessable EntityThe request was well-formed but contained semantic errors. Typically returned for validation failures such as invalid field values, duplicate entries, or constraint violations.
429Too Many RequestsYou have exceeded the rate limit. Wait and retry after the interval specified in the Retry-After header.
500Internal Server ErrorAn unexpected error occurred on the DocuTrust server. If this persists, contact support with the X-Request-Id header value from the response.

Error Examples by Status Code

400 Bad Request

{
  "error": "Invalid JSON in request body"
}

401 Unauthorized

{
  "error": "Unauthorized: invalid or missing API token"
}

403 Forbidden

Standard permission error:
{
  "error": "Forbidden: token scope 'read_submissions' does not permit this action"
}
Plan limit reached (includes an upgrade URL):
{
  "error": "Plan limit reached: your current plan allows 50 submissions per month",
  "upgrade_url": "https://your-instance.spitshake.io/settings/billing/upgrade"
}

404 Not Found

{
  "error": "Template not found"
}

422 Unprocessable Entity

{
  "error": [
    "Email can't be blank",
    "Role must match a template submitter"
  ]
}

429 Too Many Requests

{
  "error": "Rate limit exceeded. Retry after 32 seconds."
}
The response also includes the following headers:
HeaderDescriptionExample
Retry-AfterSeconds to wait before making another request.32
X-RateLimit-LimitMaximum requests allowed per window.120
X-RateLimit-RemainingRequests remaining in the current window.0
X-RateLimit-ResetUnix timestamp when the rate limit window resets.1712674352

500 Internal Server Error

{
  "error": "Internal server error. Reference ID: req_8f3a2b1c-d4e5-6789-abcd-ef0123456789"
}

Rate Limits

The DocuTrust API enforces rate limits to ensure fair usage and platform stability.
LimitValue
Requests per minute120 per API token
Rate limit window60 seconds (rolling)
ScopePer API token (not per IP or account)
When you exceed the limit, the API returns a 429 Too Many Requests response. The Retry-After header tells you how many seconds to wait before retrying.

Rate Limit Headers

Every API response includes rate limit headers so you can track your usage proactively:
HeaderDescription
X-RateLimit-LimitThe maximum number of requests permitted per 60-second window.
X-RateLimit-RemainingThe number of requests remaining in the current window.
X-RateLimit-ResetThe Unix epoch timestamp when the current window resets.

Plan Limits

Some API actions are restricted by your account’s subscription plan. When you exceed a plan limit, the API returns a 403 Forbidden response that includes an upgrade_url field pointing to your billing page:
{
  "error": "Plan limit reached: your current plan allows 50 submissions per month",
  "upgrade_url": "https://your-instance.spitshake.io/settings/billing/upgrade"
}
Common plan-limited resources include:
  • Monthly submission count
  • Number of templates
  • Number of API tokens
  • Number of team members
  • File storage capacity

Best Practices

Exponential Backoff

When you receive a 429 or 5xx response, implement exponential backoff with jitter to avoid thundering herd problems:
async function requestWithBackoff(url, options, maxRetries = 5) {
  for (let attempt = 0; attempt <= maxRetries; attempt++) {
    const response = await fetch(url, options);

    if (response.ok) {
      return response.json();
    }

    if (response.status === 429 || response.status >= 500) {
      if (attempt === maxRetries) {
        throw new Error(`Request failed after ${maxRetries + 1} attempts: ${response.status}`);
      }

      const retryAfter = response.headers.get('Retry-After');
      const baseDelay = retryAfter
        ? parseInt(retryAfter, 10) * 1000
        : Math.pow(2, attempt) * 1000;
      const jitter = Math.random() * 1000;
      const delay = baseDelay + jitter;

      await new Promise((resolve) => setTimeout(resolve, delay));
      continue;
    }

    const body = await response.json();
    throw new Error(`API error ${response.status}: ${JSON.stringify(body)}`);
  }
}

Idempotency

Create and send operations accept an Idempotency-Key header to prevent duplicate requests on retry.
StatusMeaning
Original responseA repeated request with the same key and body replays the stored response (with Idempotency-Replayed: true header)
422The same key was used with a different request body
409A request with this key is still being processed
Keys expire after 24 hours. Keys are bound to the calling token — a different token cannot replay another’s cached response.
curl -X POST https://your-instance.com/api/submissions \
  -H "X-Auth-Token: YOUR_TOKEN" \
  -H "Idempotency-Key: unique-request-id-123" \
  -H "Content-Type: application/json" \
  -d '{"template_id": 1, "submitters": [...]}'

Error Handling Checklist

Do not assume every response is successful. Check the status code before parsing the response body as a success payload.
The error field may be a string or an array of strings. Handle both cases in your error handling logic.
Every API response includes an X-Request-Id header. Log this value so you can reference it when contacting support about 500 errors.
When rate-limited, always wait at least as long as the Retry-After header specifies. Ignoring this header will extend your rate limit window.
These errors indicate a problem with the request itself. Retrying the same request will produce the same error. Fix the request parameters before retrying.
When you receive a 403 with an upgrade_url, display a clear message to the user explaining the plan limit and providing a link to upgrade.