Kanorio

API reference

Errors

The one error shape every Kanorio API returns, how codes map to HTTP statuses, and how to handle retries.

The Management API, the Content Delivery API and the Customer API return errors in the same shape. A code always has the same HTTP status on every API, so one error handler works for all of them.

{
  "error": {
    "code": "SLUG_TAKEN",
    "message": "Another post already uses this slug.",
    "details": { "slug": "how-we-feed-our-starter" }
  }
}
FieldTypeNotes
error.codestringStable, machine-readable. Branch on this.
error.messagestringOne English sentence for logs and developers. It can change at any time, so never match on it.
error.detailsobject, optionalStructured context for the code, such as retryAfter, availableAt, issues or requiredScope.

Successful responses never contain error, and no API wraps success in an ok flag.

HTTP status by code

Every code maps to one status. Codes added later follow the same rules, so you can handle a code you have not seen yet by its status.

StatusMeaningExamples
400The request is malformed or fails validationVALIDATION, INVALID_CURSOR, codes starting with INVALID_
401No credential, or the credential is invalid, expired or revokedUNAUTHORIZED, UNAUTHENTICATED
403The credential is valid but not allowed: permission, plan, role or modeFORBIDDEN, OWNER_REQUIRED, LIMIT_REACHED, LOCKED
404The resource does not exist on this siteNOT_FOUND, codes ending in _NOT_FOUND
405The method is not supported on this pathMETHOD_NOT_ALLOWED
409Conflicts with the current state: stale writes, taken slugs, duplicatesCONFLICT, SLUG_TAKEN, IDEMPOTENCY_CONFLICT
413The upload is too largeFILE_TOO_LARGE
422Valid input, but a business rule does not allow itSITE_NOT_PUBLISHED, ASSET_IN_USE
429Too many requests, or a busy backend; retry laterRATE_LIMITED, SEARCH_BUSY, ANALYTICS_BUSY
500Unexpected server errorINTERNAL
502, 503An upstream service failed or is temporarily unavailableUPLOAD_FAILED, SERVICE_UNAVAILABLE, SHARED_SENDER_PAUSED

Each operation in the API reference lists the codes it can return and what they mean for that operation. The OpenAPI documents carry the same list as x-kanorio-errors.

Validation errors

VALIDATION lists every failing field in details.issues. path uses dots for nesting.

{
  "error": {
    "code": "VALIDATION",
    "message": "Input does not match the capability schema.",
    "details": {
      "issues": [
        { "path": "title", "message": "Required", "code": "invalid_type" }
      ]
    }
  }
}

Form submissions on the Content Delivery API report invalid answers the same way, with the question id as the path.

Retries

  • Retry 429, 502 and 503 with backoff. When the response has a Retry-After header or details.retryAfter, wait at least that many seconds.
  • Do not retry other 4xx responses unchanged. Fix the request first.
  • 409 CONFLICT on a write means someone changed the resource after you read it. Read it again, merge, and send the write with the new timestamp.
  • Make create requests safe to retry with an idempotency key.

Permission errors

403 responses explain what is missing in details, for example the requiredScope the token lacks or reason: "principal_not_allowed" when a service account calls an account-level operation. Show the user what to change instead of retrying.

Request IDs

Content Delivery API and Customer API responses carry an X-Request-Id header. Include it when you contact support about a specific request.

Error codes

The tables below list every code each API can return today, generated from the OpenAPI documents.

Management API codes

CodeHTTP status
EMPTY_SLUG400
INVALID_BODY400
INVALID_CURSOR400
INVALID_EDITED_PATH400
INVALID_FORMAT400
INVALID_ORDER400
INVALID_SUBDOMAIN400
UNSUPPORTED_EDITED_PATH400
VALIDATION400
UNAUTHENTICATED401
UNAUTHORIZED401
CUSTOM_DOMAIN_CHANGE_FORBIDDEN403
CUSTOM_DOMAIN_LIMIT_REACHED403
FORBIDDEN403
LIMIT_REACHED403
MODERATION_LOCKED403
OWNER_REQUIRED403
PLAN_CANNOT_PUBLISH403
PRO_REQUIRED403
REDIRECT_LIMIT403
SUBDOMAIN_CHANGE_FORBIDDEN403
TOKEN_WEBSITE_SCOPED403
HEADER_NOT_FOUND404
HOME_PAGE_NOT_FOUND404
NOT_FOUND404
OWNER_NOT_FOUND404
PAGE_NOT_FOUND404
PARENT_NOT_FOUND404
PRODUCT_NOT_FOUND404
WEBSITE_NOT_FOUND404
METHOD_NOT_ALLOWED405
CONFLICT409
CUSTOM_DOMAIN_TAKEN409
HAS_CHILDREN409
HOSTED_ONLY409
HOSTNAME_CONFLICT409
IDEMPOTENCY_CONFLICT409
IDEMPOTENCY_IN_PROGRESS409
KEY_TAKEN409
PRIMARY_HEADER_PROTECTED409
READD_COOLDOWN409
REDIRECT_CONFLICT409
SLUG_TAKEN409
SUBDOMAIN_TAKEN409
TAKEN409
BLOCKED422
BREADCRUMB_PARENT_INVALID422
CONTENT_VALIDATION_FAILED422
CORE_SECTION_VIOLATION422
CUSTOM_DOMAIN_BLOCKED422
CUSTOM_DOMAIN_HIGH_RISK_TLD422
CUSTOM_DOMAIN_TOO_LONG422
DEPTH_EXCEEDED422
DNS_NOT_PROPAGATED422
DOMAIN_CHANGE_NOT_ALLOWED422
EMPTY_CONTENT422
FOREIGN_PAGE422
HIGH_RISK_TLD422
HOME_HAS_HIERARCHY422
HOME_NOT_CREATABLE422
HOME_NOT_DELETABLE422
HOME_NOT_SORTABLE422
HOME_SLUG_IMMUTABLE422
LINK_IN_BIO_DEDICATED_ENTRY422
LINK_IN_BIO_NOT_DUPLICABLE422
META_NOT_LIVE422
NO_PUBLIC_URL422
OWNERSHIP_REQUIRED422
PAGE_LIMIT_REACHED422
PARENT_NOT_ALLOWED422
RESERVED_SEGMENT422
RESERVED_SLUG422
RESERVED_SUBDOMAIN422
SANITIZE_FAILED422
SEARCH_CONSOLE_AUTH_EXPIRED422
SEARCH_CONSOLE_NOT_CONNECTED422
SEARCH_CONSOLE_PERMISSION_DENIED422
SEARCH_CONSOLE_PROPERTY_NOT_FOUND422
SEGMENT_TOO_LONG422
SITEMAP_NOT_REACHABLE422
SUBDOMAIN_MISSING422
SYSTEM_PAGE_LOCKED422
TEMPLATE_PRODUCT_LOCKED422
ANALYTICS_BUSY429
DAILY_LIMIT_REACHED429
RATE_LIMITED429
SEARCH_BUSY429
SEARCH_CONSOLE_QUOTA_EXCEEDED429
STOCK_BUSY429
INTERNAL500
SEARCH_CONSOLE_ERROR502
BUSY503
SEARCH_CONSOLE_UNAVAILABLE503
SERVICE_UNAVAILABLE503
WRITE_FROZEN503

Content Delivery API codes

CodeHTTP status
BAD_HOST400
FILE_TYPE_NOT_ALLOWED400
INVALID_ANSWERS400
INVALID_BODY400
INVALID_CURSOR400
INVALID_KIND400
INVALID_LIMIT400
INVALID_PATH400
INVALID_QUERY400
QUERY_REQUIRED400
QUERY_TOO_LONG400
QUERY_TOO_SHORT400
TOO_MANY_PARAMS400
UNKNOWN_BOT400
UNSUPPORTED_LOCALE400
VALIDATION400
VERIFICATION_EXPIRED400
NOT_PREVIEW403
COLLECTION_NOT_FOUND404
FORM_NOT_FOUND404
HEADER_NOT_FOUND404
ITEM_NOT_FOUND404
PAGE_NOT_FOUND404
PRODUCT_NOT_FOUND404
SITE_NOT_FOUND404
UNIT_NOT_FOUND404
DUPLICATE_SUBMISSION409
FILE_TOO_LARGE413
RATE_LIMITED429
SEARCH_BUSY429
QUERY_TIMEOUT503
UPLOAD_UNAVAILABLE503
UPSTREAM_UNAVAILABLE503

Customer API codes

CodeHTTP status
BAD_HOST400
INVALID_CODE400
INVALID_CURSOR400
INVALID_EMAIL400
INVALID_LIMIT400
VALIDATION400
UNAUTHENTICATED401
BOT_PROTECTION_FAILED403
DOWNLOAD_NOT_ALLOWED403
EXPIRED403
FORBIDDEN403
LIMIT_REACHED403
LOCKED403
NOT_RELEASED403
NO_ATTEMPTS_LEFT403
REVIEWS_DISABLED403
CERTIFICATE_DISABLED404
DELIVERABLE_NOT_FOUND404
NOT_FOUND404
NO_FILE404
NO_RECEIPT404
ORDER_NOT_FOUND404
SITE_NOT_FOUND404
UNIT_NOT_FOUND404
WEBSITE_NOT_FOUND404
METHOD_NOT_ALLOWED405
ALREADY_REVIEWED409
FILE_NOT_PROTECTED409
NOT_A_QUIZ409
QUIZ_NOT_READY409
ACCOUNT_BLOCKED422
ALREADY_REGISTERED422
CHALLENGE_EXPIRED422
EMAIL_NOT_VERIFIED422
METHOD_DISABLED422
VERIFY_FAILED422
RATE_LIMITED429
SHARED_SENDER_PAUSED503
SIGN_FAILED503
UPSTREAM_UNAVAILABLE503