I'mBoardDocs
Getting Started

Errors

All errors follow a consistent envelope format with machine-readable codes.

All errors follow a consistent envelope format with machine-readable codes.

Error Envelope

Every error response returns the same shape:

{
  "error": {
    "code": "ERROR_CODE",
    "message": "Human-readable description.",
    "status": 400,
    "requestId": "req_a1b2c3d4e5f6a7b8",
    "details": null
  }
}
FieldTypeDescription
codestringMachine-readable error code (see table below)
messagestringHuman-readable description of the error
statusintegerHTTP status code
requestIdstring or nullUnique request identifier for tracing
detailsobject or nullStructured details when available (e.g., field-level validation errors)

Error Codes

CodeHTTP StatusDescription
UNAUTHENTICATED401No token provided or token format invalid
INVALID_API_TOKEN401Token expired, revoked, or not found
ACCOUNT_SUSPENDED403Account suspended by an administrator
ACCOUNT_INACTIVE403Account is inactive
BILLING_RESTRICTED403Billing issue restricts access
FORBIDDEN403Insufficient permissions for this resource
RESOURCE_NOT_FOUND404Resource does not exist or is not accessible
CONFLICT409The request conflicts with the current state of the resource — for example, proposing a meeting time slot that already exists. On the slot endpoints, a 409's details.reason (SLOT_VOTES_CLOSED, SLOT_IS_PROMOTED, MEETING_FINALIZED) marks the conflict non-retryable — the meeting stopped collecting slot votes, the slot backs the booked meeting time, or the meeting is finalized; do not re-send the same request. updateMeeting returns the same non-retryable shape with details.reason: SLOT_POLL_OPEN — startTime was set on a meeting with no booked time that is still collecting slot votes with open proposed slots; book via a proposed slot's confirm endpoint or remove the slots first (#3937) — or with details.reason: PROMOTE_NEEDS_TIME — a forward status move into scheduled was attempted while no start time was booked; set a time first (#3849)
INVALID_REQUEST_BODY400Request body failed validation
INVALID_QUERY_PARAMETER400One or more query parameters are invalid
UNPROCESSABLE_ENTITY422The body parsed and typed fine, but the request cannot be applied to the resource in its current state — a referenced record that does not belong to this board, or a collection bound that would be exceeded. On the committee roster endpoints: a boardUserId that is not a member of the board, or an add that would exceed the 100-member committee cap. Distinct from INVALID_REQUEST_BODY (the body itself is malformed) and from CONFLICT (a concurrent write)
METHOD_NOT_ALLOWED405HTTP method not supported for this endpoint
PAYLOAD_TOO_LARGE413Uploaded file exceeds the size limit
RATE_LIMITED429Too many requests — slow down
INTERNAL_ERROR500Unexpected server error
SERVICE_UNAVAILABLE503Service temporarily unavailable — retry later

Validation Errors

When a request fails validation, the details field may contain structured information about which fields failed:

{
  "error": {
    "code": "INVALID_QUERY_PARAMETER",
    "message": "One or more query parameters are invalid.",
    "status": 400,
    "requestId": "req_a1b2c3d4e5f6a7b8",
    "details": {
      "fields": {
        "limit": "Must be an integer between 1 and 100",
        "sort": "Invalid sort field. Allowed: createdAt, updatedAt"
      }
    }
  }
}

Rate Limiting

The API enforces rate limits per 5-minute sliding window:

ContextLimitKey
Authenticated (API token)300 requests / 5 minutesPer token
Unauthenticated60 requests / 5 minutesPer IP address

Rate Limit Headers

Every response includes rate limit headers so you can track your usage:

HeaderDescription
X-RateLimit-LimitMaximum requests allowed in the current window
X-RateLimit-RemainingRequests remaining in the current window
X-RateLimit-ResetUnix timestamp (seconds) when the window resets
Retry-AfterSeconds to wait before retrying (only on 429 responses)

Rate Limit Example

When you exceed the limit, the API returns 429:

{
  "error": {
    "code": "RATE_LIMITED",
    "message": "Too many requests. Please try again later.",
    "status": 429,
    "requestId": "req_x9y8z7w6v5u4t3s2",
    "details": null
  }
}

Best practices:

  1. Check X-RateLimit-Remaining before making requests
  2. When you receive a 429, wait for the number of seconds in the Retry-After header
  3. Implement exponential backoff for retry logic

Troubleshooting

401 Errors

  1. Verify the Authorization header format: Bearer imb_pat_...
  2. Check that the token has not expired or been revoked
  3. Confirm the token exists in Account > API Access

403 Errors

  1. Verify the authenticated user has access to the target board
  2. Check billing status if you see BILLING_RESTRICTED
  3. ACCOUNT_SUSPENDED and ACCOUNT_INACTIVE indicate account-level issues — contact support

404 Errors

  1. Verify the resource ID is correct
  2. Confirm the authenticated user has access to the parent board
  3. The API returns 404 (not 403) for resources the user cannot access — this prevents leaking resource existence

429 Errors

  1. Read the Retry-After header and wait before retrying
  2. Check X-RateLimit-Reset to know when your window resets
  3. Reduce request frequency or implement request batching where possible

On this page