Skip to content
Preview. The endpoints on this page are illustrative and are likely to change as they move toward general availability. Documentation is published in advance so you can start shaping your integration; treat request and response details as subject to revision.

Errors

All Platform API errors follow RFC 7807 problem-details. Responses carry Content-Type: application/problem+json and a JSON body with at minimum:

json
{
  "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

StatusMeaning
400Request body or query parameters failed schema validation
401Token missing, expired, or revoked
403Token does not include the required scope for this operation
404Resource does not exist, or is not visible to the calling org
409Conflict (most often: selected slot no longer available, or a meeting can't be rescheduled from its current state)
410The referenced resource is gone (slot token expired, meeting already completed)
422Semantic validation failure — request was well-formed but the values didn't satisfy the schedule / model rules
429Rate limit or quota exceeded
5xxServer-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.

json
{
  "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"
}
json
{
  "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 org
  • meeting-not-found — no scheduled meeting with that id in your org
  • webhook-subscription-not-found — no webhook subscription with that id in your org
  • transcript-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 it
  • account-not-found — no account with that id in your org
  • contact-not-found — no contact with that id in your org
  • deal-not-found — no deal with that id in your org
  • insight-record-not-found — no 8P record for that (dealId, schemaType) pair or that insightId
  • qna-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.

json
{
  "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.

json
{
  "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.

json
{
  "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
openanswered, dismissed
answeredopen, dismissed
dismissedopen

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.

json
{
  "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.

json
{
  "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.

json
{
  "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
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."
}
json
{
  "type": "https://docs.cirrusinsight.com/platform-api/errors/internal",
  "title": "Internal server error",
  "status": 500,
  "requestId": "00-4bf92f3577b34da6a3ce929d0e0e4736-00f067aa0ba902b7-01"
}
CodeAction
400Fix the request — never retry as-is
401Surface to the operator to rotate the token; do not retry
403Surface to the operator to update token scopes; do not retry
404Verify the resource ID is correct and belongs to your org; do not retry
409 slot-conflictRe-call /availability and pick a new slot
409 meeting-not-reschedulableFetch the meeting and act on its current state — do not retry
410 slot-token-expiredRe-call /availability
410 meeting-completedDo not retry — the meeting is already historical
422 slot-token-invalidDo not retry the same token — re-call /availability
422 form-validationFix the form values based on fieldErrors
422 idempotency-key-conflictUse a fresh Idempotency-Key if the request body genuinely changed
422 schedule-mismatchChoose a slot from the correct schedule — cross-schedule reschedule is not supported
429Sleep for Retry-After seconds, then retry
5xxExponential backoff, up to ~5 attempts

Raleigh, NC — a Cirruspath, Inc. company