Skip to content

Error Reference

Error Reference

All qr3.app API errors follow RFC 7807 Problem Details with Content-Type: application/problem+json.

{
"type": "https://docs.qr3.app/errors/not-found",
"title": "Not Found",
"status": 404,
"detail": "QR code qr_xxx not found"
}

errors/validation

HTTP 422 Unprocessable Entity

Input data failed schema validation. The response includes an errors array with field-level details.

{
"type": "https://docs.qr3.app/errors/validation",
"title": "Validation Error",
"status": 422,
"detail": "Request body validation failed",
"errors": [
{ "field": "url", "message": "Invalid URL format" }
]
}

Causes: Missing required fields, wrong data types, values out of allowed range, invalid URL format.


errors/bad-request

HTTP 400 Bad Request

The body is not valid JSON although Content-Type: application/json is set (e.g., a trailing comma, a truncated or an empty body).

{
"type": "https://docs.qr3.app/errors/bad-request",
"title": "Bad Request",
"status": 400,
"detail": "The request could not be processed"
}

errors/authentication

HTTP 401 Unauthorized

The API key is missing, malformed, expired, or revoked.

{
"type": "https://docs.qr3.app/errors/authentication",
"title": "Unauthorized",
"status": 401,
"detail": "Invalid or missing API key"
}

Fix: Check that your Authorization: Bearer qr3_sk_... header is present and the key is active.


errors/unauthorized

HTTP 401 Unauthorized

An inbound webhook (POST /v1/webhooks/clerk, POST /v1/webhooks/eu-registry) was called without a valid signature or secret. A missing or invalid API key answers errors/authentication instead.

{
"type": "https://docs.qr3.app/errors/unauthorized",
"title": "Unauthorized",
"status": 401,
"detail": "Invalid Svix signature"
}

errors/authorization

HTTP 403 Forbidden

The API key is valid but does not have the required scope or permissions.

{
"type": "https://docs.qr3.app/errors/authorization",
"title": "Forbidden",
"status": 403,
"detail": "API key does not have the required scope"
}

errors/forbidden

HTTP 403 Forbidden

The resource exists but belongs to a different workspace or organization.

{
"type": "https://docs.qr3.app/errors/forbidden",
"title": "Forbidden",
"status": 403,
"detail": "You do not have access to this resource"
}

errors/document-immutable

HTTP 403 Forbidden

A DPP document uploaded with is_immutable cannot be deleted.

{
"type": "https://docs.qr3.app/errors/document-immutable",
"title": "Forbidden",
"status": 403,
"detail": "Immutable documents cannot be deleted"
}

errors/not-found

HTTP 404 Not Found

The requested resource does not exist or has been deleted.

{
"type": "https://docs.qr3.app/errors/not-found",
"title": "Not Found",
"status": 404,
"detail": "QR code qr_xxx not found"
}

errors/conflict

HTTP 409 Conflict

A resource with the same unique identifier already exists (e.g., duplicate slug or idempotency key collision).

{
"type": "https://docs.qr3.app/errors/conflict",
"title": "Conflict",
"status": 409,
"detail": "An organization with slug 'my-org' already exists"
}

errors/subscription-exists

HTTP 409 Conflict

POST /v1/billing/checkout was called although the organization already has a subscription. Change the plan in the billing portal instead.

{
"type": "https://docs.qr3.app/errors/subscription-exists",
"title": "Subscription already active",
"status": 409,
"detail": "This organization already has an active subscription. Manage or change it in the billing portal (GET /v1/billing/portal) instead of starting a new checkout.",
"current_plan": "pro",
"subscription_status": "active"
}

errors/rate-limited

HTTP 429 Too Many Requests

The API key’s per-minute rate limit has been exceeded.

{
"type": "https://docs.qr3.app/errors/rate-limited",
"title": "Too Many Requests",
"status": 429,
"detail": "Rate limit exceeded. Retry after 60 seconds."
}

The response includes:

  • Retry-After: 60
  • X-RateLimit-Limit: <limit>
  • X-RateLimit-Remaining: 0
  • X-RateLimit-Reset: <unix_timestamp>

errors/rate-limit

HTTP 429 Too Many Requests

A resource-level rate limit has been exceeded (e.g., 200 QR codes per day per workspace, or 5 abuse reports per hour).

{
"type": "https://docs.qr3.app/errors/rate-limit",
"title": "Too Many Requests",
"status": 429,
"detail": "Daily QR code creation limit (200) reached"
}

errors/plan-limit

HTTP 422 Unprocessable Entity

Your current plan does not allow this action (e.g., DPP or dynamic code quota used up, batch too large, too many workspaces or team members). Upgrade required.

{
"type": "https://docs.qr3.app/errors/plan-limit",
"title": "Plan Limit Reached",
"status": 422,
"detail": "Your plan allows a maximum of 25 dynamic QR code(s). Upgrade to create more.",
"resource": "dynamic_codes",
"limit": 25,
"used": 25
}

errors/invalid-file-type

HTTP 400 Bad Request

The uploaded file has a type the endpoint does not accept, or its content does not match the declared Content-Type.

{
"type": "https://docs.qr3.app/errors/invalid-file-type",
"title": "Invalid File Type",
"status": 400,
"detail": "Magic bytes indicate PDF but Content-Type does not match"
}

errors/file-too-large

HTTP 413 Payload Too Large

The uploaded file exceeds the size limit of the plan or of the endpoint.

{
"type": "https://docs.qr3.app/errors/file-too-large",
"title": "Payload Too Large",
"status": 413,
"detail": "File exceeds plan limit of 26214400 bytes"
}

errors/storage-limit-exceeded

HTTP 422 Unprocessable Entity

The upload would exceed the total storage of the workspace or of the DPP.

{
"type": "https://docs.qr3.app/errors/storage-limit-exceeded",
"title": "Unprocessable Entity",
"status": 422,
"detail": "Total file storage for this workspace would exceed your plan limit."
}

errors/not-configured

HTTP 503 Service Unavailable

A required service or configuration is missing (e.g., Stripe not configured, Web Risk API key not set).

{
"type": "https://docs.qr3.app/errors/not-configured",
"title": "Service Not Configured",
"status": 503,
"detail": "Billing is not configured in this environment"
}

errors/unsafe-url

HTTP 422 Unprocessable Entity

The URL was rejected because it was flagged as unsafe by Google Web Risk (malware, phishing, social engineering).

{
"type": "https://docs.qr3.app/errors/unsafe-url",
"title": "Unsafe URL",
"status": 422,
"detail": "The URL was flagged as SOCIAL_ENGINEERING by Web Risk"
}

errors/url-flagged

HTTP 422 Unprocessable Entity

Reserved for URLs that were previously marked as safe but were subsequently flagged by periodic re-scanning.


errors/already-submitted

HTTP 409 Conflict

Duplicate submission — for example, an NPS score has already been submitted for this workspace this month.

{
"type": "https://docs.qr3.app/errors/already-submitted",
"title": "Already Submitted",
"status": 409,
"detail": "An NPS score was already submitted for this workspace this month"
}

errors/unprocessable-entity

HTTP 422 Unprocessable Entity

An admin action is not allowed (e.g., impersonating another superadmin). Only the superadmin endpoints return this type.

{
"type": "https://docs.qr3.app/errors/unprocessable-entity",
"title": "Unprocessable Entity",
"status": 422,
"detail": "Cannot impersonate another superadmin."
}

errors/request-error

HTTP 4xx Client Error

Fallback for client errors without a more specific type; the status is in the response. The API currently has no known path that returns it.


errors/internal

HTTP 500 Internal Server Error

An unexpected error occurred on the server. Please retry the request. If the problem persists, contact [email protected].

{
"type": "https://docs.qr3.app/errors/internal",
"title": "Internal Server Error",
"status": 500,
"detail": "An unexpected error occurred"
}