Response format
Every response is JSON and carries meta.request_id. Quote it to support about a request. An error is:
{
"error": { "code": "ANCHOR_NOT_FOUND", "message": "Anchor not found" },
"meta": { "request_id": "550e8400-e29b-41d4-a716-446655440000" }
}
Branch on error.code, not on error.message, which may be reworded. Some successful responses also carry "success": true; each operation's schema shows its shape.
Ids your key cannot reach
An id your key cannot reach, because it belongs to another team or, for a bound key, to another project, is answered exactly like an id that does not exist:
- An id in the path answers 404 with the resource's not-found code:
ANCHOR_NOT_FOUND,SCENE_NOT_FOUND,PROJECT_NOT_FOUND,ASSET_NOT_FOUND. For a client key, a private cloud anchor answers the same. - A
project_idin the query or the body answers 403PROJECT_NOT_FOUND, also for a project that does not exist. - A linked scene, scene asset, team asset or file in a body answers 404
SCENE_NOT_FOUND,SCENE_ASSET_NOT_FOUND,TEAM_ASSET_NOT_FOUNDorUSER_ASSET_NOT_FOUND. - A scene's API request function answers 404
FUNCTION_NOT_FOUND.
Two groups answer differently. The co-location room operations answer 403: PROJECT_NOT_FOUND for a project that does not exist and PROJECT_ACCESS_DENIED for one the key cannot reach, because the native SDK reads a 404 there as a missing deployment and keeps retrying. The AI operations answer 403 PROJECT_ACCESS_DENIED or SCENE_ACCESS_DENIED for a project or scene the key cannot reach, and 403 ACCESS_DENIED for a task of another team or project.
Codes
Every operation lists the codes it can return. All of them:
| Code | Status | Meaning |
|---|---|---|
MISSING_API_KEY | 401 | No x-api-key header. |
MISSING_AUTH | 401 | No x-api-key header and no other credential (scenes, projects, scene API requests, AI). |
INVALID_API_KEY_FORMAT | 401 | The key is not rv_live_, rv_client_ or rv_secret_ followed by 64 lowercase hexadecimal characters. |
INVALID_API_KEY | 401 | No such key, or a key sent with the wrong prefix for its type. |
API_KEY_EXPIRED | 401 | The key is past its expiry date. |
AUTH_ERROR | 401 | A user token (rv_ut_) was sent where it is not accepted. |
INVALID_SESSION | 401 | An Authorization: Bearer header that is not a valid ReactVision Studio session. Send the key in x-api-key instead. |
API_KEY_TYPE_NOT_ALLOWED | 403 | The operation does not accept this type of key. |
API_KEY_LOOKUP_FAILED | 503 | The key could not be checked. Retry; the key is not invalid. |
RATE_LIMITED | 429 | Over a rate limit. Wait the seconds in Retry-After. |
API_REQUEST_LIMIT_REACHED | 403 | The team's monthly API request quota is used up. |
STORAGE_LIMIT_REACHED | 403 | The team's storage quota is used up. |
LIMIT_REACHED | 403 | The team's monthly AI credit budget would be exceeded, or could not be read. |
PAID_PLAN_REQUIRED | 403 | Co-location needs a paid plan. |
PROJECT_NOT_FOUND | 403 or 404 | The project does not exist or the key cannot reach it. 404 when the project id is in the path. |
PROJECT_ACCESS_DENIED | 403 | Co-location and AI: the key cannot reach the project. |
SCENE_ACCESS_DENIED | 403 | AI: the key cannot reach the scene. |
ACCESS_DENIED | 403 | AI: the task belongs to another team or project, or a bound key sent neither project_id nor scene_id. |
DRY_RUN_JWT_ONLY | 403 | A scene API request sent with dry_run: true, which only the Studio editor may send. |
PROJECT_LOOKUP_FAILED | 503 | The project could not be checked. Retry. |
TIER_LOOKUP_FAILED | 503 | The team's plan could not be checked. Retry. |
ANCHOR_NOT_FOUND | 404 | No such anchor, or one the key cannot reach. |
SCENE_NOT_FOUND | 404 | No such scene, or one the key cannot reach. |
SCENE_ASSET_NOT_FOUND | 404 | No such scene asset in the anchor's project. |
TEAM_ASSET_NOT_FOUND | 404 | No such team asset, or one of another team. |
USER_ASSET_NOT_FOUND | 404 | No such file, or one the key cannot reach. |
ASSET_NOT_FOUND | 404 | No such file, or one the key cannot reach. |
FUNCTION_NOT_FOUND | 404 | No such API request function, or one the key cannot reach. |
TASK_NOT_FOUND | 404 | No such AI task. |
ROOM_NOT_FOUND | 404 | No such co-location room or join code in this project. |
NOT_FOUND | 404 | No such operation: check the path. |
METHOD_NOT_ALLOWED | 405 | The path exists, but not with this HTTP method. |
TOO_MANY_ROOMS | 409 | The project already holds 500 co-location rooms. |
CONTENT_REFUSED | 422 | The image model refused the prompt. Reword it. |
MISSING_FIELD | 400 | A required body field is missing; the message names it. |
MISSING_PROJECT_ID | 400 | project_id (or the x-project-id header) is required. |
INVALID_PROJECT_ID | 400 | x-project-id is not a UUID. |
INVALID_BODY | 400 | The body is not valid JSON or not an object, or a field failed its check; the message says which. |
INVALID_REQUEST | 400 | Scene API requests: the body is not valid JSON or a field failed its check. |
INVALID_FIELD_VALUE | 400 | A field has the wrong type, a field that cannot be cleared was sent as null, or a client key sent a field it may not set. |
FIELD_TOO_LONG | 400 | A text field is over its length limit, or a JSON object is over 4096 bytes. |
NO_UPDATES | 400 | An update named no field it can change. |
INVALID_LATITUDE, INVALID_LONGITUDE | 400 | Outside -90 to 90, or -180 to 180. |
MISSING_COORDINATES | 400 | A nearby search without lat and lng. |
INVALID_ALTITUDE, INVALID_ALTITUDE_MODE | 400 | Geospatial alt or altitude_mode out of range. |
INVALID_PLATFORM | 400 | platform is not ios, android or web. |
INVALID_KEYPOINTS, KEYPOINT_COUNT_MISMATCH | 400 | Cloud anchor keypoints_json is malformed, or keypoint_count does not match it. |
INVALID_DESCRIPTORS_URL, INVALID_FEATURE_POINTS_URL, INVALID_MESH_URL, INVALID_FILE_URL | 400 | The URL is not a file this project uploaded through POST /assets/upload. |
FILE_NOT_FOUND | 400 | file_url names no stored file. |
INVALID_ASSET_TYPE, INVALID_ASSET_REFERENCE | 400 | An unknown asset_type, or no asset to attach. |
USER_ASSET_PROJECT_MISMATCH | 400 | The file belongs to another project of the team. |
INVALID_CONTENT_TYPE, INVALID_FORM_DATA, MISSING_FILE, FILE_TOO_LARGE, INVALID_FILE_TYPE | 400 | An upload that is not multipart, has no file, or whose file is too large or of a type the asset_type does not allow. |
APP_USER_ID_TOO_LONG, INVALID_APP_USER_ID | 400 | app_user_id is over 255 characters, or not printable ASCII without spaces. |
INVALID_SCENE_ID | 400 | A scene id that is not a UUID, or not a scene of this project (co-location). |
MISSING_PROMPT, PROMPT_TOO_LONG, INVALID_MODEL, INVALID_QUALITY, INVALID_TYPE, INVALID_COMBINATION, MISSING_IMAGE, IMAGE_TOO_LARGE, INVALID_IMAGE_URL, INVALID_REFERENCE_IMAGE_URL, INVALID_SCENE | 400 | AI request checks; each AI operation explains them. |
GENERATION_FAILED, SERVICE_ERROR | 502 | The AI provider failed. Nothing is charged; a retry may succeed. |
SERVICE_NOT_CONFIGURED, APP_USER_TOKEN_SIGNING_UNAVAILABLE | 503 | A ReactVision service is unavailable. Retry later. |
CREATE_FAILED, UPDATE_FAILED, DELETE_FAILED, LIST_FAILED, NEARBY_SEARCH_FAILED, RESOLVE_TRACKING_FAILED, ATTACH_ASSET_FAILED, REMOVE_ASSET_FAILED, ASSET_CREATE_FAILED, UPLOAD_FAILED, LOOKUP_FAILED, RESET_FAILED | 500 | The operation failed on our side. Retry. |
INTERNAL_ERROR | 500 | An unexpected error. Retry, and quote meta.request_id to support if it persists. |
A 503 is never a decision about your key or your request: retry it. A 401 or 403 is, and retrying the same request will not change it.