# Numbers

A number is the line you sell: its phone number and the eSIM that carries it. Obtain one, list and look them up, replace a lost SIM, stop and restore service, and end a line.

> Partner API · https://developer.telgea.com/docs/partner/api/numbers

## The number object {#object}

The lines you sell: obtain one, look it up, replace its SIM, stop it and end it.

| Field | Type | Description |
| --- | --- | --- |
| `id` | string (required) | UUID of the number. This is what SIM replacement and suspension act on. Example: `"8238c1b9-c2c0-4455-9b03-4bd787052709"` |
| `type` | enum (required) | Which line this is. One of: `local`, `travel`. Example: `"local"` |
| `countryCode` | string (required) | Market the number belongs to, ISO 3166-1 alpha-2. Example: `"DK"` |
| `phoneNumber` | string (required) | The number in E.164 format, or null until it has been provisioned. Example: `"+4520123456"` |
| `state` | enum (required) | Current state of the phone number in the provisioning lifecycle One of: `PENDING`, `PORTING`, `PORTING_FAILED`, `PROVISIONING`, `READY`, `REPLACING`, `CHANGING`, `SUSPENDING`, `SUSPENDED`, `RESTORING`, `RECONFIGURING`, `DEACTIVATING`, `DEACTIVATED`, `PORTING_DISCARDED`, `PORTING_OUT`, `PORTED_OUT`. Example: `"READY"` |
| `sim` | UserPlanSimDetails (required) | SIM details, included only when the number state is READY |
| `sim.iccid` | string (required) | ICCID of the eSIM profile. Example: `"8945000000000000001"` |
| `sim.activationCode` | string (required) | GSMA activation string for the eSIM. Render it as a QR code, or build an install link from it. Null until the profile has been issued. Example: `"LPA:1$SMDP.TELGEA.COM$34682-73063-9140"` |
| `sim.pinOne` | string (required) | PIN1 of the SIM, or null. Example: `"1234"` |
| `sim.pinTwo` | string (required) | PIN2 of the SIM, or null. Example: `"5678"` |
| `sim.pukOne` | string (required) | PUK1, needed after three wrong PIN1 entries, or null. Example: `"12345678"` |
| `sim.pukTwo` | string (required) | PUK2, needed after three wrong PIN2 entries, or null. Example: `"87654321"` |
| `userId` | string (required) | UUID of the user who holds the line. Example: `"9c1f2a6e-3b7d-4e0a-8f21-5d6c7b8a9e01"` |
| `createdAt` | string (required) | When the line was created, as an ISO 8601 UTC time. Example: `"2026-09-17T08:15:00.000Z"` |
| `stateUpdatedAt` | string (required) | When the line last reached the state it is in, as an ISO 8601 UTC time. Null for a line with no state yet. Example: `"2026-09-17T08:15:00.000Z"` |
| `terminationScheduledAt` | string (required) | The date this line is scheduled to end, or null when no termination is scheduled. Set by POST /v1/numbers/{numberId}/termination. Example: `"2026-10-01T00:00:00.000Z"` |
| `activatedAt` | string (required) | When the line first went into service, as an ISO 8601 UTC time: when it was provisioned, or when its number was ported in. Null until then. Example: `"2026-09-17T08:20:00.000Z"` |
| `previousSims` | array of PreviousSim (required) | The eSIMs the line carried before its current one, newest first. Each SIM replacement adds one. Empty for a line whose eSIM has never been replaced. |
| `previousSims.iccid` | string (required) | ICCID of the eSIM profile. Example: `"89462000099812030017"` |
| `previousSims.inServiceFrom` | string (required) | When this eSIM was issued to the line, as an ISO 8601 UTC time. Example: `"2026-03-02T09:00:00.000Z"` |
| `previousSims.inServiceTo` | string (required) | When the eSIM that replaced it was issued, as an ISO 8601 UTC time. Example: `"2026-09-14T08:00:00.000Z"` |

## Operations

- `GET` [List lines](#list-lines)
- `POST` [Obtain a line](#obtain-a-line)
- `GET` [Get a line](#get-a-line)
- `GET` [Get a line's connection status](#get-a-line-s-connection-status)
- `POST` [Replace a SIM card](#replace-a-sim-card)
- `POST` [Suspend a line](#suspend-a-line)
- `DELETE` [Restore a suspended line](#restore-a-suspended-line)
- `POST` [Stop a line's mobile data](#stop-a-line-s-mobile-data)
- `DELETE` [Restore a line's mobile data](#restore-a-line-s-mobile-data)
- `POST` [End a line](#end-a-line)

### List lines {#list-lines}

`GET /v1/numbers` · Partner API

Retrieves a paginated list of the lines in your organization — the numbers you sell and the eSIMs that carry them.

Every filter is optional and they combine, so this one endpoint answers both "the next page of my roster" and "the line on this number". Narrow by `msisdn` or `iccid` to look one up, by `userId` for the lines one customer holds, and by `type` or `state` for a slice of the roster.

A line that was just ordered appears here with `state: null` until its first lifecycle event, and its SIM details are published only once it reaches `READY`.

Requires the permission `numbers:read` on the key.

[Try it in the playground](https://developer.telgea.com/playground#tag/numbers/GET/v1/numbers). Calls run against your live organization; there is no sandbox.

**Parameters**

| Parameter | In | Type | Description |
| --- | --- | --- | --- |
| `page` | query | integer | Page to return, starting at 1. Example: `1` |
| `pageSize` | query | integer | Items per page, at most 100. Defaults to 50. Example: `50` |
| `orderBy` | query | enum | Field to sort by. Defaults to the order the lines were created in. `state` is not sortable: it is derived per line, so sorting by it would resolve the state of every line in your organization before a page could be picked. Narrow by it instead. Example: `createdAt` |
| `orderDirection` | query | enum | Sort direction. Only meaningful together with orderBy. Example: `asc` |
| `msisdn` | query | string | Only the line on this number, in E.164 format. Matched exactly. Example: `+4520123456` |
| `iccid` | query | string | Only the line whose eSIM has this ICCID. Matched exactly; a line with no SIM never matches. Example: `8945000000000000001` |
| `userId` | query | string (uuid) | Only the lines this user holds. Example: `9c1f2a6e-3b7d-4e0a-8f21-5d6c7b8a9e01` |
| `type` | query | enum | Only lines of this kind. Example: `local` |
| `state` | query | enum | Only lines in this state. Costs more than the other filters, since the state of each of your lines is resolved to answer it. Example: `READY` |

**Responses**

| Status | Meaning | Body |
| --- | --- | --- |
| `200` | Successfully retrieved lines. Returns a paginated list with the total count. | `ListNumbersResponse` |
| `400` | Request failed schema validation, or was refused by a business rule | none |
| `401` | Missing or invalid API key in the X-API-Key header | `UnauthorizedError` |
| `403` | Insufficient permissions to list lines | `ForbiddenError` |
| `429` | The API key has used its request quota for the current window. `Retry-After` says how many seconds until it resets. | `TooManyRequestsError` |
| `500` | Internal server error. Contact support if this persists. | `InternalError` |

**Response fields (200, ListNumbersResponse)**

| Field | Type | Description |
| --- | --- | --- |
| `page` | integer (required) | The page these items came from. Example: `1` |
| `pageSize` | integer (required) | Items per page, as requested. Example: `50` |
| `itemsCount` | integer (required) | Total items across all pages. Divide by pageSize to get the number of pages. Example: `142` |
| `items` | array of NumberListItem (required) | Lines on this page. |
| `items.id` | string (required) | UUID of the number. This is what SIM replacement and suspension act on. Example: `"8238c1b9-c2c0-4455-9b03-4bd787052709"` |
| `items.type` | enum (required) | Which line this is. One of: `local`, `travel`. Example: `"local"` |
| `items.countryCode` | string (required) | Market the number belongs to, ISO 3166-1 alpha-2. Example: `"DK"` |
| `items.phoneNumber` | string (required) | The number in E.164 format, or null until it has been provisioned. Example: `"+4520123456"` |
| `items.state` | enum (required) | Current state of the phone number in the provisioning lifecycle One of: `PENDING`, `PORTING`, `PORTING_FAILED`, `PROVISIONING`, `READY`, `REPLACING`, `CHANGING`, `SUSPENDING`, `SUSPENDED`, `RESTORING`, `RECONFIGURING`, `DEACTIVATING`, `DEACTIVATED`, `PORTING_DISCARDED`, `PORTING_OUT`, `PORTED_OUT`. Example: `"READY"` |
| `items.sim` | UserPlanSimDetails (required) | SIM details, included only when the number state is READY |
| `items.sim.iccid` | string (required) | ICCID of the eSIM profile. Example: `"8945000000000000001"` |
| `items.sim.activationCode` | string (required) | GSMA activation string for the eSIM. Render it as a QR code, or build an install link from it. Null until the profile has been issued. Example: `"LPA:1$SMDP.TELGEA.COM$34682-73063-9140"` |
| `items.sim.pinOne` | string (required) | PIN1 of the SIM, or null. Example: `"1234"` |
| `items.sim.pinTwo` | string (required) | PIN2 of the SIM, or null. Example: `"5678"` |
| `items.sim.pukOne` | string (required) | PUK1, needed after three wrong PIN1 entries, or null. Example: `"12345678"` |
| `items.sim.pukTwo` | string (required) | PUK2, needed after three wrong PIN2 entries, or null. Example: `"87654321"` |
| `items.userId` | string (required) | UUID of the user who holds the line. Example: `"9c1f2a6e-3b7d-4e0a-8f21-5d6c7b8a9e01"` |
| `items.createdAt` | string (required) | When the line was created, as an ISO 8601 UTC time. Example: `"2026-09-17T08:15:00.000Z"` |

**Example request**

```bash
curl -X GET "https://api.telgea.com/v1/numbers" \
  -H "x-api-key: $TELGEA_API_KEY"
```

**Response 200**

```json
{
  "page": 1,
  "pageSize": 50,
  "itemsCount": 2,
  "items": [
    {
      "id": "8238c1b9-c2c0-4455-9b03-4bd787052709",
      "userId": "9c1f2a6e-3b7d-4e0a-8f21-5d6c7b8a9e01",
      "type": "local",
      "countryCode": "DK",
      "phoneNumber": "+4520123456",
      "state": "READY",
      "sim": {
        "iccid": "8945000000000000001",
        "activationCode": "LPA:1$SMDP.TELGEA.COM$34682-73063-9140",
        "pinOne": "1234",
        "pinTwo": "5678",
        "pukOne": "12345678",
        "pukTwo": "87654321"
      },
      "createdAt": "2026-09-17T08:15:00.000Z"
    },
    {
      "id": "5a1c8e37-2d64-4b90-8fa2-6c0e9d4b7132",
      "userId": "3e5d1b42-7c90-4a18-b6f3-0d9e2a4c7f85",
      "type": "local",
      "countryCode": "SE",
      "phoneNumber": null,
      "state": "PROVISIONING",
      "sim": null,
      "createdAt": "2026-09-18T11:02:00.000Z"
    }
  ]
}
```

### Obtain a line {#obtain-a-line}

`POST /v1/numbers` · Partner API

Obtains a local line for one of your customers: a market-bound phone number and the eSIM that carries it.

The user must exist in your organization first — create one with POST /v1/users.

**Provisioning flow:**
1. This call returns the line's id and `state: PROVISIONING`
2. A SIM is assigned from available inventory and the number allocated with the local market's operator
3. The line reaches `READY`, and GET /v1/numbers/{numberId} carries its `sim.activationCode`

Organizations with Telgea's end-user communications enabled also send the user installation instructions by email. White-label integrations have them switched off, so that activation code is the only delivery and presenting it is yours to do.

Requires the permission `numbers:create-local` on the key.

[Try it in the playground](https://developer.telgea.com/playground#tag/numbers/POST/v1/numbers). Calls run against your live organization; there is no sandbox.

**Parameters**

| Parameter | In | Type | Description |
| --- | --- | --- | --- |
| `idempotency-key` | header | string | A value unique to this request, of 1 to 255 printable ASCII characters — a UUID is the usual choice. Retry with the same key within 24 hours and you get the original response back, even if it was a failure, and nothing is done twice. Send a new key whenever you change the request. Keys are private to your API key and organisation. Example: `0b7e4f1c-6a2d-4c9e-8f35-d1a7b2c93e60` |

**Request body**

| Field | Type | Description |
| --- | --- | --- |
| `userId` | string (uuid) (required) | UUID of an existing user to obtain the line for Example: `"9c1f2a6e-3b7d-4e0a-8f21-5d6c7b8a9e01"` |
| `countryCode` | string (required) | Two-character ISO country code of the market the line belongs to. Must be a valid ISO 3166-1 alpha-2 code (e.g., "DK", "US", "GB") and available in your organization's list of supported markets. Case-insensitive. Invalid codes are rejected immediately. Contact support to enable additional countries. Example: `"DK"` |

**Responses**

| Status | Meaning | Body |
| --- | --- | --- |
| `202` | Line accepted and being provisioned. Poll GET /v1/numbers/{numberId} until it reaches READY with its SIM. | `CreateNumberResponse` |
| `400` | Request failed schema validation, or the country code is not a supported ISO 3166-1 alpha-2 code | none |
| `401` | Missing or invalid API key in the X-API-Key header | `UnauthorizedError` |
| `403` | Insufficient permissions, or the requested country is not available for your organization: nothing it can buy covers the country, or the country requires business verification your organization has not passed. | `ForbiddenError` |
| `404` | User not found in your organization, or no plan is available for the requested market. | `NotFoundError` |
| `409` | The user already holds an active line, so nothing was created. | `ConflictError` |
| `429` | The API key has used its request quota for the current window. `Retry-After` says how many seconds until it resets. | `TooManyRequestsError` |
| `500` | Internal server error. Contact support if this persists. | `InternalError` |

**Response fields (202, CreateNumberResponse)**

| Field | Type | Description |
| --- | --- | --- |
| `numberId` | string (required) | UUID of the line being obtained. Example: `"8238c1b9-c2c0-4455-9b03-4bd787052709"` |
| `state` | enum (required) | State the line starts in. Poll GET /v1/numbers/{numberId} until it reaches READY. One of: `PENDING`, `PORTING`, `PORTING_FAILED`, `PROVISIONING`, `READY`, `REPLACING`, `CHANGING`, `SUSPENDING`, `SUSPENDED`, `RESTORING`, `RECONFIGURING`, `DEACTIVATING`, `DEACTIVATED`, `PORTING_DISCARDED`, `PORTING_OUT`, `PORTED_OUT`. Example: `"PROVISIONING"` |

**Example request**

```bash
curl -X POST "https://api.telgea.com/v1/numbers" \
  -H "x-api-key: $TELGEA_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
  "userId": "9c1f2a6e-3b7d-4e0a-8f21-5d6c7b8a9e01",
  "countryCode": "DK"
}'
```

**Response 202**

```json
{
  "numberId": "8238c1b9-c2c0-4455-9b03-4bd787052709",
  "state": "PROVISIONING"
}
```

### Get a line {#get-a-line}

`GET /v1/numbers/{numberId}` · Partner API

Retrieves one line in full: the number, where it is in the provisioning lifecycle, its eSIM, when it last changed state, when it first went into service, the eSIMs it carried before its current one, and the date it is due to end if a termination is scheduled.

Take `sim.activationCode` — a GSMA `LPA:1$…` string — and encode it as a QR code to install the eSIM; any QR library will do. SIM details are published only while the line is `READY`, so during a replacement `sim` reads `null` rather than handing out a code that has been revoked.

A line in another organization answers exactly as one that does not exist.

Requires the permission `numbers:read` on the key.

[Try it in the playground](https://developer.telgea.com/playground#tag/numbers/GET/v1/numbers/{numberId}). Calls run against your live organization; there is no sandbox.

**Parameters**

| Parameter | In | Type | Description |
| --- | --- | --- | --- |
| `numberId` | path | string (uuid) (required) | UUID of the line. Example: `8238c1b9-c2c0-4455-9b03-4bd787052709` |

**Responses**

| Status | Meaning | Body |
| --- | --- | --- |
| `200` | Successfully retrieved the line. | `NumberDetails` |
| `400` | Request failed schema validation, or was refused by a business rule | none |
| `401` | Missing or invalid API key in the X-API-Key header | `UnauthorizedError` |
| `403` | Insufficient permissions to read lines | `ForbiddenError` |
| `404` | No line in your organization has this id. | `NotFoundError` |
| `429` | The API key has used its request quota for the current window. `Retry-After` says how many seconds until it resets. | `TooManyRequestsError` |
| `500` | Internal server error. Contact support if this persists. | `InternalError` |

**Response fields (200, NumberDetails)**

| Field | Type | Description |
| --- | --- | --- |
| `id` | string (required) | UUID of the number. This is what SIM replacement and suspension act on. Example: `"8238c1b9-c2c0-4455-9b03-4bd787052709"` |
| `type` | enum (required) | Which line this is. One of: `local`, `travel`. Example: `"local"` |
| `countryCode` | string (required) | Market the number belongs to, ISO 3166-1 alpha-2. Example: `"DK"` |
| `phoneNumber` | string (required) | The number in E.164 format, or null until it has been provisioned. Example: `"+4520123456"` |
| `state` | enum (required) | Current state of the phone number in the provisioning lifecycle One of: `PENDING`, `PORTING`, `PORTING_FAILED`, `PROVISIONING`, `READY`, `REPLACING`, `CHANGING`, `SUSPENDING`, `SUSPENDED`, `RESTORING`, `RECONFIGURING`, `DEACTIVATING`, `DEACTIVATED`, `PORTING_DISCARDED`, `PORTING_OUT`, `PORTED_OUT`. Example: `"READY"` |
| `sim` | UserPlanSimDetails (required) | SIM details, included only when the number state is READY |
| `sim.iccid` | string (required) | ICCID of the eSIM profile. Example: `"8945000000000000001"` |
| `sim.activationCode` | string (required) | GSMA activation string for the eSIM. Render it as a QR code, or build an install link from it. Null until the profile has been issued. Example: `"LPA:1$SMDP.TELGEA.COM$34682-73063-9140"` |
| `sim.pinOne` | string (required) | PIN1 of the SIM, or null. Example: `"1234"` |
| `sim.pinTwo` | string (required) | PIN2 of the SIM, or null. Example: `"5678"` |
| `sim.pukOne` | string (required) | PUK1, needed after three wrong PIN1 entries, or null. Example: `"12345678"` |
| `sim.pukTwo` | string (required) | PUK2, needed after three wrong PIN2 entries, or null. Example: `"87654321"` |
| `userId` | string (required) | UUID of the user who holds the line. Example: `"9c1f2a6e-3b7d-4e0a-8f21-5d6c7b8a9e01"` |
| `createdAt` | string (required) | When the line was created, as an ISO 8601 UTC time. Example: `"2026-09-17T08:15:00.000Z"` |
| `stateUpdatedAt` | string (required) | When the line last reached the state it is in, as an ISO 8601 UTC time. Null for a line with no state yet. Example: `"2026-09-17T08:15:00.000Z"` |
| `terminationScheduledAt` | string (required) | The date this line is scheduled to end, or null when no termination is scheduled. Set by POST /v1/numbers/{numberId}/termination. Example: `"2026-10-01T00:00:00.000Z"` |
| `activatedAt` | string (required) | When the line first went into service, as an ISO 8601 UTC time: when it was provisioned, or when its number was ported in. Null until then. Example: `"2026-09-17T08:20:00.000Z"` |
| `previousSims` | array of PreviousSim (required) | The eSIMs the line carried before its current one, newest first. Each SIM replacement adds one. Empty for a line whose eSIM has never been replaced. |
| `previousSims.iccid` | string (required) | ICCID of the eSIM profile. Example: `"89462000099812030017"` |
| `previousSims.inServiceFrom` | string (required) | When this eSIM was issued to the line, as an ISO 8601 UTC time. Example: `"2026-03-02T09:00:00.000Z"` |
| `previousSims.inServiceTo` | string (required) | When the eSIM that replaced it was issued, as an ISO 8601 UTC time. Example: `"2026-09-14T08:00:00.000Z"` |

**Example request**

```bash
curl -X GET "https://api.telgea.com/v1/numbers/8238c1b9-c2c0-4455-9b03-4bd787052709" \
  -H "x-api-key: $TELGEA_API_KEY"
```

**Response 200**

```json
{
  "id": "8238c1b9-c2c0-4455-9b03-4bd787052709",
  "userId": "9c1f2a6e-3b7d-4e0a-8f21-5d6c7b8a9e01",
  "type": "local",
  "countryCode": "DK",
  "phoneNumber": "+4520123456",
  "state": "READY",
  "sim": {
    "iccid": "8945000000000000001",
    "activationCode": "LPA:1$SMDP.TELGEA.COM$34682-73063-9140",
    "pinOne": "1234",
    "pinTwo": "5678",
    "pukOne": "12345678",
    "pukTwo": "87654321"
  },
  "createdAt": "2026-09-17T08:15:00.000Z",
  "stateUpdatedAt": "2026-10-01T10:00:00.000Z",
  "terminationScheduledAt": null,
  "activatedAt": "2026-09-17T08:20:00.000Z",
  "previousSims": [
    {
      "iccid": "89462000099812030017",
      "inServiceFrom": "2026-09-17T08:20:00.000Z",
      "inServiceTo": "2026-10-01T10:00:00.000Z"
    }
  ]
}
```

### Get a line's connection status {#get-a-line-s-connection-status}

`GET /v1/numbers/{numberId}/connection` · Partner API

Reads what the network reports about one line: its status there (active, suspended or inactive), when it last saw activity on the line, the country and operator the line is attached to, the network type, and the IP address, APN and device IMEI in use.

**A line is read at most once per 5-minute window.** The windows are fixed, starting on the clock's 5-minute marks rather than at a request. A request inside a window gets the answer the network gave at `checkedAt`, whoever asked first, without the network being asked again — so polling more often returns the same answer. The first request in the next window reads the line again, however recent the last read. A failed read is answered again the same way until its window ends. Reads of many lines are answered a few at a time per network, so a loop over a large roster takes a while.

Some lines cannot be read: those in a market whose network does not report connection status, those with no phone number or eSIM yet, and those still being ported in or already ended. They answer `200` with `available: false` and every other field null.

A line in another organization answers exactly as one that does not exist.

Requires the permission `numbers:read` on the key.

[Try it in the playground](https://developer.telgea.com/playground#tag/numbers/GET/v1/numbers/{numberId}/connection). Calls run against your live organization; there is no sandbox.

**Parameters**

| Parameter | In | Type | Description |
| --- | --- | --- | --- |
| `numberId` | path | string (uuid) (required) | UUID of the line. Example: `8238c1b9-c2c0-4455-9b03-4bd787052709` |

**Responses**

| Status | Meaning | Body |
| --- | --- | --- |
| `200` | The line's connection status, or `available: false` for a line that cannot be read. | `NumberConnection` |
| `400` | Request failed schema validation, or was refused by a business rule | none |
| `401` | Missing or invalid API key in the X-API-Key header | `UnauthorizedError` |
| `403` | Insufficient permissions to read lines | `ForbiddenError` |
| `404` | No line in your organization has this id. | `NotFoundError` |
| `429` | The API key has used its request quota for the current window. `Retry-After` says how many seconds until it resets. | `TooManyRequestsError` |
| `500` | Internal server error. Contact support if this persists. | `InternalError` |
| `503` | The network serving this line did not answer, so its connection status could not be read. | `ServiceUnavailableError` |

**Response fields (200, NumberConnection)**

| Field | Type | Description |
| --- | --- | --- |
| `available` | boolean (required) | Whether the line's network could be asked. False for a line in a market whose network does not report connection status, one with no phone number or eSIM yet, and one still being ported in or already ended; every other field is then null. Example: `true` |
| `status` | enum (required) | How the network holds the line: `active`, `suspended` or `inactive`, or `unknown` when the network does not say. One of: `active`, `suspended`, `inactive`, `unknown`. Example: `"active"` |
| `lastSeenAt` | string (required) | When the network last saw activity on the line, as an ISO 8601 UTC time. Null when the network does not report it. Example: `"2026-10-19T11:58:00.000Z"` |
| `countryCode` | string (required) | The country the line is attached in, ISO 3166-1 alpha-2. Null when the network does not report it. Example: `"DK"` |
| `servingNetwork` | string (required) | The name of the network operator serving the line. Null when the network does not report it. Example: `"TDC"` |
| `accessTechnology` | enum (required) | The network type the line is attached on, or `unknown` when the network does not say. One of: `2G`, `3G`, `4G`, `5G`, `unknown`. Example: `"4G"` |
| `ipAddress` | string (required) | The IP address the line holds for data. Null when the network does not report it. Example: `"10.20.30.40"` |
| `apn` | string (required) | The access point name the line uses for data. Null when the network does not report it. Example: `"internet"` |
| `imei` | string (required) | The IMEI of the device the line was last seen in. Null when the network does not report it. Example: `"356938035643809"` |
| `checkedAt` | string (required) | When the network was asked, as an ISO 8601 UTC time. A read is shared for the rest of its 5-minute window, so this can be up to 5 minutes earlier than your request. Example: `"2026-10-19T12:00:00.000Z"` |

**Example request**

```bash
curl -X GET "https://api.telgea.com/v1/numbers/8238c1b9-c2c0-4455-9b03-4bd787052709/connection" \
  -H "x-api-key: $TELGEA_API_KEY"
```

**Response 200**

```json
{
  "available": true,
  "status": "active",
  "lastSeenAt": "2026-10-19T11:58:00.000Z",
  "countryCode": "DK",
  "servingNetwork": "TDC",
  "accessTechnology": "4G",
  "ipAddress": "10.20.30.40",
  "apn": "internet",
  "imei": "356938035643809",
  "checkedAt": "2026-10-19T12:00:00.000Z"
}
```

### Replace a SIM card {#replace-a-sim-card}

`POST /v1/numbers/{numberId}/sim-replacement` · Partner API

Initiates a SIM card replacement (eSIM swap) on one line. This provisions a new eSIM and deactivates the previous one.

> **Important:** This endpoint should **only** be used when the end-user changes devices and the existing eSIM activation QR code (LPA string) has been confirmed to be expired or no longer working. Do **not** use this endpoint to troubleshoot connectivity issues — contact support instead.

**Rate limit:** one replacement per line inside the cooldown your organization's SIM-swap offering sets, counted from when the line's last replacement finished — and once per calendar day for a German number. A request inside the window gets a `429` naming when to retry.

**Flow:**
1. A new eSIM profile is provisioned and the old SIM is deactivated
2. Until the new profile is ready, GET /v1/numbers/{numberId} reports the line with `sim: null` — its state is `REPLACING`, and SIM details are published only in `READY`
3. Back in `READY`, the line's `sim.activationCode` is the new one to render as a QR code

Organizations with Telgea's end-user communications enabled also email the user the new activation code. White-label integrations have them switched off and present it themselves.

Requires the permission `numbers:replace-sim` on the key.

[Try it in the playground](https://developer.telgea.com/playground#tag/numbers/POST/v1/numbers/{numberId}/sim-replacement). Calls run against your live organization; there is no sandbox.

**Parameters**

| Parameter | In | Type | Description |
| --- | --- | --- | --- |
| `numberId` | path | string (uuid) (required) | UUID of the line. Example: `8238c1b9-c2c0-4455-9b03-4bd787052709` |
| `idempotency-key` | header | string | A value unique to this request, of 1 to 255 printable ASCII characters — a UUID is the usual choice. Retry with the same key within 24 hours and you get the original response back, even if it was a failure, and nothing is done twice. Send a new key whenever you change the request. Keys are private to your API key and organisation. Example: `0b7e4f1c-6a2d-4c9e-8f35-d1a7b2c93e60` |

**Responses**

| Status | Meaning | Body |
| --- | --- | --- |
| `202` | SIM replacement request accepted and processed asynchronously. Poll GET /v1/numbers/{numberId} until the line is READY again with its new SIM. | `ReplaceSimResponse` |
| `400` | Request failed schema validation, or was refused by a business rule | none |
| `401` | Missing or invalid API key in the X-API-Key header | `UnauthorizedError` |
| `403` | Insufficient permissions to replace SIM cards | `ForbiddenError` |
| `404` | No line in your organization has this id. | `NotFoundError` |
| `429` | The line's last SIM replacement finished too recently for another: your organization's SIM-swap offering sets the cooldown (a German number is replaced once per calendar day), and `Retry-After` says when to retry. The same status also answers a key that has used its request quota. | `TooManyRequestsError` |
| `500` | Internal server error. Contact support if this persists. | `InternalError` |

**Response fields (202, ReplaceSimResponse)**

| Field | Type | Description |
| --- | --- | --- |
| `status` | string (required) | Status of the SIM replacement request Example: `"accepted"` |

**Example request**

```bash
curl -X POST "https://api.telgea.com/v1/numbers/8238c1b9-c2c0-4455-9b03-4bd787052709/sim-replacement" \
  -H "x-api-key: $TELGEA_API_KEY"
```

**Response 202**

```json
{
  "status": "accepted"
}
```

### Suspend a line {#suspend-a-line}

`POST /v1/numbers/{numberId}/suspension` · Partner API

Stops all traffic on one line, domestic and international — for a phone that has been lost or stolen. To stop only mobile data and leave the line usable, use the data-restriction endpoint.

The call returns once the line is down at the network, so a `204` means the service is genuinely stopped.

Suspending a line that is already suspended returns `409` and changes nothing.

Not every market offers suspension. Where it does not, this returns `400` and the line stays live — the Markets page in the documentation lists which is which.

Requires the permission `numbers:suspend` on the key.

[Try it in the playground](https://developer.telgea.com/playground#tag/numbers/POST/v1/numbers/{numberId}/suspension). Calls run against your live organization; there is no sandbox.

**Parameters**

| Parameter | In | Type | Description |
| --- | --- | --- | --- |
| `numberId` | path | string (uuid) (required) | UUID of the line. Example: `8238c1b9-c2c0-4455-9b03-4bd787052709` |
| `idempotency-key` | header | string | A value unique to this request, of 1 to 255 printable ASCII characters — a UUID is the usual choice. Retry with the same key within 24 hours and you get the original response back, even if it was a failure, and nothing is done twice. Send a new key whenever you change the request. Keys are private to your API key and organisation. Example: `0b7e4f1c-6a2d-4c9e-8f35-d1a7b2c93e60` |

**Responses**

| Status | Meaning | Body |
| --- | --- | --- |
| `204` | Line suspended. No content returned. | none |
| `400` | Request failed schema validation, or was refused by a business rule | none |
| `401` | Missing or invalid API key in the X-API-Key header | `UnauthorizedError` |
| `403` | Insufficient permissions for this action | `ForbiddenError` |
| `404` | No line in your organization has this id. | `NotFoundError` |
| `409` | Already in the state you asked for, so nothing was changed. | `ConflictError` |
| `429` | The API key has used its request quota for the current window. `Retry-After` says how many seconds until it resets. | `TooManyRequestsError` |
| `500` | Internal server error. Contact support if this persists. | `InternalError` |

**Example request**

```bash
curl -X POST "https://api.telgea.com/v1/numbers/8238c1b9-c2c0-4455-9b03-4bd787052709/suspension" \
  -H "x-api-key: $TELGEA_API_KEY"
```

### Restore a suspended line {#restore-a-suspended-line}

`DELETE /v1/numbers/{numberId}/suspension` · Partner API

Undoes a suspension made with `POST /v1/numbers/{numberId}/suspension`, and returns once the line is live again at the network.

Restoring a line that is not suspended returns `409`.

Requires the permission `numbers:unsuspend` on the key.

[Try it in the playground](https://developer.telgea.com/playground#tag/numbers/DELETE/v1/numbers/{numberId}/suspension). Calls run against your live organization; there is no sandbox.

**Parameters**

| Parameter | In | Type | Description |
| --- | --- | --- | --- |
| `numberId` | path | string (uuid) (required) | UUID of the line. Example: `8238c1b9-c2c0-4455-9b03-4bd787052709` |
| `idempotency-key` | header | string | A value unique to this request, of 1 to 255 printable ASCII characters — a UUID is the usual choice. Retry with the same key within 24 hours and you get the original response back, even if it was a failure, and nothing is done twice. Send a new key whenever you change the request. Keys are private to your API key and organisation. Example: `0b7e4f1c-6a2d-4c9e-8f35-d1a7b2c93e60` |

**Responses**

| Status | Meaning | Body |
| --- | --- | --- |
| `204` | Line restored. No content returned. | none |
| `400` | Request failed schema validation, or was refused by a business rule | none |
| `401` | Missing or invalid API key in the X-API-Key header | `UnauthorizedError` |
| `403` | Insufficient permissions for this action | `ForbiddenError` |
| `404` | No line in your organization has this id. | `NotFoundError` |
| `409` | Already in the state you asked for, so nothing was changed. | `ConflictError` |
| `429` | The API key has used its request quota for the current window. `Retry-After` says how many seconds until it resets. | `TooManyRequestsError` |
| `500` | Internal server error. Contact support if this persists. | `InternalError` |

**Example request**

```bash
curl -X DELETE "https://api.telgea.com/v1/numbers/8238c1b9-c2c0-4455-9b03-4bd787052709/suspension" \
  -H "x-api-key: $TELGEA_API_KEY"
```

### Stop a line's mobile data {#stop-a-line-s-mobile-data}

`POST /v1/numbers/{numberId}/data-restriction` · Partner API

Stops mobile data on one line — for a customer who has used up what they paid for. Calls and texts keep working; use the suspension endpoint to stop the whole line.

The call returns once the change has taken effect at the network, so a `200` means the data is genuinely off. Nothing here is queued for later.

Stopping data that is already stopped returns `409` and changes nothing. Our own automated processes never undo a stop you made — only `DELETE` on this path does.

Data is stopped against the data pool the line draws on, so a line in none of your pools returns `422`. Not every market offers stopping data on its own either; where it does not, this returns `422` and nothing changes — the Markets page in the documentation lists which is which.

Requires the permission `numbers:suspend` on the key.

[Try it in the playground](https://developer.telgea.com/playground#tag/numbers/POST/v1/numbers/{numberId}/data-restriction). Calls run against your live organization; there is no sandbox.

**Parameters**

| Parameter | In | Type | Description |
| --- | --- | --- | --- |
| `numberId` | path | string (uuid) (required) | UUID of the line. Example: `8238c1b9-c2c0-4455-9b03-4bd787052709` |
| `idempotency-key` | header | string | A value unique to this request, of 1 to 255 printable ASCII characters — a UUID is the usual choice. Retry with the same key within 24 hours and you get the original response back, even if it was a failure, and nothing is done twice. Send a new key whenever you change the request. Keys are private to your API key and organisation. Example: `0b7e4f1c-6a2d-4c9e-8f35-d1a7b2c93e60` |

**Request body**

| Field | Type | Description |
| --- | --- | --- |
| `reason` | string | Free text kept with the change and shown to our support staff. Example: `"Customer exceeded their agreed data allowance."` |

**Responses**

| Status | Meaning | Body |
| --- | --- | --- |
| `200` | Data stopped. Lists the numbers the stop reached and when it took effect. | `DataRestrictionResponse` |
| `400` | Request failed schema validation, or was refused by a business rule | none |
| `401` | Missing or invalid API key in the X-API-Key header | `UnauthorizedError` |
| `403` | Insufficient permissions for this action | `ForbiddenError` |
| `404` | No line in your organization has this id. | `NotFoundError` |
| `409` | Already in the state you asked for, so nothing was changed. | `ConflictError` |
| `422` | Nothing was changed: the line draws on none of your data pools, so there is no data to stop, or its market does not offer stopping data on its own. | `UnprocessableEntityError` |
| `429` | The API key has used its request quota for the current window. `Retry-After` says how many seconds until it resets. | `TooManyRequestsError` |
| `500` | Internal server error. Contact support if this persists. | `InternalError` |

**Response fields (200, DataRestrictionResponse)**

| Field | Type | Description |
| --- | --- | --- |
| `numbers` | array of string (required) | The phone numbers the request actually reached at the network. Example: `["+4520123456"]` |
| `effectiveAt` | string (required) | When the change took effect at the network. Example: `"2026-09-14T09:30:00.000Z"` |

**Example request**

```bash
curl -X POST "https://api.telgea.com/v1/numbers/8238c1b9-c2c0-4455-9b03-4bd787052709/data-restriction" \
  -H "x-api-key: $TELGEA_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
  "reason": "Customer exceeded their agreed data allowance."
}'
```

**Response 200**

```json
{
  "numbers": [
    "+4520123456"
  ],
  "effectiveAt": "2026-09-14T09:30:00.000Z"
}
```

### Restore a line's mobile data {#restore-a-line-s-mobile-data}

`DELETE /v1/numbers/{numberId}/data-restriction` · Partner API

Undoes a stop made with `POST /v1/numbers/{numberId}/data-restriction`, and returns once data is live again at the network.

Restoring data that is not stopped returns `409`. Data stays off if the customer is also over an allowance you set — clear that first.

Requires the permission `numbers:unsuspend` on the key.

[Try it in the playground](https://developer.telgea.com/playground#tag/numbers/DELETE/v1/numbers/{numberId}/data-restriction). Calls run against your live organization; there is no sandbox.

**Parameters**

| Parameter | In | Type | Description |
| --- | --- | --- | --- |
| `numberId` | path | string (uuid) (required) | UUID of the line. Example: `8238c1b9-c2c0-4455-9b03-4bd787052709` |
| `reason` | query | string | Free text kept with the change. Example: `Customer settled their account.` |
| `idempotency-key` | header | string | A value unique to this request, of 1 to 255 printable ASCII characters — a UUID is the usual choice. Retry with the same key within 24 hours and you get the original response back, even if it was a failure, and nothing is done twice. Send a new key whenever you change the request. Keys are private to your API key and organisation. Example: `0b7e4f1c-6a2d-4c9e-8f35-d1a7b2c93e60` |

**Responses**

| Status | Meaning | Body |
| --- | --- | --- |
| `200` | Data restored. Lists the numbers the restore reached and when it took effect. | `DataRestrictionResponse` |
| `400` | Request failed schema validation, or was refused by a business rule | none |
| `401` | Missing or invalid API key in the X-API-Key header | `UnauthorizedError` |
| `403` | Insufficient permissions for this action | `ForbiddenError` |
| `404` | No line in your organization has this id. | `NotFoundError` |
| `409` | Already in the state you asked for, so nothing was changed. | `ConflictError` |
| `429` | The API key has used its request quota for the current window. `Retry-After` says how many seconds until it resets. | `TooManyRequestsError` |
| `500` | Internal server error. Contact support if this persists. | `InternalError` |

**Response fields (200, DataRestrictionResponse)**

| Field | Type | Description |
| --- | --- | --- |
| `numbers` | array of string (required) | The phone numbers the request actually reached at the network. Example: `["+4520123456"]` |
| `effectiveAt` | string (required) | When the change took effect at the network. Example: `"2026-09-14T09:30:00.000Z"` |

**Example request**

```bash
curl -X DELETE "https://api.telgea.com/v1/numbers/8238c1b9-c2c0-4455-9b03-4bd787052709/data-restriction" \
  -H "x-api-key: $TELGEA_API_KEY"
```

**Response 200**

```json
{
  "numbers": [
    "+4520123456"
  ],
  "effectiveAt": "2026-09-14T09:30:00.000Z"
}
```

### End a line {#end-a-line}

`POST /v1/numbers/{numberId}/termination` · Partner API

Ends the line on the date you name — the date the customer agreed to stop.

The line is suspended on that date and deactivated at the network 14 days later. The call returns as soon as the termination is scheduled, so a `202` means it is booked, not that the line is already down. Read it back on `GET /v1/numbers/{numberId}` as `terminationScheduledAt`.

**Billing is not prorated.** The customer keeps the period they already bought: the line stops on your date, and billing runs to `activeUntil` in the response. The plan does not renew afterwards.

Send `deleteUser: true` to delete the end-user along with the line. Otherwise the user remains, and `DELETE /v1/users/{userId}` succeeds once the line is suspended — you do not have to wait out the grace period.

The response lists every line the termination ends, which can be more than the one you named: a travel eSIM raised against this line's plan ends with it.

Requires the permission `orders:cancel` on the key.

[Try it in the playground](https://developer.telgea.com/playground#tag/numbers/POST/v1/numbers/{numberId}/termination). Calls run against your live organization; there is no sandbox.

**Parameters**

| Parameter | In | Type | Description |
| --- | --- | --- | --- |
| `numberId` | path | string (uuid) (required) | UUID of the line. Example: `8238c1b9-c2c0-4455-9b03-4bd787052709` |
| `idempotency-key` | header | string | A value unique to this request, of 1 to 255 printable ASCII characters — a UUID is the usual choice. Retry with the same key within 24 hours and you get the original response back, even if it was a failure, and nothing is done twice. Send a new key whenever you change the request. Keys are private to your API key and organisation. Example: `0b7e4f1c-6a2d-4c9e-8f35-d1a7b2c93e60` |

**Request body**

| Field | Type | Description |
| --- | --- | --- |
| `terminationDate` | string (date) (required) | The date the customer agreed to stop, as YYYY-MM-DD. Today is allowed; a past date is rejected. Example: `"2026-10-01"` |
| `deleteUser` | boolean | Delete the end-user once their line is gone. Defaults to false, in which case the user remains and can be deleted with DELETE /v1/users/{userId} once the line is suspended. Example: `false` |

**Responses**

| Status | Meaning | Body |
| --- | --- | --- |
| `202` | Termination scheduled. States the date, when billing stops, and the lines ending. | `TerminationResponse` |
| `400` | Request failed schema validation, or was refused by a business rule | none |
| `401` | Missing or invalid API key in the X-API-Key header | `UnauthorizedError` |
| `403` | Insufficient permissions for this action | `ForbiddenError` |
| `404` | No plan to end stands against this line in your organization | `NotFoundError` |
| `429` | The API key has used its request quota for the current window. `Retry-After` says how many seconds until it resets. | `TooManyRequestsError` |
| `500` | Internal server error. Contact support if this persists. | `InternalError` |

**Response fields (202, TerminationResponse)**

| Field | Type | Description |
| --- | --- | --- |
| `terminationDate` | string (required) | The date the line stops, as accepted. Example: `"2026-10-01"` |
| `activeUntil` | string (required) | The end of the period already paid for. Billing runs to this date even when the line stops earlier; null when the plan carried no billing period. Example: `"2026-12-31T00:00:00.000Z"` |
| `numberIds` | array of string (required) | The lines this termination ends, by their number ids. Example: `["9f1c6f3e-4f4a-4f2e-bb2a-2b9a1f0c8e11"]` |

**Example request**

```bash
curl -X POST "https://api.telgea.com/v1/numbers/8238c1b9-c2c0-4455-9b03-4bd787052709/termination" \
  -H "x-api-key: $TELGEA_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
  "terminationDate": "2026-10-01",
  "deleteUser": true
}'
```

**Response 202**

```json
{
  "terminationDate": "2026-10-01",
  "activeUntil": "2026-12-31T00:00:00.000Z",
  "numberIds": [
    "8238c1b9-c2c0-4455-9b03-4bd787052709"
  ]
}
```
