Appearance
Errors
Every JSON error has the same shape:
json
{
"statusCode": 403,
"message": "Invalid camera 'token' or 'fingerprint'",
"errorCode": "FORBIDDEN",
"requestId": "..."
}A 422 adds a details array, with one entry per problem:
json
{
"statusCode": 422,
"message": "Validation failed",
"errorCode": "VALIDATION_ERROR",
"requestId": "...",
"details": [{ "field": "config.trigger_scheme", "message": "Invalid option" }]
}Quote requestId when contacting support.
Keep the fingerprint 16 to 64 characters. A fingerprint longer than 64 characters is currently rejected with a server error (500) on the first call, so do not retry: shorten it.
/v1/camera-info
| Status | When | errorCode |
|---|---|---|
| 400 | User-Agent header missing or empty | BAD_REQUEST |
| 401 | Token or Fingerprint missing | UNAUTHORIZED |
| 403 | Unknown token, fingerprint mismatch, or registration window expired | FORBIDDEN |
| 422 | Body fails validation (an unknown key, a missing field, an invalid trigger_scheme and so on), with details | VALIDATION_ERROR |
| 422 | Token not 20 characters, or fingerprint shorter than 16 | VALIDATION_ERROR |
| 5xx | Server error. Retry later with backoff. A fingerprint longer than 64 characters also gives a 500 on the first call: shorten it | INTERNAL_SERVER_ERROR |
/v1/snapshot
Snapshot uploads first pass the upload gateway, then reach the Camera Service. Both check the request. A gateway response has no JSON body; a Camera Service response uses the JSON shape above. Rely on the status code.
| Status | When | What to do |
|---|---|---|
| 200 | Snapshot accepted. Body {"status":"OK"} | Upload the next one at your cadence |
| 400 | Empty body, an invalid Content-Length, or a missing User-Agent | Send a non-empty JPEG with a correct Content-Length and a User-Agent |
| 401 | Token or Fingerprint header missing or empty | Send both headers |
| 403 | Unknown token, fingerprint mismatch, or registration window expired. Message Camera access denied | See troubleshooting |
| 411 | No Content-Length header, for example chunked transfer | Send the Content-Length header |
| 413 | Image too large. The maximum snapshot size is 1 MB | Shrink the image, do not retry the same one |
| 415 | Content-Type is not image/jpeg or image/jpg | Send Content-Type: image/jpeg |
| 422 | Token not 20 characters, or fingerprint shorter than 16 | Check the lengths |
| 429 or 503 | Rate limit exceeded (6 uploads per minute per camera). Gateway only | Wait, then keep to a 10, 30 or 60 second cadence |
| 500 | Server error. Also a fingerprint longer than 64 characters on the first call | Retry later with backoff. For the fingerprint case, shorten it |
Troubleshooting
| Symptom | Likely cause | Fix |
|---|---|---|
| 403 on a fresh token | The 15-minute registration window expired, or the fingerprint changed | Create a new camera, or restore the original fingerprint |
| 403 after a device reset | The fingerprint changed and no longer matches the one bound to the token | Restore the fingerprint, or delete the camera and create a new one |
| 400 on every request | No User-Agent header | Send a User-Agent such as MyCam/1.2.0 |
| 422 on camera info | The body does not match camera info. details names the field | Fix the field. Remove keys that are not documented |
| 422 on any endpoint | Token is not 20 characters, or fingerprint is shorter than 16 | Check the lengths |
| 401 | Missing or empty Token or Fingerprint header | Check the header names are exactly Token and Fingerprint |
| 415 on snapshot | Content-Type is not image/jpeg or image/jpg | Send Content-Type: image/jpeg |
| 411 or 400 on snapshot | No Content-Length (chunked transfer), or an empty body | Send a non-empty JPEG with a Content-Length header |
| 413 on snapshot | Image too large | Keep snapshots at most 1 MB. Shrink the image, do not retry the same one |
| 429 or 503 on snapshot | Rate limit exceeded | Wait before retrying and upload no more than every 10 seconds |
| 500 on the first call | Fingerprint longer than 64 characters (currently rejected with a server error) | Keep the fingerprint 16 to 64 characters. Shorten it, do not retry |
See authentication and snapshots.