Skip to main content

Errors

The CalendarPipe REST API uses standard HTTP status codes. A 2xx status indicates success; a 4xx indicates a client-side problem you can correct; a 5xx indicates a problem on CalendarPipe or an upstream provider.

Status codes

CodeMeaningWhen you see it
200OKA successful read.
201CreatedA new resource was created — for example, a hosted calendar or event.
204No ContentA successful delete or cancel. The response body is empty.
400Bad RequestThe request payload is missing required fields, malformed, or fails validation.
401UnauthorizedThe Authorization header is missing, the API key is invalid, or the key has been revoked.
402Payment RequiredThe endpoint requires a Pro plan and the account is on Free.
403ForbiddenThe API key is missing a scope this operation requires, or the connected calendar account can no longer write to the calendar.
404Not FoundThe resource does not exist, is not owned by the authenticated account, or names a calendar that is gone.
409ConflictThe request conflicts with the current state of the resource (for example, a duplicate).
422Unprocessable EntityThe request was well-formed but a referenced resource is in a state that cannot satisfy it.
429Too Many RequestsToo many requests in a short window — currently only the invitation send limit.
500Internal Server ErrorSomething failed inside CalendarPipe. Retry; if the error persists, contact support.
502Bad GatewayAn upstream provider (Google, Microsoft, Apple) rejected the request or is unavailable.

Response shape

Every error — every 4xx and every 5xx, with no exceptions — returns the same JSON envelope, described as the ApiError schema in the OpenAPI description:

{
"error": "Bad Request",
"code": "validation_failed",
"message": "Validation failed",
"details": { "start_at": ["must be before end_at"] }
}
FieldDescription
errorA short label matching the HTTP status (Unauthorized, Not Found, etc.). Human-facing.
codeA stable machine-readable cause, from the list below. This is the field to branch on.
messageA human-readable description of what went wrong. Free to change between releases — never match on it.
detailsOptional. Context for this particular failure — the rejected fields, the scope that was missing, a link to the docs.

A successful response never uses this shape. Always check the HTTP status code before parsing the body.

Error codes

code is a closed list. Treat an unfamiliar value as a generic failure of its HTTP status rather than an error — new codes are additive and can appear at any time (see Versioning and deprecation).

codeStatusMeaning
validation_failed400A field failed validation. details maps each rejected field to its reasons.
bad_request400Understood but not actionable as written — often a calendar reference that names an account without naming the calendar.
unauthorized401Missing, invalid, or revoked API key.
api_access_blocked402The account is on the Free plan, which has no API access.
insufficient_scope403The key authenticated but lacks a scope this operation needs.
not_found404No such resource, or it is not owned by this account. The two are deliberately alike.
calendar_not_writable403The connected calendar account can no longer write to the calendar — access was revoked, or the calendar is read-only. Not about the API key; retrying will not help.
calendar_not_found404The target calendar no longer exists on the provider. Retrying will not help.
conflict409The request conflicts with the current state of the resource.
unprocessable_entity422Well-formed, but a referenced resource cannot satisfy it.
rate_limited429Too many requests. Back off and retry.
internal_error500Something failed inside CalendarPipe. Safe to retry.
upstream_error502A calendar provider rejected the request or was unreachable. Usually transient.

Common cases

403 with calendar_not_writable

{
"error": "Forbidden",
"code": "calendar_not_writable",
"message": "The connected calendar account cannot write to this calendar. Reconnect the account or grant it write access."
}

The API key is fine — the calendar connection is not. Either the account lost write access to that calendar, or the calendar is read-only. Reconnect the account on Calendar Connections, or grant it write access at the provider. Retrying without doing one of those returns the same error.

Check the code, not the status: a 403 carrying insufficient_scope is about the API key instead, and is fixed by issuing a key with the missing scope.

401 Unauthorized

{
"error": "Unauthorized",
"code": "unauthorized",
"message": "Missing, invalid, or revoked API key"
}

Check the Authorization header — the value must be Bearer <key> with no extra whitespace, and the key must not have been revoked. See API Keys.

The response also carries WWW-Authenticate: Bearer resource_metadata="https://www.calendarpipe.com/.well-known/oauth-protected-resource/api/v1". That document (RFC 9728) lists every scope a key can hold, so a client that guessed wrong can discover what to ask for.

402 Payment Required

Returned when an account on the Free plan calls a Pro-only endpoint:

{
"error": "Payment Required",
"code": "api_access_blocked",
"message": "Public API is not available on the Free plan. Upgrade to Pro for API access.",
"details": {
"documentation": "https://docs.calendarpipe.com/account/billing-and-plans"
}
}

Upgrade the account on the Billing page to clear the error.

403 Forbidden

Returned when the key is valid but was not granted a scope the operation needs:

{
"error": "Forbidden",
"code": "insufficient_scope",
"message": "This API key is missing the \"events:write\" scope.",
"details": {
"required_scope": "events:write",
"documentation": "https://docs.calendarpipe.com/developers/api-keys"
}
}

The response also carries WWW-Authenticate: Bearer error="insufficient_scope", scope="events:write". Scopes are fixed at creation, so generate a key with the scope named in details.required_scope and revoke the old one. See API Keys.

502 Bad Gateway

CalendarPipe could not reach the upstream provider (Google Calendar, Microsoft Graph, iCloud). The original error message is forwarded in message to help diagnose. These are usually transient — retry after a short delay.

Retries

5xx responses are safe to retry. 4xx responses indicate a problem with your request and will keep failing until the request changes. Use exponential backoff for retries to avoid amplifying transient issues.

Unknown endpoints

A path under /api/v1 that no operation implements returns a JSON 404 rather than an HTML page, so a client parser never has to deal with markup:

{
"error": "Not Found",
"code": "not_found",
"message": "No such endpoint. See the OpenAPI description for the operations this API implements.",
"details": {
"openapi": "https://www.calendarpipe.com/openapi.json",
"documentation": "https://docs.calendarpipe.com/api"
}
}