Skip to main content
Every Signa API error follows a consistent structure inspired by RFC 9457. Errors are wrapped under an "error" key with machine-readable fields for programmatic handling.

Error Response Structure

{
  "error": {
    "type": "not_found",
    "title": "Resource not found",
    "status": 404,
    "detail": "Trademark tm_xxx does not exist.",
    "instance": "/v1/trademarks/tm_xxx",
    "suggestion": "Check the trademark ID. Use GET /v1/trademarks?q=... to find marks by text.",
    "retryable": false,
    "retry_after": null
  },
  "request_id": "req_abc123"
}
FieldTypeDescription
typestringSnake_case error type slug (stable identifier for programmatic use, e.g. not_found, validation_error, rate_limited)
titlestringHuman-readable error title
statusintegerHTTP status code
detailstringSpecific error description for this instance
instancestringRequest path that caused the error
suggestionstringActionable fix guidance
retryablebooleanWhether the client should retry
retry_afterinteger or nullSeconds to wait before retry
request_idstringUnique request identifier for support (top-level, alongside error)

Error Catalog

StatusType SlugRetryableTitleExample MessageCommon CauseFix
400validation_errorNoValidation failed”Parameter ‘limit’ must be between 1 and 100.”Invalid query parameter, missing required field, malformed JSON bodyCheck the parameter types and ranges. See the endpoint documentation for accepted values.
400id_type_mismatchNoID type mismatch”Expected an owner ID (own_*) but received tm_abc123.”Using a trademark ID where an owner ID is expected (or vice versa)Use the correct ID prefix for the endpoint. Owner endpoints expect own_*, trademark endpoints expect tm_*, etc.
400cursor_expiredNoCursor expired”The pagination cursor has expired. Start a new query.”Pagination cursor is more than 24 hours oldStart a fresh pagination session. For long-running syncs, checkpoint and resume within the 24-hour window.
401unauthorizedNoAuthentication required”Invalid API key.”Missing Authorization header, invalid key format, expired key, revoked keyCheck that you are sending Authorization: Bearer sig_xxx with a valid key. Verify the key has not expired or been revoked.
403forbiddenNoInsufficient scope”API key does not have the ‘trademarks:read’ scope.”The API key is valid but lacks the required scope for this endpointCreate a new API key with the required scopes, or update the existing key’s scopes via PATCH /v1/organization/api-keys/{id}.
403plan_upgrade_requiredNoPlan upgrade required”Portfolios is not available on your current plan. Upgrade to access this feature.”The endpoint belongs to a feature that is not included in your current plan (e.g. portfolios, watches, saved searches, alerts, events)Upgrade your plan to gain access. Contact sales if you need this capability enabled. Not retryable — the response will not change without a plan change.
404not_foundNoResource not found”Trademark tm_xxx does not exist.”The ID does not exist, was deleted, or belongs to a different resource typeVerify the ID is correct. Use search to find the resource if you do not have the exact ID.
409conflictNoConflict”Idempotency key ‘abc123’ was already used with a different request body.”Reusing an Idempotency-Key header with a different request bodyGenerate a new unique idempotency key for each distinct request. If retrying the same request, use the same key AND the same body.
410entity_mergedNoEntity merged”Owner own_old123 has been merged into own_abc123.”The entity was deduplicated via entity resolution. The old ID is permanently redirected.Follow the merged_into field in the error response to the canonical entity. Update any cached references.
429rate_limitedYesRate limit exceeded”Rate limit exceeded. Retry after 30 seconds.”Too many requests within the rate limit windowWait for retry_after seconds, then retry. See Rate Limits.
500internal_errorYesInternal server error”An unexpected error occurred.”Server-side bug or transient failureRetry with exponential backoff. If the error persists, contact support with the request_id.
503service_unavailableYesService unavailable”Database is temporarily unavailable.”A backend dependency is downWait for retry_after seconds, then retry. Check status.signa.so for ongoing incidents.

Handling Errors

Errors return non-2xx status codes. The response body always contains a structured error object and a top-level request_id.
curl -s -w "\nHTTP Status: %{http_code}\n" \
  https://api.signa.so/v1/trademarks/tm_nonexistent \
  -H "Authorization: Bearer sig_xxx"
The TypeScript SDK exposes typed error classes for each status code. See SDK Error Handling for instanceof patterns and automatic retries.

Idempotency and 409 Conflict

Mutating requests (PATCH, DELETE, and non-search POST) require an Idempotency-Key header:
PATCH /v1/organization/api-keys/key_abc123
Idempotency-Key: rename-prod-key-2026-03-24-001
Same key + same body = cached response replayed (safe to retry). Same key + different body = 409 Conflict error. Idempotency keys are scoped to your organization and expire after 24 hours.
curl -s -X PATCH https://api.signa.so/v1/organization/api-keys/key_abc123 \
  -H "Authorization: Bearer sig_xxx" \
  -H "Content-Type: application/json" \
  -H "Idempotency-Key: my-unique-key-123" \
  -d '{"name": "Production key (renamed)"}'
A handful of endpoints are exempt by design and ignore Idempotency-Key (search endpoints are read-only; api-key creation and rotation return one-time secrets that must not be cached and replayed):
  • POST /v1/trademarks (search)
  • POST /v1/trademarks/batch (batch lookup)
  • POST /v1/suggest (and other suggest endpoints)
  • POST /v1/organization/api-keys (create — returns one-time secret_value)
  • POST /v1/organization/api-keys/{id}/rotate (rotate — returns one-time secret_value)
See Resilience and Retries → Idempotent Requests for the full exemption list and a worked retry example.

Troubleshooting by Symptom

Check your Authorization header format. It must be Authorization: Bearer sig_xxx (with the Bearer prefix). Common mistakes:
  • Missing Bearer prefix: Authorization: sig_xxx
  • Wrong key prefix: only keys of the form sig_{48 hex chars} are accepted. Any other prefix is rejected with 401 before any database lookup.
  • Expired key: check expires_at on your API key
  • Revoked key: check the API key status in your dashboard
Your API key is valid but does not have the required scope for this endpoint. Each endpoint requires specific scopes:
  • Trademark search, list, and entity GET endpoints need trademarks:read
  • API key management needs api-keys:manage
  • Usage and log endpoints need billing:read
Create a new key with the needed scopes or update your existing key.
Common causes:
  • Missing required filter: GET /v1/trademarks requires at least one filter (no unscoped list queries).
  • Wrong date format: Use ISO 8601 (2026-03-24 or 2026-03-24T12:00:00Z).
  • Array syntax: Bracketed keys (e.g. offices[]=uspto) are not accepted; repeated keys (e.g. offices=uspto&offices=euipo) are accepted as a fallback, but the canonical form is comma-separated (offices=uspto,euipo).
  • Date range syntax: Use flat underscore operators, not brackets: ?filing_date_gte=2020-01-01&filing_date_lt=2025-01-01.
  • Boolean values: Only the literal strings true and false are accepted. 1, 0, yes, no, and TRUE all return a validation error.
  • application_number without office: When filtering by application_number or registration_number, you must also specify office.
  • Missing Idempotency-Key: All POST/PATCH/DELETE requests require this header.
Entity resolution runs periodically. When two owner records are identified as the same entity, one is merged into the other. The 410 response includes a merged_into field pointing to the canonical record.Update your cached ID to the new one. All trademarks previously associated with the old owner are now under the canonical record.
This is expected behavior due to the eventual consistency model. Search reads from OpenSearch (eventually consistent, typically under 30 seconds lag), while detail reads from PostgreSQL (immediately consistent).If you just updated a record, wait a few seconds and retry the search. For time-sensitive workflows, use the detail endpoint as the source of truth.
For bulk lookups, use Batch Get Trademarks (up to 100 IDs per request) instead of individual GET requests. This counts as one request against your rate limit.For search-heavy workloads, consider caching results on your side, using cursor pagination instead of re-executing searches, or upgrading your plan.
This indicates a transient backend issue. The error is retryable — wait for the retry_after period and retry with exponential backoff. If 503 errors persist for more than a few minutes, check status.signa.so for ongoing incidents.