Response Codes
Every Addepar API response returns a standard HTTP status code. The code tells you whether the request succeeded and, if it failed, whether the problem is in your request, your permissions, or the server. Understanding what each code means operationally (retry, fix, or escalate) prevents wasted debugging time.
Success codes
| Code | Title | When returned | What it means |
|---|---|---|---|
200 | OK | Successful GET or PATCH | The resource was retrieved or updated. Response body contains the result. |
201 | Created | Successful POST | A new resource was created. Response body contains the created resource with its assigned id. |
202 | Accepted | POST to an async endpoint (Jobs) | The request was accepted for background processing. The response contains a job ID. Poll GET /v1/jobs/{id} until completion. |
204 | No Content | Successful DELETE, or relationship modification | The operation succeeded. There is no response body. |
303 | See Other | Completed async job | The job finished. Follow the Location header to retrieve results. Do not re-poll after receiving 303. |
Error codes
A failed request returns one of these codes. The response body contains a JSON:API errors array with structured detail.
Client errors (fix your request)
| Code | Title | Meaning | Action |
|---|---|---|---|
400 | Bad Request | The request body or query parameters are malformed | Read the detail field. Fix the indicated parameter. Common causes: invalid JSON, wrong date format, missing required field, request timeout (60s exceeded). |
405 | Method Not Allowed | The HTTP method is not supported on this endpoint | Use GET, POST, PATCH, or DELETE as documented for the specific endpoint. |
409 | Conflict | The request would create an invalid state | The type field in the request body must match the resource type in the URL. Also occurs when creating a duplicate of a unique resource. |
415 | Unsupported Media Type | Missing or wrong Content-Type header | Set Content-Type: application/vnd.api+json on all requests with a body. |
Auth and permission errors (fix your credentials or access)
| Code | Title | Meaning | Action |
|---|---|---|---|
401 | Unauthorized | Authentication failed | The API key/secret pair is invalid, expired, or malformed. Verify: (1) the key is base64-encoded as key_id:key_secret, (2) the Authorization: Basic {encoded} header is present, (3) the key has not been revoked. For OAuth: the access token has expired (240s lifetime). Refresh it. |
403 | Forbidden | Authenticated but insufficient permissions | The user behind the credential lacks the required permission. Check: (1) API Access permission is set to "Create, edit, and delete," (2) the user has Portfolio Access for the requested entities, (3) for OAuth: the required scope was authorized. |
401 vs 403: If the server cannot identify who you are, you get 401. If it knows who you are but you are not allowed to do this specific thing, you get 403. A 401 means fix your credential. A 403 means fix your permissions in Firm Administration or request the correct OAuth scope.
Resource errors (the target doesn't exist or expired)
| Code | Title | Meaning | Action |
|---|---|---|---|
404 | Not Found | The URL or resource ID is wrong, or the user cannot access the resource | Verify the ID exists and the authenticated user has permission to see it. A user without Portfolio Access to an entity will receive 404 (not 403) for that entity. |
410 | Gone | The resource existed but has expired | Job results expire after a period. Resubmit the job request to generate fresh results. |
Rate and server errors (retry or escalate)
| Code | Title | Meaning | Action |
|---|---|---|---|
429 | Too Many Requests | Rate limit exceeded | Read X-RateLimit-Retry-After header for seconds to wait. Do not retry before that time. Implement exponential backoff. |
500 | Internal Server Error | Unexpected server failure | Retry once after a brief delay. If persistent, contact Addepar Support with the request URL, timestamp, and any request ID from the response headers. |
Error response format
All error responses follow JSON:API structure:
{
"errors": [
{
"id": "bad_request",
"status": "400",
"title": "Bad Request",
"detail": "Validation failed: 'report_id' is required."
}
]
}
| Field | Purpose |
|---|---|
id | Machine-readable error identifier |
status | HTTP status code as a string |
title | Human-readable error category |
detail | Specific explanation of what went wrong. This is the field to read first when debugging. |
The errors array can contain multiple entries when a request fails multiple validations simultaneously.
Operational decision tree
When you receive an error, the response code tells you which category of fix to apply:
| Code range | Decision |
|---|---|
400, 405, 409, 415 | Fix the request. The problem is in what you sent. Read detail, correct the payload or URL, and retry immediately. |
401, 403 | Fix credentials or permissions. Do not retry the same request. It will fail again until the underlying access issue is resolved. |
404 | Verify the resource exists and that your user has visibility. This is often a permission issue presenting as "not found." |
410 | Resubmit the operation. The resource expired. Generate fresh results. |
429 | Wait, then retry. Respect the Retry-After value. Implement backoff. See Rate Limiting. |
500 | Retry once. If it persists, escalate to support with full request context. |
Related
- Rate Limiting - Budget model, proactive headers, and exempt endpoints
- Access & Authentication - Credential setup and permission requirements
- OAuth - Token lifecycle and scope authorization
Updated 4 days ago