Errors & status codes
HTTP status codes returned by the Dailybot public API, machine-readable error codes, and how to recover.
The Dailybot API returns standard HTTP status codes on every response. Successful responses fall in the 2xx range; client errors in 4xx; server errors in 5xx. Every error body follows the same shape: a top-level detail string, a machine-readable code, and optional per-field validation errors under errors.
Error response envelope
Every non-2xx response is a JSON object with at minimum a detail and code field. Validation errors (400 responses on write endpoints) additionally include a per-field errors map. Rate limits (429) return a Retry-After header alongside the JSON body.
{
"detail": "Human-readable explanation",
"code": "machine_readable_code"
}
Some errors include additional fields:
upgrade_url— present onplan_upgrade_requiredresponses, linking directly to the billing upgrade pageRetry-Afterheader — present on429responses, indicating seconds until the limit resets
Always dispatch on
code, notdetail. Thedetailstring is for humans; it may change. Thecodevalues are frozen — see Machine-readable error codes below.
Status codes returned by the public API
| Status | When you get it | How to recover |
|---|---|---|
| 200 OK | Successful GET, PATCH, or a POST that returns the resource. | Nothing to do — success. |
| 201 Created | Successful POST that creates a new resource. | The resource is in the response body; note the uuid. |
| 202 Accepted | Request was accepted for async processing (send-message, send-email, workflow trigger). | Poll or subscribe to a webhook to know when it completes. |
| 204 No Content | Successful DELETE or PATCH where no body is returned. | No body to parse; success. |
| 400 Bad Request | Validation error. The errors field contains per-field messages. Check code for specifics. |
Fix the payload and retry. Never retry blindly. |
| 401 Unauthorized | Missing, expired, or invalid credential. | Confirm your API key or refresh your CLI Bearer session with dailybot login. |
| 403 Forbidden | Credential is valid but the caller lacks permission. Plan/auth 403s carry a stable code — see machine codes. |
Check the code field and the auth method matrix. |
| 404 Not Found | Resource does not exist, or the caller cannot see it in this organization. | Verify the UUID and the scope of the credential. |
| 409 Conflict | The write conflicts with the current state (e.g. transitioning a form response to an invalid workflow state). | Re-read the resource, choose the correct next state, retry. |
| 422 Unprocessable Entity | The payload is syntactically valid but semantically invalid. | Read detail — the message identifies the offending field. |
| 429 Too Many Requests | Rate limit exceeded. | Respect the Retry-After header. See /developers/rate-limits. |
| 500 Internal Server Error | Unexpected error on the Dailybot side. | Retry with exponential backoff. If it persists, contact support. |
| 502 / 503 / 504 | Upstream outage or maintenance window. | Retry with exponential backoff. |
Plan API (Beta)
The Plan API is in Beta. Until your organization is enabled, every Plan endpoint answers 402 plan_upgrade_required: that is expected, so write to [email protected] to join. 503 feature_temporarily_read_only is different: Plan is temporarily read-only during an incident and reads keep working. Every Plan code, with what to do next, is in Errors for Plan.
Retry policy
Retry only on 429, 502, 503, 504, and idempotent 5xx. Never retry a 4xx blindly — the error is on your side. For 429, honor Retry-After; for 5xx, use exponential backoff (start at 250 ms, cap at 30 s, add jitter).
Machine-readable error codes
Every plan-gate, capability-gate, and rate-limit response carries a stable code field alongside the human-readable detail. Integrations should dispatch on code, never parse the prose.
Stability guarantee: The
codevalues listed here are frozen — existing values will never change meaning or be reused. New codes may be added in future API updates, but none of the codes below will ever change.
Auth & plan gate codes
code |
HTTP | When you get it |
|---|---|---|
invalid_credentials |
403 | Credentials supplied but don’t resolve to a valid key or token |
api_key_owner_inactive |
403 | The API key’s owner user is deactivated |
plan_free_api_keys_forbidden |
403 | The API key’s organization is on a free plan |
plan_missing_core_api_integrations |
403 | The org’s plan doesn’t include API access |
plan_upgrade_required |
403 | Free-plan CLI Bearer token hit a non-allowlisted endpoint |
free_plan_daily_limit_exceeded |
429 | Free-plan daily rate limit reached for this endpoint |
org_admin_required |
403 | The action requires organization admin role |
member_in_scope_required |
403 | Target user is not in the same organization |
API key management codes
code |
HTTP | When you get it |
|---|---|---|
agent_key_admin_only |
400 | Non-admin tried to create an agent key |
target_user_inactive |
400 | Target user for key creation is deactivated |
target_user_not_found |
400 | Target user UUID not found in the organization |
Messaging codes
code |
HTTP | When you get it |
|---|---|---|
send_as_user_conflict |
400 | send_as_user combined with bot_username, bot_icon_url, or bot_icon_emoji |
send_as_user_invalid_uuid |
400 | Invalid UUID format in send_as_user |
send_as_user_not_found |
400 | User not found, inactive, or in a different org for send_as_user |
cli_send_message_target_not_allowed |
403 | CLI caller tried to send a message to an out-of-scope target |
Filter & query codes
code |
HTTP | When you get it |
|---|---|---|
search_query_too_long |
400 | ?search= exceeds 256 characters. Applies uniformly to /v1/forms/, /v1/checkins/, /v1/forms/{uuid}/responses/, /v1/checkins/{uuid}/responses/, /v1/kudos/, /v1/workflows/, /v1/users/. |
invalid_date_range |
400 | ?start_date or ?end_date is not a valid YYYY-MM-DD date, or start_date > end_date. Applies to every endpoint accepting start_date / end_date. |
invalid_user_identifier |
400 | ?user= is not a valid UUID. Use the user’s UUID from GET /v1/users/. Applies to /v1/checkins/{uuid}/responses/ and /v1/forms/{uuid}/responses/. |
not_valid_kudos_filter |
400 | Deprecated alias — use invalid_kudos_filter. |
invalid_kudos_filter |
400 | ?filter= is not one of kudos_received / kudos_given (case-insensitive). Applies to /v1/kudos/ and /v1/kudos/organization/. |
invalid_sender_uuid |
400 | ?sender_uuid= is not a valid UUID. Applies to /v1/kudos/ and /v1/kudos/organization/. |
invalid_receiver_uuid |
400 | ?receiver_uuid= is not a valid UUID. Applies to /v1/kudos/ and /v1/kudos/organization/. |
invalid_workflow_state |
400 | ?state= is not a valid workflow state for the form. Applies to /v1/forms/{uuid}/responses/. |
form_response_view_all_forbidden |
403 | Member used ?all=true on a form they are not allowed to view all responses for. |
JSON error responses: Every
/v1/**error response is guaranteed to beapplication/json— the API never returns HTML error pages for client-input validation failures.
Authoring codes (forms & check-ins)
code |
HTTP | When you get it |
|---|---|---|
unknown_field |
400 | Request body contains an unrecognized key on config endpoints |
questions_required |
400 | Create called without at least one question |
short_question_required |
400 | Question missing short_question without generate_short_question |
checkin_requires_participant |
400 | Check-in create/config with zero participants |
anonymous_irreversible |
400 | Attempt to disable anonymity on an anonymous check-in |
report_channel_not_found |
400 | report_channels contains an ID not returned by GET /v1/report-channels/ |
too_many_report_channels |
400 | More than 3 report channels provided |
question_uuids_incomplete |
400 | Reorder request missing one or more question UUIDs |
Labels & personalization codes
code |
HTTP | When you get it |
|---|---|---|
feature_not_available |
403 | Labels feature is not enabled for the organization (or equivalent Labels gate) |
guest_not_allowed |
403 | Guest caller attempted a Labels endpoint or assignment |
archived_label |
400 | Attempted to newly assign an archived label |
label_in_use |
409 | Hard-delete of a label that still has attachments |
label_limit_exceeded |
400 | Assign/batch would exceed the per-entity Label attachment limit |
invalid_color |
400 | Label create/PATCH color is not a valid hex color |
duplicate_name |
409 | Label name collides with an existing org label, or a saved-view name already exists on the same surface |
invalid_preference_payload |
400 | Missing/invalid Featured entity_type, unsupported saved-view/preference surface, or invalid preference/saved-view body |
not_found |
404 | Unknown label, entity, or Featured target UUID |
invalid_featured_request |
400 | Unsupported Featured entity_type or invalid Featured body |
dashboard_enrichment_temporarily_unavailable |
503 | Labels/Featured list enrichment temporarily unavailable; retry without enrichment params per retry policy |
labels_feature_unavailable |
— | Response warning (not an error envelope): preference/saved-view reads omit Label filters when Labels are unavailable |
Admin-only endpoints
Non-admin members receive 403 with code: "org_admin_required" on these endpoints:
| Endpoint | Methods |
|---|---|
/v1/kudos/organization/ |
GET |
/v1/webhook-subscription/ |
POST, DELETE |
/v1/webhook-subscription/sample/ |
POST |
/v1/open-conversation/ |
POST |
/v1/teams/{uuid}/members/{uuid}/ |
GET, PUT, PATCH, DELETE |
/v1/teams/{uuid}/invite/ |
POST |
/v1/followups/ |
POST (create only) |