Errors
All Platform API errors follow RFC 7807 problem-details. Responses carry Content-Type: application/problem+json and a JSON body with at minimum:
{
"type": "https://docs.cirrusinsight.com/platform-api/errors/<error-name>",
"title": "Human-readable summary",
"status": 4xx-or-5xx,
"detail": "Specific cause for this request"
}Individual error types may include additional fields documented below.
HTTP status codes
| Status | Meaning |
|---|---|
400 | Request body or query parameters failed schema validation |
401 | Token missing, expired, or revoked |
403 | Token does not include the required scope for this operation |
404 | Resource does not exist, or is not visible to the calling org |
409 | Conflict (most often: selected slot no longer available, or a meeting can't be rescheduled from its current state) |
410 | The referenced resource is gone (slot token expired, meeting already completed) |
422 | Semantic validation failure — request was well-formed but the values didn't satisfy the schedule / model rules |
429 | Rate limit or quota exceeded |
5xx | Server-side error — safe to retry with exponential backoff |
Authentication and authorization
missing-trust-header 401
The request reached the backend without a valid token. Almost always means the request bypassed the API gateway — check that you're sending X-Cirrus-Api-Key: ci_live_... and hitting altus.cirrusinsight.com.
unknown-subscription 401
The token was present but does not correspond to a known API token. The most likely cause is a revoked or deleted token.
subscription-expired 401
The token's expiration date has passed. Issue a new token from the developer dashboard.
insufficient-scope 403
The token is valid but does not carry the scope this endpoint requires. The requiredScope field tells you which scope to add.
{
"type": "https://docs.cirrusinsight.com/platform-api/errors/subscription-expired",
"title": "API token expired",
"status": 401,
"detail": "This API token expired at 2026-09-01T00:00:00Z.",
"expiredAt": "2026-09-01T00:00:00Z"
}{
"type": "https://docs.cirrusinsight.com/platform-api/errors/insufficient-scope",
"title": "Insufficient scope",
"status": 403,
"detail": "This token does not include the required scope 'smart-scheduling:write'.",
"requiredScope": "smart-scheduling:write"
}Not-found errors
Every 404 uses a domain-specific type so callers can distinguish "wrong id" from "wrong resource type."
schedule-not-found— no Smart Schedule with that id in your orgmeeting-not-found— no scheduled meeting with that id in your orgwebhook-subscription-not-found— no webhook subscription with that id in your orgtranscript-not-available— meeting exists but has no transcript (no bot was configured, or the bot didn't record)bot-not-configured— meeting exists but never had a recording bot scheduled for itaccount-not-found— no account with that id in your orgcontact-not-found— no contact with that id in your orgdeal-not-found— no deal with that id in your orginsight-record-not-found— no 8P record for that(dealId, schemaType)pair or thatinsightIdqna-item-not-found— no Q&A item with that id in your org
A cross-org id (i.e., a valid id that belongs to another organization) also returns the same 404 error type — the API never leaks the existence of resources you don't own.
Request validation
invalid-resource-id 400
A path parameter that should be a resource id doesn't decode to one. Usually a typo or a stale id from an old system.
invalid-cursor 400
The pagination cursor is malformed, tampered with, or was issued for a different sort order than the one this request is using. Cursors carry the sort field and direction they were minted under; replaying a cursor against a different sort would compare the wrong key and let a caller walk past the keyset boundary, so this is rejected rather than silently re-paginating.
invalid-sort-field 400
The sort query parameter names a field that isn't in the endpoint's allowlist. The response includes an allowedSortFields array so callers can correct themselves without reading docs.
idempotency-key-required 400
An endpoint that requires Idempotency-Key (booking, reschedule) was called without one.
idempotency-key-conflict 422
The same Idempotency-Key was reused within the 24-hour window with a different request body. Prevents accidental reuse of a key across semantically-different requests.
{
"type": "https://docs.cirrusinsight.com/platform-api/errors/invalid-sort-field",
"title": "Sort field not allowed",
"status": 400,
"detail": "Sort field 'foo' is not allowed on this endpoint.",
"field": "foo",
"allowedSortFields": ["updatedAt", "createdAt", "name"]
}Slot token errors
Slot tokens are issued by POST /smart-schedules/{id}/availability and consumed by POST /scheduled-meetings and PATCH /scheduled-meetings/{id}.
slot-conflict 409
The slot was valid when issued but is no longer bookable — typically because the host's calendar changed between the /availability call and the booking. The rerunAvailability field signals that the caller should refresh availability and pick a new slot.
slot-token-expired 410
Slot tokens are valid for 10 minutes from issue. After that window, call /availability again to get fresh tokens.
slot-token-invalid 422
The token's signature failed verification, or its payload doesn't match the request context (wrong schedule id on the path, wrong meeting on a reschedule, etc.). Do not retry — the token cannot be repaired. Call /availability again.
{
"type": "https://docs.cirrusinsight.com/platform-api/errors/slot-conflict",
"title": "Slot is no longer available",
"status": 409,
"detail": "The selected slot conflicts with the host's calendar.",
"rerunAvailability": true
}Booking-time validation
availability-request-invalid 422
The /availability request body was malformed, or durationMinutes doesn't match one of the schedule's configured booking periods.
form-validation 422
The submitted formValues failed the schedule's matching-form validation — a required field is missing, a value is outside the allowed option list, or (on booking) the values differ from those used to issue the slot token. The fieldErrors array names each offending field.
booking-validation-failed 422
The booking passed schema and form validation but was rejected downstream — for example, an unknown survey key. Response body carries a detail explaining which check failed.
schedule-unavailable 422
The schedule is currently disabled or otherwise not accepting bookings, even though it's visible in list responses.
{
"type": "https://docs.cirrusinsight.com/platform-api/errors/form-validation",
"title": "Form values failed validation",
"status": 422,
"detail": "One or more form values did not satisfy the schedule's validation rules.",
"fieldErrors": [
{ "field": "region", "message": "Required field is missing" },
{ "field": "companySize", "message": "Value 'Enterprise' is not in the allowed list" }
]
}Meeting state errors
meeting-not-reschedulable 409
PATCH /scheduled-meetings/{id} on a meeting that has already been canceled or has passed its end time.
schedule-mismatch 422
PATCH /scheduled-meetings/{id} with a slot token whose scheduleId differs from the meeting's schedule. Cross-schedule reschedules are not supported in v1 — cancel and rebook.
meeting-completed 410
DELETE /scheduled-meetings/{id} on a meeting whose end time has already passed. Completed meetings cannot be canceled retroactively — cancellation would misrepresent the historical record.
Webhook subscription errors
webhook-endpoint-invalid 422
POST /webhook-subscriptions with an endpointUrl that isn't HTTPS, or that targets localhost / an RFC1918 private address.
webhook-events-invalid 422
POST /webhook-subscriptions with an empty events list, or with events that aren't in the v1alpha1 catalog.
webhook-limit-reached 422
Your org has reached the maximum number of webhook subscriptions (10 in v1). Delete an existing one to make room.
Transcript errors
transcript-window-invalid 422
GET /scheduled-meetings/{id}/transcript with startTime > endTime, or endTime past the meeting's durationSeconds. Both bounds are in seconds from meeting start.
transcript-expired 410
The transcript is older than the retention window (12 months from meeting end). Not recoverable — plan to fetch and store what matters to your integration within the retention window.
Cortex errors
schema-mismatch 422
POST /deals or PATCH /deals/{id} with customFields that don't match the deal's schema — an unknown key, a value with the wrong type, or a required field missing on create.
source-ref-conflict 422
POST /deals where another deal in your org already references the same (sourceType, sourceId) pair — for example, two attempts to create a Cirrus deal from the same Salesforce opportunity id. Distinct from idempotency-key-conflict (which is about client-supplied replay keys); this is about the underlying record layer catching duplicates.
deal-closed 409
PATCH /deals/{id} on a deal that's already in a terminal stage (Won or Lost). Closed deals are immutable via API in v1alpha1.
invalid-schema-type 400
A 8P endpoint (/deals/{id}/insights/{schemaType}) called with a schemaType that isn't one of profile, problem, pain, power, position, phases, process, plan.
insight-field-invalid 422
Appending an insight to a field that isn't in the 8P record's schema, or whose value doesn't match the schema field's type.
qna-shape-invalid 422
Creating a Q&A missing the direction-specific required fields — a Discovery Q&A without linkedInsight, or an RFI Q&A without contactId.
qna-transition-invalid 409
State transition not allowed from the item's current state. The response body includes currentState so a racing caller can recover:
Allowed transitions:
| From | → allowed target states |
|---|---|
open | answered, dismissed |
answered | open, dismissed |
dismissed | open |
answer-source-invalid 422
Attaching an answer with a source.type that requires additional fields but doesn't include them — e.g., type: "meeting" without a meetingId, or type: "grounding-doc" without a documentId.
{
"type": "https://docs.cirrusinsight.com/platform-api/errors/qna-transition-invalid",
"title": "Q&A transition not allowed",
"status": 409,
"detail": "Cannot transition to 'dismissed' from current state 'dismissed'.",
"currentState": "dismissed"
}Identity errors
user-not-found 404
The referenced user id is unknown, or belongs to a different org. Cross-org access never leaks — the response is identical whether the id doesn't exist or exists in another org.
organization-not-found 404
The referenced org id doesn't equal the token's org context. Attempting to fetch or patch an unrelated org returns this — same as user-not-found, existence is never leaked.
invalid-role 400
The requested role value isn't one of User, Admin, Partner Admin, or Partner Admin was requested on a non-partner-admin organization.
last-administrator 422
The mutation would remove Admin from the organization's last remaining Admin. Assign Admin to another user first, then retry.
administrator-transfer-required 422
Attempted to deactivate the org's contractual owner without first transferring ownership. Ownership transfer is a two-step confirmation flow in the dashboard; it isn't exposed on the API in v1alpha1.
seat-limit-exceeded 403
Invite would push active users + pending invites past the org's seats.total. Response includes:
Preflight seat availability via GET /organizations/me/entitlements.
email-already-in-use 409
Invite attempted for an email that already belongs to an active or pending user in the org. Response includes the existing usr_... id so partners can render "this person is already on your team" instead of surfacing a raw error.
email-domain-not-verified 400
PATCH /organizations/{orgId} attempted to set primaryEmailDomain to a value that isn't in the org's verified emailDomains[]. Adding new domains requires DNS verification (dashboard-only flow).
token-not-org-scoped 401
Reserved for future auth models. All v1alpha1 tokens are org-scoped, so this error is never emitted today. When per-user OAuth ships, a request that hits an org-scoped endpoint with a user-scoped token (no X-Cirrus-Org-Id context) will return this error.
{
"type": "https://docs.cirrusinsight.com/platform-api/errors/seat-limit-exceeded",
"title": "Seat limit exceeded",
"status": 403,
"detail": "Adding this user would exceed the organization's seat limit.",
"seatLimit": 25,
"remainingSeats": 0
}Partner delegation errors
Returned when using the X-Cirrus-Acting-On header to act on a child organization. See Partner Delegation for the full contract.
delegation-scope-required 403
The request sent X-Cirrus-Acting-On but the token doesn't hold the partner:act-as-child scope. Contact your organization's admin to reissue the token with the scope, or drop the header if the request should target your own org.
invalid-acting-on-org 400
The X-Cirrus-Acting-On header value isn't a valid org_... id — empty, malformed, or the wrong prefix.
cross-org-delegation-forbidden 403
The target org isn't a child of your token's org. This is returned uniformly whether:
- The child id doesn't exist
- The id belongs to an org that isn't yours
- The parent-child relationship has been revoked
Existence is never leaked. If you're sure the relationship exists and this is a bug, contact support with the request id.
delegation-scope-insufficient 403
Your token holds the scope required for this operation, but the child hasn't granted your parent org that scope. Response includes the granted subset:
Enumerate per-child grants via GET /partner/managed-organizations.
{
"type": "https://docs.cirrusinsight.com/platform-api/errors/delegation-scope-insufficient",
"title": "Delegation scope insufficient",
"status": 403,
"detail": "The child organization has not granted this parent 'users:write'.",
"requiredScope": "users:write",
"grantedScopes": ["users:read"]
}Infrastructure
rate-limit-exceeded 429
The token has exceeded a rate-limit bucket or its daily quota. Response includes a Retry-After header with the number of seconds to wait. See rate limits for the per-operation limits.
method-not-allowed 405
The path exists but the HTTP method is not supported. Check the endpoint documentation.
unsupported-media-type 415
A Content-Type other than application/json was sent on a request that requires JSON.
not-implemented 501
The route matched an endpoint that is announced in the OpenAPI spec but is not yet available in this release channel. Typically only appears during rolling deploys of a new capability.
internal 5xx
Server-side error. Safe to retry with exponential backoff (start at 1s, double up to 30s, give up after ~5 attempts). Includes a requestId field — provide it when contacting support.
HTTP/1.1 429 Too Many Requests
Retry-After: 23
Content-Type: application/problem+json{
"type": "https://docs.cirrusinsight.com/platform-api/errors/rate-limit-exceeded",
"title": "Rate limit exceeded",
"status": 429,
"detail": "Too many requests. Retry after 23 seconds."
}{
"type": "https://docs.cirrusinsight.com/platform-api/errors/internal",
"title": "Internal server error",
"status": 500,
"requestId": "00-4bf92f3577b34da6a3ce929d0e0e4736-00f067aa0ba902b7-01"
}Recommended client behavior
| Code | Action |
|---|---|
400 | Fix the request — never retry as-is |
401 | Surface to the operator to rotate the token; do not retry |
403 | Surface to the operator to update token scopes; do not retry |
404 | Verify the resource ID is correct and belongs to your org; do not retry |
409 slot-conflict | Re-call /availability and pick a new slot |
409 meeting-not-reschedulable | Fetch the meeting and act on its current state — do not retry |
410 slot-token-expired | Re-call /availability |
410 meeting-completed | Do not retry — the meeting is already historical |
422 slot-token-invalid | Do not retry the same token — re-call /availability |
422 form-validation | Fix the form values based on fieldErrors |
422 idempotency-key-conflict | Use a fresh Idempotency-Key if the request body genuinely changed |
422 schedule-mismatch | Choose a slot from the correct schedule — cross-schedule reschedule is not supported |
429 | Sleep for Retry-After seconds, then retry |
5xx | Exponential backoff, up to ~5 attempts |