## Authentication  
REST API calls must be authenticated using a custom HTTP header `X-Incode-Hardware-Id` — along with a JSON web token. Additionally, every API call has to contain `x-api-key` header with valid client API key.

### Please check the section [Create an Access Token](https://developer.incode.com/docs/how-to-get-an-session-token) for an explanation of how access tokens are generated and used

## API Responses  
Incode Omni uses conventional HTTP response codes to indicate the success or failure of an API request. In general:

- Codes in the `2XX` range indicate success.
- Codes in the `4xx` range indicate an error that failed given the information provided (e.g. missing required parameter). These usually mean you need to fix your request.
- Codes in the `5xx` range indicate server side errors (these are rare).

Some `2XX` responses of the Omni API have a dynamic nature. For example, the [Fetch ocr data](https://developer.incode.com/reference/getocrdata) endpoint might contain additional fields depending on the data which was extracted from the provided ID Document in the session. If you are using typed languages such as Java or C#, consider these cases to avoid having serialization exception when reading the JSON responses.

`4XX` errors that can be handled programmatically on your end include status of an error and message that briefly explains the error reported.

**Arguments:**
- **timestamp**: Long, UTC timestamp in milliseconds
- **status**: Integer, custom error code or http status code
- **error**: String, Http status error
- **message**: String, custom error message
- **path**: String, endpoint path

**Custom error codes** are given for each endpoint.

**Example response with custom error**
```json
 {
   "timestamp": 1584639032757,
   "status": 405,
   "error": "Spoof attempt detected",
   "message": "BadRequestException: Spoof attempt detected.",
   "path": "/omni/add/face"
}
```

**HTTP status code summary:**
- **`200`(OK)** - Everything worked as expected.
- **`400`(Bad Request)** - The request was unacceptable, often due to missing a required parameter.
- **`401`(Unauthorized)** - Invalid or missing access token.
- **`403`(Forbidden)** - Invalid or missing api key.
- **`404`(Not Found)** - The requested resource doesn't exist.
- **`405`(Method Not Allowed)** - Unacceptable HTTP method for the requested resource.
- **`406`(Not Acceptable)** - Unacceptable request.
- **`429`(Too Many Requests)** - See [rate limits](https://developer.incode.com/reference/introduction#rate-limits) below.
- **`500, 502, 503, 504`(Server Errors)** - Something went wrong on server side. (These are rare.)

## API Limitations  
### Maximum Request Size  
**There is a limitation of 10Mb** as the maximum possible request / response size in all our API endpoints, for this reason; it's is not possible to upload or fetch images/files larger than 10 Mb.

### Timeout  
**There is a hard limit of 30 seconds** for all of our endpoints. If any request takes longer than that, you will receive a `Request Timeout` error.

### Rate limits  
We rate limit our APIs via throttling based on the "tokens in a bucket" approach:
- Each endpoint call requires a token (each organization has a bucket of tokens per endpoint category)
- Bucket capacity (`burst`) defines how many tokens can be withdrawn at once
- Tokens are refilled until the bucket reaches maximum capacity based on the refill rate (`maxRps`)

There are three endpoint categories, each one with its own bucket:
1. `SUPER_HEAVY`: ID endpoints triggered by the SDK normally (e.g. `add/front`, `add/back`, `process/id`)
2. `HEAVY`: Face endpoints triggered by the SDK normally (e.g. `add/face`, `process/face`)
3. `OTHER`: All other endpoints

| Category | maxRps | burst |
| --- | --- | --- |
| SUPER HEAVY | 1 | 5 |
| HEAVY | 1 | 5 |
| OTHER | 100 | 50 |

For **special cases (only)** where these limits are not enough, our Customer Success team can help you adjust as needed.

**Rate limit example:**

The endpoints `add/front`, `add/back`, and `process/id` are in the `SUPER_HEAVY` category. The maximum bucket capacity is `5`, meaning the max amount of requests that can be done in a second is 5. Every request will deplete the bucket by 1. If all 5 requests are consumed **within the same second**, the bucket is emptied, and any additional requests within the same second will receive the response: `429 Too Many Requests`.

The `SUPER_HEAVY` bucket has a refill rate of 1 (`maxRps`) per second, so it will refill by 1 unit every second until it's filled (5).
