The Cirro API uses conventional HTTP response codes to indicate the success or failure of an API request. In general, codes in the 2xx range indicate success, codes in the 4xx range indicate an error that failed given the information provided (e.g., a required parameter was omitted, etc.), and codes in the 5xx range indicate an error with Cirro's servers (these are rare).
The body of any error response will be a JSON object with a single error key containing a human-readable message:
HTTP status codes
| Status | Meaning |
|---|
200 - OK | The request succeeded. |
201 - Created | The resource was successfully created. |
208 - Already Reported | A request with the same idempotency key was already processed. The original response is returned. |
400 - Bad Request | The request was invalid, often due to missing or invalid parameters. |
401 - Unauthorized | The access token is missing, expired, or invalid. |
403 - Forbidden | The request is not allowed. The authenticated app does not have permission to perform the action. |
404 - Not Found | The requested resource does not exist or does not belong to your space. |
422 - Unprocessable Entity | The request was well-formed but could not be processed due to semantic errors (e.g., validation failures, invalid state transitions, duplicate entries). |
500 - Internal Server Error | Something went wrong on Cirro's end (these are rare). |
Authentication errors
Authentication errors return a 401 status code. These occur when the JWT access token is missing, malformed, or expired.
| Error message | Description |
|---|
Access token is missing | No authorization token was provided in the request header. |
Access token is expired | The JWT token has passed its expiration time. |
Can not maintain an access token for longer than 10 min | The token's exp claim is set more than 10 minutes in the future. |
Can not verify the access token | The token signature does not match the expected key. |
Access token can not be decoded | The token is malformed and cannot be parsed. |
No space found for the token subject | The sub claim does not match a valid app ID. |
No user found for the token owner | The token's resource owner could not be found. |
Access Denied | The authenticated token does not have the required permissions. |
Validation errors
Validation errors return a 400 or 422 status code. A 400 is returned when required parameters are missing or have invalid formats. A 422 is returned when the parameters are well-formed but fail domain-level validation (e.g., a record is invalid or a state transition is not allowed).
Common validation error scenarios:
| Error message | Status | Description |
|---|
<param> is missing | 400 | A required parameter was not provided. |
<param> does not have a valid value | 400 | A parameter value is not in the allowed set. |
Duplicate entry | 422 | A uniqueness constraint was violated (e.g., creating a duplicate record). |
Validation failed: <details> | 422 | An ActiveRecord validation failed. The message includes specific field errors. |
<event> cannot transition | 422 | A state transition was attempted that is not allowed from the current state. |
Resource-specific errors
Users
| Error message | Status | Description |
|---|
Can not find user in your space | 404 | The specified user does not exist or is not a member of your space. |
Gigs
| Error message | Status | Description |
|---|
The gig is already started, <params> cannot be updated | 422 | Certain gig attributes cannot be changed once the gig has started. |
The gig is already started and cannot be deleted | 422 | A gig that has already started cannot be deleted. |
The gig is already archived | 422 | Users cannot be invited to an archived gig. |
Cannot find users: <ids> to invite | 422 | One or more user IDs provided for invitation do not exist in your space. |
Users can not be invited until new terms are accepted | 422 | The space has pending terms that must be accepted before invitations can be sent. |
Gig Results
| Error message | Status | Description |
|---|
The given user is not a community member of your space | 403 | The user specified is not a community member in your space. |
Gig does not belong to your space | 403 | The gig task referenced does not belong to your space. |
No rewarded results are expected for the gig | 400 | The gig invitation is flagged as no_reward, so results cannot be submitted. |
Gig Time Activities
| Error message | Status | Description |
|---|
The given user is not a community member in your space. | 422 | The user specified is not a community member in your space. |
Can not find gig in your space | 404 | The specified gig does not exist or does not belong to your space. |
No rewarded time activities are expected for the gig | 400 | The gig invitation is flagged as no_reward, so time activities cannot be submitted. |
Payouts
| Error message | Status | Description |
|---|
The given user is not a community member of your space | 422 | The user specified is not a community member in your space. |
You can not delete payouts which are already billed | 422 | A payout that has already been billed cannot be deleted. |
Notification Topics
| Error message | Status | Description |
|---|
only snake_case(lowercase letters) allowed | 400 | The topic name parameter must use snake_case format. |
Idempotency
When you include an Idempotency-Key header in a create request and a previous request with the same key has already been processed, the API returns a 208 Already Reported status with the original response body. This is not an error — it indicates the request was already fulfilled.
Handling errors
We recommend writing code that handles errors gracefully. Here are some best practices:
- Check the HTTP status code before parsing the response body.
- Parse the
error field from the JSON response to get a human-readable description of what went wrong. - Retry on
5xx errors with exponential backoff, as these indicate temporary server issues. - Do not retry
4xx errors without modifying the request, as the same request will produce the same error. - Use idempotency keys for create requests to safely retry without risking duplicate records.