error object with
code (HTTP status), key (machine-readable key), message (human-readable
text), optional details, and a meta.requestId.
Match client logic on the exact error.key string, never on error.message.
Messages may be reworded or translated; keys are stable.
error.key values come in two families:
- Framework keys are dotted lowercase (
auth.invalid_token,rate_limit.exceeded). They are emitted by the shared Public API plumbing: authentication, scopes, rate limiting, idempotency, routing, and server errors. They can occur on any bearer endpoint. - Endpoint validation keys are
UPPER_SNAKE(PUBLIC_API_INVALID_CLIENT_ID,CLIENT_NOT_FOUND). They are emitted by endpoint request validation and domain checks, so each key only occurs on the endpoints that use the underlying resource.
Framework keys
| Key | HTTP status | Meaning | How to resolve |
|---|---|---|---|
auth.missing_bearer | 401 | The Authorization header is missing or is not a Bearer token. | Send Authorization: Bearer <access_token>. |
auth.invalid_token | 401 | The access token is malformed, expired, or revoked. | Request a new token from POST /public/v1/oauth/token. |
auth.invalid_client | 401 | The OAuth client behind the token no longer exists or is disabled. | Check the API client status in the coach portal, or create a new client. |
auth.missing_context | 401 | The token carries no usable company context. | Request a new token. Contact support when the issue persists. |
scopes.insufficient | 403 | The token is missing a scope required by this endpoint. | Request a token that includes every scope the endpoint page documents. |
scopes.health_consent_required | 403 | The endpoint requires a health-consent-gated scope, but the API client was created without the health data consent. | Have a coach recreate the API client with "consents": { "healthData": true }. |
scopes.private_communication_consent_required | 403 | The endpoint requires a private-communication-gated scope, but the API client was created without that consent. | Have a coach recreate the API client with "consents": { "privateCommunication": true }. |
rate_limit.exceeded | 429 | The per-client rate limit was exceeded. | Wait Retry-After seconds (also in meta.rateLimit.retryAfterSeconds) and retry. |
idempotency.required | 400 | A write request is missing the Idempotency-Key header. | Send a stable Idempotency-Key on every POST, PUT, PATCH, and DELETE. |
idempotency.invalid | 400 | The Idempotency-Key is empty or longer than 200 characters. | Use a non-empty key of at most 200 characters. |
idempotency.conflict | 409 | The same key was reused with a different method, path, query, or body. | Use a new key for a new request; reuse a key only for exact retries. |
idempotency.in_progress | 409 | The first request with this key is still processing. | Wait briefly and retry with the same key. |
resource.not_found | 404 | No route matches the requested path. | Check the URL path and HTTP method against the endpoint documentation. |
request.failed | varies | Generic fallback when no specific key applies. | Inspect the HTTP status and error.message. |
webhook.request_invalid | 400 | Generic fallback for invalid webhook management requests. | Check the request against the webhooks page. |
server.internal_error | 500 | An unexpected Public API server error occurred. | Retry later. Report meta.requestId to support when the issue persists. |
Endpoint validation keys
Endpoint validation keys useUPPER_SNAKE. The tables below list every key the
Public API can emit. PUBLIC_API_* keys are Public API specific; the domain
keys in the second table are shared with internal validation logic but are just
as stable.
PUBLIC_API_* keys
| Key | HTTP status | Meaning | How to resolve |
|---|---|---|---|
PUBLIC_API_AUDIT_LOG_NOT_FOUND | 404 | Audit log entry was not found. | Check that the id exists and belongs to the authenticated company. |
PUBLIC_API_AUDIT_STORE_UNAVAILABLE | 500 | The audit store is currently unavailable. | Retry later. Contact support when the issue persists. |
PUBLIC_API_AVAILABILITY_SLOT_NOT_BOOKABLE | 409 | This availability slot can no longer be booked. | Fetch the current resource state and adjust the request. |
PUBLIC_API_BOOKING_REQUEST_NOT_FOUND | 404 | Booking request was not found. | Check that the id exists and belongs to the authenticated company. |
PUBLIC_API_BOOKING_REQUEST_NOT_PENDING | 400 | Booking request is no longer pending. | Fetch the current resource state and adjust the request. |
PUBLIC_API_CHARGEBACK_NOT_FOUND | 404 | Chargeback was not found. | Check that the id exists and belongs to the authenticated company. |
PUBLIC_API_CLIENT_EMAIL_REQUIRED_FOR_INVITE | 400 | An email address is required to invite this client. | Include the missing field or context in the request. |
PUBLIC_API_CLIENT_NOT_FOUND | 404 | Client was not found. | Check that the id exists and belongs to the authenticated company. |
PUBLIC_API_CLIENT_PRODUCT_NOT_FOUND | 404 | Client product was not found. | Check that the id exists and belongs to the authenticated company. |
PUBLIC_API_COACH_NOT_FOUND | 404 | Coach was not found. | Check that the id exists and belongs to the authenticated company. |
PUBLIC_API_COACH_REQUIRED | 400 | A coach is required for this request. | Include the missing field or context in the request. |
PUBLIC_API_COMPANY_NOT_FOUND | 404 | Company was not found. | Check that the id exists and belongs to the authenticated company. |
PUBLIC_API_COMPANY_POLICIES_NOT_FOUND | 404 | Company policies were not found. | Check that the id exists and belongs to the authenticated company. |
PUBLIC_API_CUSTOM_FIELD_VALUES_REQUIRED | 400 | Provide at least one custom field value. | Include the missing field or context in the request. |
PUBLIC_API_DATE_RANGE_ORDER_INVALID | 400 | The end date must be on or after the start date. | Send a value that matches the documented format and limits. |
PUBLIC_API_DATE_RANGE_REQUIRED | 400 | Provide both a start date and an end date. | Include the missing field or context in the request. |
PUBLIC_API_DATE_RANGE_TOO_LARGE | 400 | The requested date range is too large. | Send a value that matches the documented format and limits. |
PUBLIC_API_DOCUMENT_FOLDER_NOT_FOUND | 404 | Document folder was not found. | Check that the id exists and belongs to the authenticated company. |
PUBLIC_API_DOCUMENT_NAME_REQUIRED | 400 | Enter a document name. | Include the missing field or context in the request. |
PUBLIC_API_DOCUMENT_NOT_FOUND | 404 | Document was not found. | Check that the id exists and belongs to the authenticated company. |
PUBLIC_API_DOCUMENT_NOTHING_TO_UPDATE | 400 | Update at least one document field. | Include at least one updatable field in the request body. |
PUBLIC_API_DOCUMENT_TYPE_REQUIRED | 400 | Enter a document type. | Include the missing field or context in the request. |
PUBLIC_API_DOCUMENT_URL_INVALID | 400 | Enter a valid document URL. | Send a value that matches the documented format and limits. |
PUBLIC_API_ERROR | 400, 403, 404, or 409 | The Public API request failed. | Generic fallback. Inspect the HTTP status and meta.requestId, and contact support when the cause is unclear. |
PUBLIC_API_EVENT_TEMPLATE_DURATION_REQUIRED | 400 | Enter an event template duration. | Include the missing field or context in the request. |
PUBLIC_API_EVENT_TEMPLATE_NAME_REQUIRED | 400 | Enter an event template name. | Include the missing field or context in the request. |
PUBLIC_API_EVENT_TEMPLATE_NOT_FOUND | 404 | Event template was not found. | Check that the id exists and belongs to the authenticated company. |
PUBLIC_API_EVENT_TYPE_NAME_REQUIRED | 400 | Enter an event type name. | Include the missing field or context in the request. |
PUBLIC_API_EVENT_TYPE_NOT_FOUND | 404 | Event type was not found. | Check that the id exists and belongs to the authenticated company. |
PUBLIC_API_FIELD_TOO_LONG | 400 | One of the provided fields exceeds its maximum length. | Send a value that matches the documented format and limits. |
PUBLIC_API_HEALTH_CONSENT_REQUIRED | 400 | The requested scopes include health data, but the health data consent was not accepted. | Emitted by the coach-app client creation endpoint. Include "consents": { "healthData": true } when granting health-gated scopes. |
PUBLIC_API_IDEMPOTENCY_PERSISTENCE_FAILED | 500 | The idempotency record could not be stored. | Retry the request with the same Idempotency-Key. Contact support when the issue persists. |
PUBLIC_API_INVALID_ACCESS_ZONES | 400 | Access zones are invalid. | Send a value that matches the documented format and limits. |
PUBLIC_API_INVALID_ATTENDANCE_STATUS | 400 | Attendance status is invalid. | Send a value that matches the documented format and limits. |
PUBLIC_API_INVALID_AUDIT_LOG_ID | 400 | Audit log id is invalid. | Send a valid identifier as documented for the endpoint. |
PUBLIC_API_INVALID_BOOKING_REQUEST_ID | 400 | Booking request id is invalid. | Send a valid identifier as documented for the endpoint. |
PUBLIC_API_INVALID_BOOKING_REQUEST_STATUS | 400 | Booking request status is invalid. | Send a value that matches the documented format and limits. |
PUBLIC_API_INVALID_BOOLEAN | 400 | Provide a valid boolean value. | Send a value that matches the documented format and limits. |
PUBLIC_API_INVALID_CALENDAR_EVENT_ID | 400 | Calendar event id is invalid. | Send a valid identifier as documented for the endpoint. |
PUBLIC_API_INVALID_CANCELLATION_TIMING | 400 | Cancellation timing is invalid. | Send a value that matches the documented format and limits. |
PUBLIC_API_INVALID_CAPACITY_ACTION | 400 | Capacity action is invalid. | Send a value that matches the documented format and limits. |
PUBLIC_API_INVALID_CHARGEBACK_ID | 400 | Chargeback id is invalid. | Send a valid identifier as documented for the endpoint. |
PUBLIC_API_INVALID_CLIENT_ID | 400 | Client id is invalid. | Send a valid identifier as documented for the endpoint. |
PUBLIC_API_INVALID_CLIENT_PRODUCT_ID | 400 | Client product id is invalid. | Send a valid identifier as documented for the endpoint. |
PUBLIC_API_INVALID_COACH_ID | 400 | Coach id is invalid. | Send a valid identifier as documented for the endpoint. |
PUBLIC_API_INVALID_COORDINATES | 400 | Coordinates are invalid. | Send a value that matches the documented format and limits. |
PUBLIC_API_INVALID_CURRENCY | 400 | Currency is invalid. | Send a value that matches the documented format and limits. |
PUBLIC_API_INVALID_DATE | 400 | Provide a valid date. | Send a value that matches the documented format and limits. |
PUBLIC_API_INVALID_DATE_RANGE | 400 | Provide a valid date range. | Send a value that matches the documented format and limits. |
PUBLIC_API_INVALID_DOCUMENT_FOLDER_ID | 400 | Document folder id is invalid. | Send a valid identifier as documented for the endpoint. |
PUBLIC_API_INVALID_DOCUMENT_ID | 400 | Document id is invalid. | Send a valid identifier as documented for the endpoint. |
PUBLIC_API_INVALID_ENUM | 400 | One of the provided fields has an unsupported value. | Send a value that matches the documented format and limits. |
PUBLIC_API_INVALID_FIELD_TYPE | 400 | One of the provided fields has an invalid type. | Send a value that matches the documented format and limits. |
PUBLIC_API_INVALID_FORM_TYPE | 400 | Form type is invalid. | Send a value that matches the documented format and limits. |
PUBLIC_API_INVALID_GOAL_DATE | 400 | Goal date is invalid. | Send a value that matches the documented format and limits. |
PUBLIC_API_INVALID_GOAL_ENUM | 400 | One of the goal fields has an unsupported value. | Send a value that matches the documented format and limits. |
PUBLIC_API_INVALID_GOAL_NUMBER | 400 | One of the goal fields has an invalid number. | Send a value that matches the documented format and limits. |
PUBLIC_API_INVALID_INSTANCE_DATE | 400 | Instance date is invalid. | Send a value that matches the documented format and limits. |
PUBLIC_API_INVALID_INTEGER | 400 | Provide a valid integer value. | Send a value that matches the documented format and limits. |
PUBLIC_API_INVALID_INVOICE_ID | 400 | Invoice id is invalid. | Send a valid identifier as documented for the endpoint. |
PUBLIC_API_INVALID_INVOICE_TYPE | 400 | Invoice type is invalid. | Send a value that matches the documented format and limits. |
PUBLIC_API_INVALID_LOCATION_ID | 400 | Location id is invalid. | Send a valid identifier as documented for the endpoint. |
PUBLIC_API_INVALID_LOCATION_TYPE | 400 | Location type is invalid. | Send a value that matches the documented format and limits. |
PUBLIC_API_INVALID_NUMBER | 400 | Provide a valid number. | Send a value that matches the documented format and limits. |
PUBLIC_API_INVALID_PAUSE_WINDOW | 400 | Pause window is invalid. | Send a value that matches the documented format and limits. |
PUBLIC_API_INVALID_PAYMENT_ID | 400 | Payment id is invalid. | Send a valid identifier as documented for the endpoint. |
PUBLIC_API_INVALID_PAYMENT_METHOD | 400 | Payment method is invalid. | Send a value that matches the documented format and limits. |
PUBLIC_API_INVALID_PAYMENT_REQUEST_ID | 400 | Payment request id is invalid. | Send a valid identifier as documented for the endpoint. |
PUBLIC_API_INVALID_PRODUCT_ID | 400 | Product id is invalid. | Send a valid identifier as documented for the endpoint. |
PUBLIC_API_INVALID_PRODUCT_TYPE | 400 | Product type is invalid. | Send a value that matches the documented format and limits. |
PUBLIC_API_INVALID_RECURRING_BOOKING_ID | 400 | Recurring booking id is invalid. | Send a valid identifier as documented for the endpoint. |
PUBLIC_API_INVALID_RECURRING_END_DATE | 400 | Recurring end date is invalid. | Send a value that matches the documented format and limits. |
PUBLIC_API_INVALID_SUBSCRIPTION_ID | 400 | Subscription id is invalid. | Send a valid identifier as documented for the endpoint. |
PUBLIC_API_INVOICE_MESSAGE_NOT_ALLOWED | 400 | An invoice message is not allowed for this invoice. | Send a value that matches the documented format and limits. |
PUBLIC_API_INVOICE_NOT_FOUND | 404 | Invoice was not found. | Check that the id exists and belongs to the authenticated company. |
PUBLIC_API_LOCATION_NAME_REQUIRED | 400 | Enter a location name. | Include the missing field or context in the request. |
PUBLIC_API_LOCATION_NOT_FOUND | 404 | Location was not found. | Check that the id exists and belongs to the authenticated company. |
PUBLIC_API_NO_FIELDS_TO_UPDATE | 400 | Update at least one field. | Include at least one updatable field in the request body. |
PUBLIC_API_PAYMENT_NOT_FOUND | 404 | Payment was not found. | Check that the id exists and belongs to the authenticated company. |
PUBLIC_API_PAYMENT_REQUEST_NOT_FOUND | 404 | Payment request was not found. | Check that the id exists and belongs to the authenticated company. |
PUBLIC_API_PRICE_FIELDS_NOT_ALLOWED | 400 | Price fields cannot be updated through this endpoint. | Send a value that matches the documented format and limits. |
PUBLIC_API_PRIVATE_COMM_CONSENT_REQUIRED | 400 | The requested scopes include private communication, but that consent was not accepted. | Emitted by the coach-app client creation endpoint. Include "consents": { "privateCommunication": true } when granting private-communication-gated scopes. |
PUBLIC_API_PRODUCT_ALREADY_EXISTS | 409 | A product with this name already exists. | Fetch the current resource state and adjust the request. |
PUBLIC_API_PRODUCT_NOT_FOUND | 400 or 404 | Product was not found. | Check that the id exists and belongs to the authenticated company. |
PUBLIC_API_PRODUCT_REVOKE_NOT_SUPPORTED | 400 | This product type cannot be revoked. | See the message and endpoint documentation for details. |
PUBLIC_API_PRODUCT_VALIDATION_FAILED | 400 | Product validation failed. | See the message and endpoint documentation for details. |
PUBLIC_API_RECURRING_BOOKING_ALREADY_CANCELLED | 400 | Recurring booking is already cancelled. | Fetch the current resource state and adjust the request. |
PUBLIC_API_RECURRING_BOOKING_NOT_FOUND | 404 | Recurring booking was not found. | Check that the id exists and belongs to the authenticated company. |
PUBLIC_API_RECURRING_END_MODE_CONFLICT | 400 | Provide either a recurring end date or an occurrence count, not both. | Send only one of the two end-mode fields. |
PUBLIC_API_REQUIRED_FIELDS | 400 | One or more required fields are missing. | Include the missing field or context in the request. |
PUBLIC_API_UNKNOWN_FIELDS | 400 | The request contains unknown fields. | Remove undocumented fields from the request body. |
PUBLIC_API_UNKNOWN_GOAL_FIELDS | 400 | The request contains unknown goal fields. | Remove undocumented fields from the request body. |
PUBLIC_API_UNSUPPORTED_PRODUCT_TYPE | 400 | This product type is not supported. | Send a value that matches the documented format and limits. |
Domain keys
| Key | HTTP status | Meaning | How to resolve |
|---|---|---|---|
ASSIGNED_COACH_REQUIRED | 400 | assignedCoach is required | Include the missing field or context in the request. |
CHECKUP_CUSTOM_START_DATE_REQUIRED | 400 | Start date required for custom schedule type | Include the missing field or context in the request. |
CHECKUP_INVALID_OR_MISSING_MONTHLY_DAY | 400 | Invalid or missing monthly(day) schedule type | Send a value that matches the documented format and limits. |
CHECKUP_INVALID_OR_MISSING_MONTHLY_WEEK | 400 | Invalid or missing monthly(week) schedule type | Send a value that matches the documented format and limits. |
CHECKUP_INVALID_OR_MISSING_WEEKLY_ON | 400 | Invalid or missing weekly schedule type | Send a value that matches the documented format and limits. |
CHECKUP_INVALID_REPEAT_EVERY | 400 | Invalid repeat interval for custom schedule type | Send a value that matches the documented format and limits. |
CHECKUP_SETTING_NOT_FOUND | 404 | Checkup setting not found | Check that the id exists and belongs to the authenticated company. |
CLIENT_ALREADY_EXISTS | 409 | An account with this email already exists. Please log in to continue. | Fetch the current resource state and adjust the request. |
CLIENT_ALREADY_EXISTS_IN_COMPANY | 409 | This Client Already Exists in your company | Fetch the current resource state and adjust the request. |
CLIENT_NOT_FOUND | 400 or 404 | Client not found | Check that the id exists and belongs to the authenticated company. |
CLIENT_REGISTRATION_REQUEST_NOT_FOUND | 404 | Client registration request not found. | Check that the id exists and belongs to the authenticated company. |
COACH_ID_REQUIRED | 400 | Coach ID is required | Include the missing field or context in the request. |
COACH_NOT_FOUND | 404 | Coach not found | Check that the id exists and belongs to the authenticated company. |
COMPANY_ID_REQUIRED | 400 | companyId is required. | Include the missing field or context in the request. |
COMPANY_MCP_GOALS_NOT_FOUND | 404 | No goals were found for this client. | Check that the id exists and belongs to the authenticated company. |
COMPANY_MCP_INVALID_CLIENT_ID | 400 | Client id is invalid. | Send a valid identifier as documented for the endpoint. |
COMPANY_MCP_SUBSCRIPTION_NOT_FOUND | 404 | Subscription was not found. | Check that the id exists and belongs to the authenticated company. |
COMPANY_NOT_FOUND | 404 | Company not found | Check that the id exists and belongs to the authenticated company. |
CREDENTIAL_VALUE_REQUIRED | 400 | credentialValue is required | Include the missing field or context in the request. |
CREDIT_PACK_VALIDITY_REQUIRED | 400 | Credit packs require a positive validity period before credits can be issued | Include the missing field or context in the request. |
DATE_REQUIRED | 400 | date is required | Include the missing field or context in the request. |
DEVICE_NOT_AUTHORIZED | 401 | Device not authorized | Check the device key used for the access endpoint. |
EMAIL_REQUIRED | 400 | Email is required | Include the missing field or context in the request. |
ENTRY_AFTER_HABIT_END_DATE | 400 | Entry is after habit end date | Log the entry within the habit’s active date range. |
ENTRY_BEFORE_HABIT_START_DATE | 400 | Entry is before habit start date | Log the entry within the habit’s active date range. |
FIRST_NAME_MAX_50 | 400 | First name cannot be longer than 50 characters. | Send a value that matches the documented format and limits. |
FIRST_NAME_MIN_2 | 400 | First name must be at least 2 characters long. | Send a value that matches the documented format and limits. |
FIRST_NAME_REQUIRED | 400 | First name is required | Include the missing field or context in the request. |
FORM_NOT_FOUND | 400 or 404 | Form not found. | Check that the id exists and belongs to the authenticated company. |
HABIT_CAN_ONLY_BE_LOGGED_ON_SPECIFIC_DAYS | 400 | This habit can only be logged on: {{days}} | Log the entry on one of the habit’s scheduled days. |
HABIT_ENTRY_NOT_FOUND | 404 | Habit Entry not found | Check that the id exists and belongs to the authenticated company. |
HABIT_NOT_FOUND | 404 | Habit not found | Check that the id exists and belongs to the authenticated company. |
INBODY_INSTALLATION_NOT_FOUND | 404 | InBody installation was not found. | Check that the id exists and belongs to the authenticated company. |
INBODY_WEBHOOK_SECRET_INVALID | 401 | InBody webhook secret is invalid. | Send a value that matches the documented format and limits. |
INVALID_CHECKUP_SCHEDULE_TYPE | 400 | Invalid checkup form schedule type | Send a value that matches the documented format and limits. |
INVALID_CHECKUP_SETTING_ID | 400 | Invalid checkup setting id | Send a valid identifier as documented for the endpoint. |
INVALID_COACH_ID | 400 | Invalid coach | Send a valid identifier as documented for the endpoint. |
INVALID_CREDENTIAL_TYPE | 400 | credentialType is not supported | Send a value that matches the documented format and limits. |
INVALID_CURSOR | 400 | Pagination cursor is invalid. | Send a valid identifier as documented for the endpoint. |
INVALID_EMAIL | 400 | Invalid email format | Send a value that matches the documented format and limits. |
INVALID_FORM_ID | 400 | Invalid form id | Send a valid identifier as documented for the endpoint. |
INVALID_HABIT_ENTRY_ID | 400 | Invalid Habit Entry ID | Send a valid identifier as documented for the endpoint. |
INVALID_HABIT_GOAL_PERIOD | 400 | Habit goal period is invalid. | Send a value that matches the documented format and limits. |
INVALID_HABIT_ID | 400 | Invalid Habit ID | Send a valid identifier as documented for the endpoint. |
INVALID_JSON_PAYLOAD | 400 | Invalid JSON payload. | Send a value that matches the documented format and limits. |
INVALID_MEASUREMENT_ENTRY_ID | 400 | Invalid measurementEntryId | Send a valid identifier as documented for the endpoint. |
INVALID_MEASUREMENT_TYPE_ID | 400 | Invalid measurement type id | Send a valid identifier as documented for the endpoint. |
INVALID_MEASUREMENTTYPEID | 400 | Invalid measurementTypeId | Send a value that matches the documented format and limits. |
INVALID_PROGRESS_PHOTO_ID | 400 | Progress photo id is invalid. | Send a valid identifier as documented for the endpoint. |
INVALID_PROGRESS_PHOTO_ORIENTATION | 400 | Progress photo orientation is invalid. | Send a value that matches the documented format and limits. |
INVALID_ROLE_SPECIFIED | 400 | Invalid role specified. Valid roles are: {{roles}} | Send a value that matches the documented format and limits. |
INVALID_UNIT | 400 | Invalid unit | Send a value that matches the documented format and limits. |
INVALID_UNIT_FOR_MEASUREMENT | 400 | Unit {{UNIT}} is not allowed for measurement {{MEASUREMENT}}. Allowed units: {{ALLOWED_UNITS}} | Send a value that matches the documented format and limits. |
LAST_NAME_MAX_50 | 400 | Last name cannot exceed 50 characters | Send a value that matches the documented format and limits. |
MAXIMUM_ALLOWED_VALUE_EXCEEDED | 400 | Maximum allowed value is {{max}} | Send a value that matches the documented format and limits. |
MEASUREMENT_ENTRY_NOT_FOUND | 404 | Measurement entry not found | Check that the id exists and belongs to the authenticated company. |
MEASUREMENT_TYPES_NOT_FOUND | 404 | Measurement types not found | Check that the id exists and belongs to the authenticated company. |
MOBILE_APP_RELEASE_WEBHOOK_UNAUTHORIZED | 401 | Mobile app release webhook is not authorized. | Check the credentials used for this integration. |
NOTE_MAX_LENGTH | 400 | Note cannot exceed {{MAX}} characters | Send a value that matches the documented format and limits. |
NOTHING_TO_UPDATE | 400 | Nothing to update - provide at least one field. | Include at least one updatable field in the request body. |
OCCURRED_AT_INVALID_FORMAT | 400 | occurredAt must be ISO (YYYY-MM-DDTHH:MM:SS.000Z) | Send a value that matches the documented format and limits. |
OCCURRED_AT_REQUIRED | 400 | occurredAt is required | Include the missing field or context in the request. |
PDF_NOT_AVAILABLE | 404 | No PDF is available for this resource. | The invoice has no generated PDF yet. The Public API does not generate missing PDFs on read. |
PROGRESS_PHOTO_NOT_FOUND | 404 | Progress photo was not found. | Check that the id exists and belongs to the authenticated company. |
REASON_REQUIRED | 400 | A reason is required. | Include the missing field or context in the request. |
SCAN_ID_REQUIRED | 400 | scanId is required | Include the missing field or context in the request. |
TAG_NOT_FOUND | 400 or 404 | No tag found with the provided ID. | Check that the id exists and belongs to the authenticated company. |
TV_DASHBOARD_ACTIVE_SESSION_EXISTS | 409 | A TV is already paired. Disconnect it first before pairing a new screen | Disconnect the paired screen before pairing a new one. |
TV_DASHBOARD_SESSION_INVALID | 400 | TV dashboard session is invalid | Send a value that matches the documented format and limits. |
TV_DASHBOARD_SESSION_NOT_FOUND | 404 | TV dashboard session was not found or has expired | Check that the id exists and belongs to the authenticated company. |
VALID_NUMERIC_VALUE_REQUIRED | 400 | Valid numeric value is required | Include the missing field or context in the request. |
VALUE_REQUIRED | 400 | value is required | Include the missing field or context in the request. |
WISHLIST_INTAKE_INVALID_PAYLOAD | 400 | Wishlist intake payload is invalid | Send a value that matches the documented format and limits. |
WISHLIST_INTAKE_ROUTING_CONTEXT_MISSING | 422 | We could not link this wishlist intake item to an internal support ticket. | Contact support; the intake could not be routed internally. |
OAuth token endpoint errors
POST /public/v1/oauth/token does not use the bearer error envelope. It
returns standard OAuth 2.0 (RFC 6749) error responses:
| Error code | HTTP status | Meaning |
|---|---|---|
invalid_request | 400 | The token request is malformed or missing parameters. |
invalid_client | 401 | Unknown client ID or wrong client secret. |
unauthorized_client | 403 | The client is disabled or not allowed to use this grant. |
unsupported_grant_type | 400 | Only client_credentials is supported. |
invalid_scope | 400 | A requested scope is unknown or not granted to this client. |
server_error | 500 | Unexpected error while issuing the token. |