jackdocs

Errors & Rate Limits

jack uses standard HTTP status codes. Every error response includes a human-readable detail field. Never show raw jack error messages to your end users — handle them in your backend.

Error response format

json
{ "detail": "documents list must not be empty" }

Status codes

StatusMeaningWhat to do
400Bad Request — malformed JSON or missing required fieldCheck your request body against the endpoint reference
401Unauthorized — missing or invalid API keyCheck your Authorization header
403Forbidden — API key has been revokedGenerate a new key from the dashboard
404Not Found — document or resource does not existCheck the ID — it may have been deleted
413Payload Too Large — file exceeds 100MBCompress or split the file before uploading
415Unsupported Media Type — file format not supportedUse .pdf, .docx, .txt, or .md
422Unprocessable Entity — field validation failedCheck field types and value ranges
429Too Many Requests — rate limit exceededWait 60 seconds, then retry
500Internal Server Error — something went wrong on our endRetry after 30 seconds. Contact support if it persists

Handling errors in Python

python
import httpx

try:
    response = httpx.post(
        "https://api.usejack.io/v1/query",
        headers={"Authorization": "Bearer jack_xxxxxxxx"},
        json={"question": "What is the refund policy?"},
        timeout=30
    )
    response.raise_for_status()
    return response.json()

except httpx.HTTPStatusError as e:
    status = e.response.status_code
    detail = e.response.json().get("detail", "Unknown error")

    if status == 401:
        raise Exception("Invalid API key")
    elif status == 429:
        retry_after = int(e.response.headers.get("Retry-After", 60))
        # wait and retry
    elif status >= 500:
        # retry with backoff
    else:
        raise Exception(f"jack API error {status}: {detail}")

Rate limits

jack enforces a sliding-window rate limit of 60 requests per minute per organisation across all endpoints. The limit resets every 60 seconds.

Batching is the most effective way to stay within limits. One POST /v1/ingest with 10 documents counts as 1 request, not 10.

429 response

http
HTTP/1.1 429 Too Many Requests
Retry-After: 60

{ "detail": "Rate limit exceeded" }

Retry with backoff

python
import time, httpx

def query_with_retry(question: str, api_key: str, max_retries: int = 3) -> dict:
    for attempt in range(max_retries):
        resp = httpx.post(
            "https://api.usejack.io/v1/query",
            headers={"Authorization": f"Bearer {api_key}"},
            json={"question": question},
            timeout=30
        )
        if resp.status_code == 429:
            wait = int(resp.headers.get("Retry-After", 60))
            time.sleep(wait)
            continue
        resp.raise_for_status()
        return resp.json()
    raise Exception("Max retries exceeded")

Support

Emailhello@usejack.io
Dashboardapp.usejack.io
Docsdocs.usejack.io
← PREVIOUSUsage