Error Codes
Comprehensive reference for all error codes returned by the Texture REST API
Error Response Structure
All error responses from the Texture REST API return a JSON body with at minimum a code and message field:
{
"code": "ERROR_CODE",
"message": "Human-readable description of the error"
}| Field | Type | Description |
|---|---|---|
code | string | Machine-readable error code. Use this for programmatic error handling. |
message | string | Human-readable description. Use for logging — do not parse for control flow, as wording may change. |
Additional Fields
Some error responses include extra fields alongside code and message:
| Field | Type | When Present | Description |
|---|---|---|---|
details | object | Validation errors | Contains field-level error information |
mismatchedFields | string[] | PARAMETER_MISMATCH only | Lists which fields differ from the existing resource |
retryAfter | number | RATE_LIMITED only | Seconds until rate limit window resets (also in Retry-After header) |
Example: Standard Error
{
"code": "DEVICE_NOT_FOUND",
"message": "The specified device does not exist"
}Example: Validation Error with Details
{
"code": "VALIDATION_ERROR",
"message": "The request body failed validation",
"details": {
"serialNumber": "Serial number is required",
"capacity": "Must be a positive number"
}
}Example: Rate Limit Error
{
"code": "RATE_LIMITED",
"message": "Rate limit exceeded. Try again later.",
"retryAfter": 42
}Example: Conflict with Mismatched Fields
{
"code": "PARAMETER_MISMATCH",
"message": "A device with this manufacturer device ID already exists with different parameters",
"mismatchedFields": ["serialNumber", "name"]
}Authentication Errors (401)
Returned when the API cannot verify the caller's identity.
| Error Code | Description | What to Do |
|---|---|---|
UNAUTHENTICATED | Missing, invalid, expired, or revoked API key | Verify your API key is included, correctly formatted, and active. Generate a new key in the Dashboard if needed. |
Common causes
- Missing
Texture-Api-Keyheader - Malformed API key value
- API key has been revoked or expired
- Using the wrong API key type for the endpoint (e.g., using a Management key on an OEM endpoint that requires a Manufacturer key)
Do not retry. Fix the API key and re-send.
Authorization Errors (403)
Returned when the API key is valid but lacks permission for the requested operation.
| Error Code | Description | What to Do |
|---|---|---|
FORBIDDEN | Insufficient permissions for this resource or action | Verify the key's scopes include the resource type and operation you're attempting |
DEVICE_MODEL_MANUFACTURER_MISMATCH | The device model belongs to a different manufacturer than your API key | Confirm your Manufacturer API key matches the device model's manufacturer |
DEVICE_NOT_OEM_DIRECT | The device was not provisioned via OEM Direct | Only OEM Direct devices can receive telemetry via POST /devices/:id/telemetry |
MANUFACTURER_NOT_ALLOWED | The device's manufacturer is not in your API key's scope | Check that your Manufacturer API key is scoped to the correct manufacturer |
Do not retry. Adjust your API key permissions or correct the request.
Validation Errors (400)
Returned when the request data is invalid or the operation cannot be performed given the resource's current state.
| Error Code | Description | What to Do |
|---|---|---|
VALIDATION_ERROR | Required fields missing or invalid. The details field lists specific field errors. | Read the details object, fix the indicated fields, and retry |
INVALID_LOCATION | The provided address or coordinates could not be resolved to a valid location | Verify the address is correctly formatted and geocodable |
INVALID_STATE | The operation is not valid for the resource's current state | Check the resource's current state; some operations are only valid in certain lifecycle stages |
INVALID_STATUS | The requested status transition is not allowed | Consult the API docs for valid status transitions |
INVALID_CRITERIA | The filter or query criteria are malformed | Check filter syntax and supported operators |
CUSTOMER_NOT_CONNECTED_TO_SITE | The customer is not associated with the specified site | Verify the customer-site relationship before performing this operation |
DELETION_PROTECTION_ENABLED | Workspace has deletion protection enabled | Disable deletion protection before retrying |
SITE_ALREADY_EXISTS | A site with this address already exists in the workspace | Use the existing site or provide a different address |
DUPLICATE_NAME | A resource with this name already exists in the same scope | Choose a different name |
DEVICE_MODEL_NOT_FOUND | The specified deviceModelId does not match any known device model | Verify the device model ID; use the device models endpoint to list available models |
Do not retry without modifying the request. Read the message and details fields to identify what needs to change.
Resource Not Found Errors (404)
Returned when the specified resource does not exist or is not accessible with your current API key.
| Error Code | Description |
|---|---|
NOT_FOUND | The requested resource does not exist |
CUSTOMER_NOT_FOUND | The specified customer ID does not exist |
DEVICE_NOT_FOUND | The specified device ID does not exist |
SITE_NOT_FOUND | The specified site ID does not exist |
SITE_NOT_IN_WORKSPACE | The site exists but is not accessible from your current workspace scope |
APIKEY_NOT_FOUND | The specified API key ID does not exist |
WORKSPACE_NOT_FOUND | The specified workspace ID does not exist |
SCHEDULE_NOT_FOUND | The specified schedule ID does not exist |
DEVICE_NOT_ASSOCIATED | The device exists but is not associated with any workspace |
COLLECTION_NOT_FOUND | The specified collection ID does not exist |
Verify the resource ID is correct. The resource may have been deleted, or your API key may not have access to the workspace that contains it.
Conflict Errors (409)
Returned when the request conflicts with the current state of an existing resource.
| Error Code | Description | What to Do |
|---|---|---|
DUPLICATE_CONNECTION | A connection with these parameters already exists | Use the existing connection instead of creating a duplicate |
PARAMETER_MISMATCH | A device with the same manufacturerDeviceId exists with different attribute values | Either update the existing device or correct the conflicting fields in your request |
Handling PARAMETER_MISMATCH
This error is specific to OEM device creation (POST /devices). When you create a device and one with the same manufacturerDeviceId already exists, the API compares fields. If they all match, the call succeeds idempotently. If any fields differ, you receive PARAMETER_MISMATCH with a mismatchedFields array listing the differing fields.
Rate Limit Errors (429)
Returned when the caller exceeds the API's request rate limits.
Rate Limit Response Headers
| Header | Type | Description |
|---|---|---|
X-RateLimit-Limit | number | Maximum requests allowed per window |
X-RateLimit-Remaining | number | Requests remaining in the current window |
X-RateLimit-Reset | number | Unix timestamp (seconds) when the window resets |
Retry-After | number | Seconds until you can retry |
Rate Limits by Operation Type
| Operation Type | Limit |
|---|---|
| Read operations (GET) | 300 requests/minute |
| Write operations (POST, PATCH, PUT, DELETE) | 60 requests/minute |
Rate limits are applied per API key. Wait for the number of seconds in Retry-After, then retry. For sustained rate limiting, implement exponential backoff.
Server Errors (500, 502)
Returned when an unexpected error occurs on the server side. These are never caused by your request data.
| HTTP Status | Error Code | Description |
|---|---|---|
| 500 | UNKNOWN_ERROR | An unexpected error occurred while processing the request |
| 500 | LOCATION_SERVICE_ERROR | The address validation service is temporarily unavailable |
| 502 | SERVICE_UNAVAILABLE | A dependent service is temporarily unreachable |
Retry with exponential backoff (1s → 2s → 4s). After 3–5 retries, stop and contact Texture support.
OEM Device Integration Errors
Quick reference for OEM Direct Integration endpoints.
Device Creation — POST /devices
| Error Code | HTTP | Description | What to Do |
|---|---|---|---|
VALIDATION_ERROR | 400 | Required fields missing or invalid | Check details for field-level errors |
DEVICE_MODEL_NOT_FOUND | 400 | The deviceModelId does not match any known model | Verify the device model ID |
SITE_NOT_FOUND | 404 | The specified siteId does not exist | Verify the site ID |
DEVICE_MODEL_MANUFACTURER_MISMATCH | 403 | The device model belongs to a different manufacturer | Use a model belonging to your manufacturer |
PARAMETER_MISMATCH | 409 | Device with same manufacturerDeviceId exists with different attributes | See Conflict Errors section |
If you create a device with a manufacturerDeviceId that already exists and all fields match, the request succeeds and returns the existing device. This allows safe retries.
Telemetry Push — POST /devices//telemetry
| Error Code | HTTP | Description | What to Do |
|---|---|---|---|
DEVICE_NOT_FOUND | 404 | The device ID does not exist | Verify the device ID |
DEVICE_NOT_OEM_DIRECT | 403 | The device was not provisioned via OEM Direct | This endpoint only accepts telemetry for OEM Direct devices |
MANUFACTURER_NOT_ALLOWED | 403 | The device's manufacturer is not in your API key's scope | Verify your Manufacturer API key scope |
DEVICE_NOT_ASSOCIATED | 404 | The device is not associated with any workspace | Device must be associated with a workspace before telemetry can be ingested |
VALIDATION_ERROR | 400 | The telemetry payload is invalid or missing required fields | Check details for field-level errors |
HTTP Status Code Quick Reference
| Status | Meaning | Retryable? | Action |
|---|---|---|---|
| 400 | Bad Request | No | Fix request data per code, message, and details |
| 401 | Unauthenticated | No | Fix or replace API key |
| 403 | Forbidden | No | Check API key scopes and permissions |
| 404 | Not Found | No* | Verify resource ID and workspace access |
| 409 | Conflict | No | Resolve the conflict per the error details |
| 429 | Too Many Requests | Yes | Wait for Retry-After, then retry |
| 500 | Internal Server Error | Yes | Retry with exponential backoff |
| 502 | Service Unavailable | Yes | Retry with exponential backoff |
* 404 may be retryable if the resource was very recently created (eventual consistency). A single retry after 1–2 seconds is reasonable.
Best Practices for Error Handling
- Branch on HTTP status code first. Use the status code to determine the error category, then inspect
codefor specifics. - Use
codefor programmatic handling. Thecodefield is stable and machine-readable. Map code values to specific handling logic in your client. - Use
messagefor logging only. Themessagefield is human-readable and may change without notice. Do not parse it for control flow. - Retry only retryable errors. Only 429, 500, and 502 responses should be retried. All other status codes indicate a problem with the request itself.
- Respect
Retry-After. When present, always honor theRetry-Afterheader before retrying. - Implement exponential backoff for server errors. Start at 1 second and double on each retry, up to a maximum of 3–5 attempts.
- Log the full error response. Always log
code,message, and any additional fields (details,mismatchedFields) for debugging. - Handle
PARAMETER_MISMATCHexplicitly in your device provisioning flow. This is an expected response when re-provisioning devices and should be handled as a recoverable conflict, not a generic error. - Monitor rate limit headers proactively. Check
X-RateLimit-Remainingon successful responses to throttle your request rate before hitting 429.