> This page is for Developers.

> For clean Markdown of any page, append .md to the page URL.
> For a complete documentation index, see https://docs.emnify.com/llms.txt.
> For AI client integration (Claude Code, Cursor, etc.), connect to the MCP server at https://docs.emnify.com/_mcp/server.

> Understand RESTful API conventions including HTTP methods, authentication with JWTs, URL structure, headers, and response codes.

emnify provides a RESTful API.
Communication with the API is done over HTTP(S) requests with JSON request body with `application/json` content-type and an authentication token as a requirement for every API call.

The API is defined in detail in the following section, but here are some highlights:

* Lookup values are accessed at the same level as the resource they describe.
  For example, the URL to retrieve the list of possible statuses of an endpoint is `/api/v1/endpoint/status`.
* Collection responses aren't wrapped in an envelope.
  Instead the result metadata is returned in the header of the response.
* Paging, filtering sorting of large datasets are managed via query parameters of GET requests.
* The API provides complex error messages capable of reporting a set of errors.
* The API implicitly provides multi-tenancy management.
  The server limits the visibility of the data and available operations based on the organization of the user identified by authentication token.
* When associating an existing objects to a collection, it's sufficient to provide only the objects IDs.

The following service pattern is provided for all major resources:

| Action   | URL                                       | Description                                                                          |
| -------- | ----------------------------------------- | ------------------------------------------------------------------------------------ |
| `GET`    | `/api/v1/resource`                        | Retrieve resource collection                                                         |
| `POST`   | `/api/v1/resource`                        | Create resource                                                                      |
| `GET`    | `/api/v1/resource/{id}`                   | Retrieve single resource                                                             |
| `PATCH`  | `/api/v1/resource/{id}`                   | Update single resource                                                               |
| `DELETE` | `/api/v1/resource/{id}`                   | Delete single resource                                                               |
| `PUT`    | `/api/v1/resource/{id1}/collection/{id2}` | Add sub-resource with id `id2` to a collection belonging to a resource with id `id1` |

> **Info**
>
> The word endpoint, typically used in RESTful API definitions has a particular meaning in the emnify application domain.
> To avoid confusion, the word *endpoint* is used in this documentation to identify endpoint entities (resources) of the emnify System domain while the word *entrypoint* is used to identify generic RESTful API endpoints.

## Securing the API

The API is secured through usage of JSON Web Tokens (JWT) which are an open standard ([RFC 7519](https://datatracker.ietf.org/doc/html/rfc7519)) for representing claims securely between two parties.

The server generates JWT tokens for accessing the API (further referenced as 'authentication token') for users or applications after they present verifiable credentials.
Once the credentials are exchanged for an authentication token on the server, the client has to submit it within the HTTP `Authorization` header in each subsequent request.
The system validates the rights and permissions of the requesting user/application by parsing the token's content.

The authentication token expires after 240 minutes.
Therefore the authentication needs to be performed again to obtain a new authentication token.

If the authentication token is missing, invalid, or expired, the API returns `401 Unauthorized` response status.

If a client tries to access resources that exists, but the client doesn't have the permissions or the rights to access it, the API returns either `403 Forbidden` or `404 Not Found`.

These requirements are general and aren't repeated in the remainder of this API specification.

## Connection

All API calls including the authentication must be made over secure socket (SSL).

The server responds to API request in gzip compressed format with the following header:

```http
Content-Encoding: gzip
Content-Type: application/json
```

## URL format

All API URLs follow a generic structure:

```generic
/api/API_VERSION/ENTRYPOINT/{object_id}
```

For example:

```generic
/api/v1/user/123
```

Some resources may also provide access to further sub-resources:

```generic
/api/v1/organisation/123/contact
```

## HTTP guidelines

### HTTP verbs

Here is the definition of HTTP verbs used in the API with description and typical
responses upon request to collection entrypoint and single resource entrypoint.

| Verb   | Description                                                                                     | Collection response for example, `/sim`                                              | Item Response for example, `/sim/{id}`                                     |
| :----- | :---------------------------------------------------------------------------------------------- | :----------------------------------------------------------------------------------- | :------------------------------------------------------------------------- |
| GET    | Retrieve a resource without side-effects (nothing changes on the server)                        | 200 (OK), list of SIMs. Use pagination, sorting and filtering to navigate big lists. | 200 (OK), single SIM. 404 (Not Found), if ID not found or invalid.         |
| POST   | Create a resource                                                                               | 201 (Created), 'Location' header with link to `/sim/{id}` containing new ID.         | 404 (Not Found).                                                           |
| PUT    | Assign already-existing sub-resource to a resource. No request body is requested in such calls. | 404 (Not Found)                                                                      | 200 (OK) or 204 (No Content). 404 (Not Found), if ID not found or invalid. |
| PATCH  | Partially modify a resource                                                                     | 404 (Not Found)                                                                      | 200 (OK) or 204 (No Content). 404 (Not Found), if ID not found or invalid. |
| DELETE | Delete a resource                                                                               | 404 (Not Found)                                                                      | 200 (OK). 404 (Not Found), if ID not found or invalid.                     |

### HTTP headers

#### Request headers

Each HTTP request must have at least the following headers:

* Content-Type: `application/json`
* Accept: `application/json`
* Authorization: `Bearer AUTH_TOKEN`

#### Response headers

The API uses header to transfer meta information about the returned result.
The usage varies depending on the operation.
The details are available within the specification of particular resource description:

| Header         | Description                                 | Examples                                                                                                                                                                                                                                                                                            |
| :------------- | :------------------------------------------ | :-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| Location       | \[POST] - URL of the created resource       | Location: /api/v1/endpoint/123                                                                                                                                                                                                                                                                      |
| Link           | \[GET] Collection - URL of available pages  | Link: `https://cdn.emnify.net/api/v1/endpoint?per_page=100;rel="first"`, `https://cdn.emnify.net/api/v1/endpoint?page=5&per_page=100;rel="prev"`, `https://cdn.emnify.net/api/v1/endpoint?page=7&per_page=100;rel="next"`, `https://cdn.emnify.net/api/v1/endpoint?page=34&per_page=100;rel="last"` |
| X-Total-Count  | \[GET] Collection - Total item count        | X-Total-Count: 3325                                                                                                                                                                                                                                                                                 |
| X-Current-Page | \[GET] Collection - Current page            | X-Current-Page: 6                                                                                                                                                                                                                                                                                   |
| X-Filter       | \[GET] Collection - Filter applied criteria | X-Filter: status:1                                                                                                                                                                                                                                                                                  |
| X-Sort         | \[GET] Collection - Applied sort criteria   | X-Sort: -status                                                                                                                                                                                                                                                                                     |

### HTTP return codes

| Code | Meaning                | Description                                                                                                                     |
| :--- | :--------------------- | :------------------------------------------------------------------------------------------------------------------------------ |
| 200  | OK                     | Response to a successful GET, also used for a POST if it doesn't result in a creation                                           |
| 201  | Created                | Response to a POST that results in a creation, usually returns a `Location` header pointing to the location of the new resource |
| 204  | No Content             | Response to a successful request that isn't returning a body                                                                    |
| 400  | Bad Request            | The request is malformed, for example, the body can't be parsed                                                                 |
| 401  | Unauthorized           | No or invalid authentication token provided                                                                                     |
| 403  | Forbidden              | authentication token is valid, but user has no access permissions to the request resource                                       |
| 404  | Not Found              | A non-existent resource is requested                                                                                            |
| 405  | Method Not Allowed     | HTTP method being requested isn't allowed                                                                                       |
| 409  | Conflict               | The request couldn't be completed due to a conflict with the current state of the resource.                                     |
| 410  | Gone                   | Indicates that the resource at this end point is no longer available.                                                           |
| 415  | Unsupported Media Type | Incorrect media type was provided as part of the request                                                                        |
| 422  | Unprocessable Entity   | Body returned a list of validation errors                                                                                       |
| 429  | Too Many Requests      | Request is rejected due to rate limiting                                                                                        |

## Timestamps

Unless otherwise specified, you can expect timestamps returned by the emnify REST API to be [ISO 8601](https://en.wikipedia.org/wiki/ISO_8601)-encoded date and time strings in the UTC (Coordinated Universal Time) time zone.

* `2023-03-06` - Date in YYYY-MM-DD format
* `T` - Represents time
* `11:15:57.000` - Time in HH:mm:ss.sss format
* `+0000` - Offsets the time 0 hours from UTC