# Errors

Sinch uses conventional HTTP codes to indicate the success or failure of an API request.

Generally, a 2xx code indicates success. Codes in the 4xx range indicate an error that failed because of information you provided in the request (authentication failed, a required field was missing, or some other parameter was invalid are all examples).
Codes in the 5xx range are rare errors on the Sinch servers that you as a developer usually can't do anything about.

In addition to the standard HTTP codes, we provide a `Message` field to help you understand in plain text what went wrong.

```json
{
  "$ref": "#/components/schemas/Error",
  "components": {
    "schemas": {
      "FieldViolation": {
        "type": "object",
        "properties": {
          "field": {
            "type": "string",
            "readOnly": true,
            "description": "Request field.",
            "example": "to"
          },
          "description": {
            "type": "string",
            "readOnly": true,
            "description": "Description of why the request field was considered invalid.",
            "example": "Phone number was not in the expected format."
          }
        }
      },
      "BadRequestDetail": {
        "type": "object",
        "description": "The request was malformed on one or more fields.",
        "x-internal": "https://github.com/googleapis/googleapis/blob/f79d6e85a9a6b913a5e9cb0067e846e7f087dbc8/google/rpc/error_details.proto#L169",
        "properties": {
          "type": {
            "type": "string",
            "description": "The request was malformed on one or more fields.",
            "readOnly": true,
            "example": "BadRequest",
            "default": "BadRequest"
          },
          "fieldViolations": {
            "description": "The field violation(s).",
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/FieldViolation"
            }
          }
        }
      },
      "RequestInfoDetail": {
        "description": "Information on why a request failed.",
        "type": "object",
        "x-internal": "https://github.com/googleapis/googleapis/blob/f79d6e85a9a6b913a5e9cb0067e846e7f087dbc8/google/rpc/error_details.proto#L187",
        "properties": {
          "type": {
            "type": "string",
            "description": "Information on why a request failed.",
            "readOnly": true,
            "example": "RequestInfo",
            "default": "RequestInfo"
          },
          "requestId": {
            "type": "string",
            "example": "879c4177-af8a-4534-8168-cc2f66a1f2c6",
            "description": "The ID of the request."
          },
          "data": {
            "type": "object",
            "description": "The data sent to to the API when the error occurred."
          }
        }
      },
      "QuotaFailure": {
        "type": "object",
        "description": "Description of quota failure, example not enough credit, maximum calls per minute",
        "properties": {
          "subject": {
            "type": "string",
            "description": "On what part the quota failed, example ip address, CPS."
          },
          "description": {
            "description": "A description of how the quota check failed. You can can use this\ndescription to find more about the quota configuration in the service's\npublic documentation"
          }
        }
      },
      "QuotaFailureDetail": {
        "type": "object",
        "description": "Describes how a quota check failed. For example if the total number of `IN_PROGRESS` call was reached",
        "properties": {
          "type": {
            "type": "string",
            "description": "Describes how a quota check failed. For example if the total number of `IN_PROGRESS` call was reached",
            "readOnly": true,
            "example": "QuotaFailure",
            "default": "QuotaFailure"
          },
          "violations": {
            "description": "A list of quota violations",
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/QuotaFailure"
            }
          }
        }
      },
      "ErrorInfo": {
        "description": "Describes the cause of the error with structured details.\nExample of an error when trying to make a call to blocked destination:\n\n     { \"reason\": \"DESTINATION_BLOCKED\"\n       \"domain\": \"VOICE\"\n       \"metadata\": {\n         \"country\": \"Bermuda\",\n       }\n     }",
        "type": "object",
        "properties": {
          "type": {
            "type": "string",
            "description": "Describes the cause of the error with structured details.\nExample of an error when trying to make a call to blocked destination:\n\n```\n    { \"reason\": \"DESTINATION_BLOCKED\"\n      \"domain\": \"VOICE\"\n      \"metadata\": {\n        \"country\": \"Bermuda\",\n      }\n    }\n```",
            "default": "ErrorInfo",
            "example": "ErrorInfo"
          },
          "reason": {
            "type": "string",
            "description": "The reason of the error. This is a constant value that identifies the\nproximate cause of the error. Error reasons are unique. Max 63 characters and match\n /[A-Z0-9_]+/.",
            "maxLength": 63
          },
          "domain": {
            "type": "string",
            "description": "Domain for error, for voice its always sinch.voice"
          },
          "metaData": {
            "description": "Additional structured details about this error. key value pair of strings",
            "type": "object"
          }
        }
      },
      "ErrorDetail": {
        "type": "object",
        "anyOf": [
          {
            "$ref": "#/components/schemas/BadRequestDetail"
          },
          {
            "$ref": "#/components/schemas/RequestInfoDetail"
          },
          {
            "$ref": "#/components/schemas/QuotaFailureDetail"
          },
          {
            "$ref": "#/components/schemas/ErrorInfo"
          }
        ],
        "discriminator": {
          "propertyName": "type",
          "mapping": {
            "BadRequest": "#/components/schemas/BadRequestDetail",
            "RequestInfo": "#/components/schemas/RequestInfoDetail",
            "QuotaFailure": "#/components/schemas/QuotaFailureDetail",
            "ErrorInfo": "#/components/schemas/ErrorInfo"
          }
        }
      },
      "Error": {
        "description": "An error response. The `code` field is a unique identifier for the error. The `message` field is a human-readable description of the error.",
        "type": "object",
        "properties": {
          "code": {
            "description": "HTTP status code or error code",
            "readOnly": true,
            "type": "integer",
            "format": "int32",
            "example": 400
          },
          "status": {
            "description": "Response status name.",
            "readOnly": true,
            "type": "string",
            "example": "INVALID_ARGUMENT"
          },
          "message": {
            "type": "string",
            "readOnly": true,
            "description": "A developer-facing error message",
            "example": "Bad request."
          },
          "details": {
            "readOnly": true,
            "description": "Details of the errors",
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/ErrorDetail"
            }
          }
        }
      }
    }
  }
}
```

## HTTP Codes

The Sinch API can throw the following HTTP codes:

### 2xx - Success

Any 2xx response is considered a successful response. Response bodies will differ depending on the request.

### 400 - BadRequest

400 errors generally concern the construction or format of the request you submitted. For example, missing required parameters or the using the wrong parameter in a request. The following examples all show different types of 400 errors:

| HTTP Code | Status | Message |
|  --- | --- | --- |
| 400 | BAD_REQUEST | "The provided domain name is unavailable" |
| 400 | BAD_REQUEST | "The provided username is unavailable" |
| 400 | BAD_REQUEST | "Customer with id '$id' already exists" |
| 400 | BAD_REQUEST | "Phone Number '$phoneNumber' already exists" |
| 400 | BAD_REQUEST | "Project with id '$id' is not enabled" |
| 400 | BAD_REQUEST | "Project with id '$id' already exists" |
| 400 | BAD_REQUEST | "SIP trunk cannot be deleted while there are one or more endpoints attached" |
| 400 | BAD_REQUEST | "Endpoint cannot be deleted while attached to a SIP trunk" |
| 400 | BAD_REQUEST | "Invalid timestamp format, must match $CALL_RECORD_TIME_STAMP_FORMAT" |
| 400 | BAD_REQUEST | "Access control list with id '$aclId' is already added to trunk '$trunkId'" |
| 400 | BAD_REQUEST | "Credential list with id '$clId' is already added to trunk '$trunkId'" |
| 400 | BAD_REQUEST | "Access Control Lists must contain at least one IP Range" |
| 400 | BAD_REQUEST | "Credential Lists must contain at least one Credential" |
| 400 | BAD_REQUEST | "Cannot delete SIP Trunk $trunkId when there are phone numbers assigned." |
| 400 | BAD_REQUEST | "Credential '$username' is already being used by a SIP Endpoint on SIP Trunk '$trunkId'" |
| 400 | BAD_REQUEST | "Phone number $number is already assigned to SIP Trunk $trunkId" |
| 400 | BAD_REQUEST | "Blocking rule already exists with the same parameters" |
| 400 | BAD_REQUEST | "Invalid $fieldName: $countryCode. Must be a valid ISO 3166-1 alpha-2 code." |
| 400 | BAD_REQUEST | "Invalid direction type: $direction. Must be INBOUND or OUTBOUND." |
| 400 | BAD_REQUEST | "Direction field cannot be null or empty" |


### 401 - Unauthorized

| HTTP Code | Status | Message |
|  --- | --- | --- |
| 401 | UNAUTHORIZED |


### 403 - Forbidden

| HTTP Code | Status | Message |
|  --- | --- | --- |
| 403 | FORBIDDEN |


### 404 - NotFound

404 errors are thrown when the specified resource can't be found. The following examples all show different types of 404 errors:

| HTTP Code | Status | Message |
|  --- | --- | --- |
| 404 | NOT_FOUND | "Could not find SIP Trunk with id '$id'" |
| 404 | NOT_FOUND | "Could not find SIP Trunk with domain '$domain'" |
| 404 | NOT_FOUND | "Could not find SIP Endpoint with id '$id'" |
| 404 | NOT_FOUND | "Could not find phone number with id '$id'" |
| 404 | NOT_FOUND | "Could not find phone number '$number'" |
| 404 | NOT_FOUND | "Could not find Customer with id '$id'" |
| 404 | NOT_FOUND | "Could not find Project with id '$id'" |
| 404 | NOT_FOUND | "Could not find project config with key '$key'" |
| 404 | NOT_FOUND | "Could not find Access Control List with id '$id'" |
| 404 | NOT_FOUND | "Could not find IP Range with id '$id' in access control list with id '$aclId'" |
| 404 | NOT_FOUND | "Access control list '$aclId' is not associated with trunk '$trunk'" |
| 404 | NOT_FOUND | "Could not find Credential List with id '$id'" |
| 404 | NOT_FOUND | "Could not find Credential with username '$username'" |
| 404 | NOT_FOUND | "Could not find call ID '$callId'" |
| 404 | NOT_FOUND | "BlockingRule with ID $id not found for project $projectId" |
| 404 | NOT_FOUND | "Export '$key' could not be found. Check this is the correct key name, if so, it may still be processing." |


### 500 - Internal Server Error

500 errors are general server errors that are temporary and you usually can't do anything about. Try the request a little later or contact support if you receive this error repeatedly after a period of time.

| HTTP Code | Status | Message |
|  --- | --- | --- |
| 500 | INTERNAL_SERVER_ERROR | "Internal Server Error" |