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
| Code | Meaning | When you see it |
|---|---|---|
200 | OK | A successful read. |
201 | Created | A new resource was created — for example, a hosted calendar or event. |
204 | No Content | A successful delete or cancel. The response body is empty. |
400 | Bad Request | The request payload is missing required fields, malformed, or fails validation. |
401 | Unauthorized | The Authorization header is missing, the API key is invalid, or the key has been revoked. |
402 | Payment Required | The endpoint requires a Pro plan and the account is on Free. |
403 | Forbidden | The API key is missing a scope this operation requires, or the connected calendar account can no longer write to the calendar. |
404 | Not Found | The resource does not exist, is not owned by the authenticated account, or names a calendar that is gone. |
409 | Conflict | The request conflicts with the current state of the resource (for example, a duplicate). |
422 | Unprocessable Entity | The request was well-formed but a referenced resource is in a state that cannot satisfy it. |
429 | Too Many Requests | Too many requests in a short window — currently only the invitation send limit. |
500 | Internal Server Error | Something failed inside CalendarPipe. Retry; if the error persists, contact support. |
502 | Bad Gateway | An 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"] }
}
| Field | Description |
|---|---|
error | A short label matching the HTTP status (Unauthorized, Not Found, etc.). Human-facing. |
code | A stable machine-readable cause, from the list below. This is the field to branch on. |
message | A human-readable description of what went wrong. Free to change between releases — never match on it. |
details | Optional. 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).
code | Status | Meaning |
|---|---|---|
validation_failed | 400 | A field failed validation. details maps each rejected field to its reasons. |
bad_request | 400 | Understood but not actionable as written — often a calendar reference that names an account without naming the calendar. |
unauthorized | 401 | Missing, invalid, or revoked API key. |
api_access_blocked | 402 | The account is on the Free plan, which has no API access. |
insufficient_scope | 403 | The key authenticated but lacks a scope this operation needs. |
not_found | 404 | No such resource, or it is not owned by this account. The two are deliberately alike. |
calendar_not_writable | 403 | The 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_found | 404 | The target calendar no longer exists on the provider. Retrying will not help. |
conflict | 409 | The request conflicts with the current state of the resource. |
unprocessable_entity | 422 | Well-formed, but a referenced resource cannot satisfy it. |
rate_limited | 429 | Too many requests. Back off and retry. |
internal_error | 500 | Something failed inside CalendarPipe. Safe to retry. |
upstream_error | 502 | A 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"
}
}
Related
- API Keys — authentication and the
Authorizationheader. - API Reference — per-endpoint request and response details.
- Versioning and deprecation — what can change, and with how much notice.