# Cost thresholds

What people may spend per month on a usage type, such as international calls, before it is paused: set per organization, team or user, and read back with each user's spend.

> Enterprise API · https://developer.telgea.com/docs/enterprise/api/cost-thresholds

## The cost threshold object {#object}

What people may spend per month on a usage type, such as international calls, before it is paused.

| Field | Type | Description |
| --- | --- | --- |
| `id` | string (required) | UUID of the threshold. Example: `"5d0b2c1e-7f3a-4b6c-9e8d-2a1f0c3b4d5e"` |
| `usageType` | enum (required) | The usage type the threshold is on. `VOICE` is international calling: reaching it pauses international calls and SMS on the person's lines, where their market offers the pause. Other types answer `422` until the platform can enforce them. One of: `DATA`, `VOICE`, `SMS`, `MMS`. Example: `"VOICE"` |
| `scope` | enum (required) | Whose threshold this is: the organization's default, a team's, or one user's own. One of: `organization`, `team`, `user`. Example: `"team"` |
| `teamId` | string (required) | The team, for a team threshold. Example: `"2f6b0d3a-8c1e-4a7f-9b2d-1e3c4d5f6a70"` |
| `userId` | string (required) | The user, for a user threshold. Example: `null` |
| `maxAmount` | number (required) | What one person may spend on the usage type per month, in `currency`. Example: `50` |
| `currency` | string (required) | ISO 4217 code of the threshold's money: the team's cost-center currency, else the organization's primary. Example: `"EUR"` |
| `period` | enum (required) | The period the spend is counted in. Always the calendar month. One of: `monthly`. Example: `"monthly"` |
| `validFrom` | string (required) | When the threshold opens (ISO 8601). A threshold lowered below someone's spend opens next month. Example: `"2026-10-01T00:00:00.000Z"` |
| `validTo` | string (required) | When the threshold closes (ISO 8601), or null while it stands. Example: `null` |

## Operations

- `GET` [List cost thresholds](#list-cost-thresholds)
- `PUT` [Set a cost threshold](#set-a-cost-threshold)
- `DELETE` [Remove a cost threshold](#remove-a-cost-threshold)

### List cost thresholds {#list-cost-thresholds}

`GET /v1/cost-thresholds` · Enterprise API + Partner API

Lists what people in your organization may spend per month on a usage type: the organization's own threshold; with `teamId`, that team's own and the own thresholds of the people in it; with `userId`, that user's own. A threshold that opens next month is listed with its `validFrom` in the future. Omit `usageType` for every type.

A team or user of another organization answers `404`; a usage type nothing can enforce yet answers `422`. A user falls under their own threshold, else their team's, else the organization's. To see which one a user is under, with their spend this month, use `GET /v1/users/{userId}/cost-thresholds/{usageType}`.

`currency` is the money a threshold written for the named team or user would carry: their cost-center currency, else the organization's primary.

**Scope:** `policies:read`, and `teams:read` when a team is named.

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

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

**Parameters**

| Parameter | In | Type | Description |
| --- | --- | --- | --- |
| `usageType` | query | enum | The usage type the threshold is on. `VOICE` is international calling: reaching it pauses international calls and SMS on the person's lines, where their market offers the pause. Other types answer `422` until the platform can enforce them. Example: `VOICE` |
| `teamId` | query | string (uuid) | UUID of the team the threshold is for. Omit with `userId` for the organization's own. Example: `2f6b0d3a-8c1e-4a7f-9b2d-1e3c4d5f6a70` |
| `userId` | query | string (uuid) | UUID of the user the threshold is for. Omit with `teamId` for the organization's own. Example: `9c1f2a6e-3b7d-4e0a-8f21-5d6c7b8a9e01` |

**Responses**

| Status | Meaning | Body |
| --- | --- | --- |
| `200` | The thresholds in force or opening next month. | `ListCostThresholdsResponse` |
| `400` | Request failed schema validation, or named both a team and a user | none |
| `401` | Missing or invalid API key in the X-API-Key header | `UnauthorizedError` |
| `403` | Insufficient permissions to view policies | `ForbiddenError` |
| `404` | No team in your organization has this id, so nothing was read or changed. No user in your organization has this id, so nothing was read or changed. | `NotFoundError` |
| `422` | No threshold can stand on this usage type yet, so nothing was read or changed. | `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, ListCostThresholdsResponse)**

| Field | Type | Description |
| --- | --- | --- |
| `thresholds` | array of CostThreshold (required) | The organization's thresholds in force or opening next month, and the named team's or user's own. |
| `thresholds.id` | string (required) | UUID of the threshold. Example: `"5d0b2c1e-7f3a-4b6c-9e8d-2a1f0c3b4d5e"` |
| `thresholds.usageType` | enum (required) | The usage type the threshold is on. `VOICE` is international calling: reaching it pauses international calls and SMS on the person's lines, where their market offers the pause. Other types answer `422` until the platform can enforce them. One of: `DATA`, `VOICE`, `SMS`, `MMS`. Example: `"VOICE"` |
| `thresholds.scope` | enum (required) | Whose threshold this is: the organization's default, a team's, or one user's own. One of: `organization`, `team`, `user`. Example: `"team"` |
| `thresholds.teamId` | string (required) | The team, for a team threshold. Example: `"2f6b0d3a-8c1e-4a7f-9b2d-1e3c4d5f6a70"` |
| `thresholds.userId` | string (required) | The user, for a user threshold. Example: `null` |
| `thresholds.maxAmount` | number (required) | What one person may spend on the usage type per month, in `currency`. Example: `50` |
| `thresholds.currency` | string (required) | ISO 4217 code of the threshold's money: the team's cost-center currency, else the organization's primary. Example: `"EUR"` |
| `thresholds.period` | enum (required) | The period the spend is counted in. Always the calendar month. One of: `monthly`. Example: `"monthly"` |
| `thresholds.validFrom` | string (required) | When the threshold opens (ISO 8601). A threshold lowered below someone's spend opens next month. Example: `"2026-10-01T00:00:00.000Z"` |
| `thresholds.validTo` | string (required) | When the threshold closes (ISO 8601), or null while it stands. Example: `null` |
| `currency` | string | ISO 4217 code a threshold written for the named team or user would carry. Absent when neither is named. Example: `"EUR"` |

**Example request**

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

**Response 200**

```json
{
  "thresholds": [
    {
      "id": "5d0b2c1e-7f3a-4b6c-9e8d-2a1f0c3b4d5e",
      "usageType": "VOICE",
      "scope": "team",
      "teamId": "2f6b0d3a-8c1e-4a7f-9b2d-1e3c4d5f6a70",
      "userId": null,
      "maxAmount": 50,
      "currency": "EUR",
      "period": "monthly",
      "validFrom": "2026-10-01T00:00:00.000Z",
      "validTo": null
    }
  ],
  "currency": "EUR"
}
```

### Set a cost threshold {#set-a-cost-threshold}

`PUT /v1/cost-thresholds` · Enterprise API + Partner API

Sets what one person may spend per month on a usage type: for the organization, for a team (`teamId`), or for one user (`userId`). A new amount replaces the scope's current one on that usage type.

`VOICE` is international calling: once a user's spend reaches the threshold, international calls and SMS on their lines are paused until the next month, where their market offers the pause; elsewhere the threshold warns only. Other usage types answer `422` until the platform can enforce them.

The amount is in the team's cost-center currency, else the organization's primary; read it back from the response. The threshold opens now, so this month's spend counts against it at once, unless someone in scope has already spent more than the new amount: then it opens next month and `appliesFromNextMonth` says so. Raising it above a paused user's spend lifts their pause in the same call.

**Scope:** `policies:write`, and `teams:read` when a team is named.

Requires the permission `policies:write` on the key.

[Try it in the playground](https://developer.telgea.com/playground#tag/cost-thresholds/PUT/v1/cost-thresholds). 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 |
| --- | --- | --- |
| `usageType` | enum (required) | The usage type the threshold is on. `VOICE` is international calling: reaching it pauses international calls and SMS on the person's lines, where their market offers the pause. Other types answer `422` until the platform can enforce them. One of: `DATA`, `VOICE`, `SMS`, `MMS`. Example: `"VOICE"` |
| `teamId` | string (uuid) | UUID of the team the threshold is for. Omit with `userId` for the organization's own. Example: `"2f6b0d3a-8c1e-4a7f-9b2d-1e3c4d5f6a70"` |
| `userId` | string (uuid) | UUID of the user the threshold is for. Omit with `teamId` for the organization's own. Example: `"9c1f2a6e-3b7d-4e0a-8f21-5d6c7b8a9e01"` |
| `maxAmount` | number (required) | What one person may spend on the usage type per month, at most two decimals. Example: `50` |

**Responses**

| Status | Meaning | Body |
| --- | --- | --- |
| `200` | The threshold as written, and what it did on the way in. | `SetCostThresholdResponse` |
| `400` | Request failed schema validation, or named both a team and a user | none |
| `401` | Missing or invalid API key in the X-API-Key header | `UnauthorizedError` |
| `403` | Insufficient permissions to manage policies | `ForbiddenError` |
| `404` | No team in your organization has this id, so nothing was read or changed. No user in your organization has this id, so nothing was read or changed. | `NotFoundError` |
| `409` | Another write of the same threshold landed at the same moment, so this one was refused and nothing was changed. | `ConflictError` |
| `422` | No cost center names a currency for this scope, so the threshold has no money to be written in. The cost-center currency is one no exchange rate covers, so spend could never be compared with a threshold in it. No threshold can stand on this usage type yet, so nothing was read or changed. | `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, SetCostThresholdResponse)**

| Field | Type | Description |
| --- | --- | --- |
| `threshold` | object (required) | The threshold as written. |
| `threshold.id` | string (required) | UUID of the threshold. Example: `"5d0b2c1e-7f3a-4b6c-9e8d-2a1f0c3b4d5e"` |
| `threshold.usageType` | enum (required) | The usage type the threshold is on. `VOICE` is international calling: reaching it pauses international calls and SMS on the person's lines, where their market offers the pause. Other types answer `422` until the platform can enforce them. One of: `DATA`, `VOICE`, `SMS`, `MMS`. Example: `"VOICE"` |
| `threshold.scope` | enum (required) | Whose threshold this is: the organization's default, a team's, or one user's own. One of: `organization`, `team`, `user`. Example: `"team"` |
| `threshold.teamId` | string (required) | The team, for a team threshold. Example: `"2f6b0d3a-8c1e-4a7f-9b2d-1e3c4d5f6a70"` |
| `threshold.userId` | string (required) | The user, for a user threshold. Example: `null` |
| `threshold.maxAmount` | number (required) | What one person may spend on the usage type per month, in `currency`. Example: `50` |
| `threshold.currency` | string (required) | ISO 4217 code of the threshold's money: the team's cost-center currency, else the organization's primary. Example: `"EUR"` |
| `threshold.period` | enum (required) | The period the spend is counted in. Always the calendar month. One of: `monthly`. Example: `"monthly"` |
| `threshold.validFrom` | string (required) | When the threshold opens (ISO 8601). A threshold lowered below someone's spend opens next month. Example: `"2026-10-01T00:00:00.000Z"` |
| `threshold.validTo` | string (required) | When the threshold closes (ISO 8601), or null while it stands. Example: `null` |
| `appliesFromNextMonth` | boolean (required) | True when someone in scope has already spent more than the new amount this month, so it opens next month rather than now. Example: `false` |
| `releasedNumberCount` | integer (required) | Lines whose pause was lifted because the raised amount put their user back under it. Example: `0` |

**Example request**

```bash
curl -X PUT "https://api.telgea.com/v1/cost-thresholds" \
  -H "x-api-key: $TELGEA_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
  "usageType": "VOICE",
  "teamId": "2f6b0d3a-8c1e-4a7f-9b2d-1e3c4d5f6a70",
  "maxAmount": 50
}'
```

**Response 200**

```json
{
  "threshold": {
    "id": "5d0b2c1e-7f3a-4b6c-9e8d-2a1f0c3b4d5e",
    "usageType": "VOICE",
    "scope": "team",
    "teamId": "2f6b0d3a-8c1e-4a7f-9b2d-1e3c4d5f6a70",
    "userId": null,
    "maxAmount": 50,
    "currency": "EUR",
    "period": "monthly",
    "validFrom": "2026-10-01T00:00:00.000Z",
    "validTo": null
  },
  "appliesFromNextMonth": false,
  "releasedNumberCount": 0
}
```

### Remove a cost threshold {#remove-a-cost-threshold}

`DELETE /v1/cost-thresholds` · Enterprise API + Partner API

Ends the scope's threshold on a usage type now: the organization's (no team or user), a team's (`teamId`) or a user's own (`userId`). A user then falls under their team's threshold, a team under the organization's; with none left, the usage is unlimited.

Removing a threshold that is not set changes nothing and still answers `204`.

**Scope:** `policies:write`, and `teams:read` when a team is named.

Requires the permission `policies:write` on the key.

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

**Parameters**

| Parameter | In | Type | Description |
| --- | --- | --- | --- |
| `usageType` | query | enum (required) | The usage type the threshold is on. `VOICE` is international calling: reaching it pauses international calls and SMS on the person's lines, where their market offers the pause. Other types answer `422` until the platform can enforce them. Example: `VOICE` |
| `teamId` | query | string (uuid) | UUID of the team the threshold is for. Omit with `userId` for the organization's own. Example: `2f6b0d3a-8c1e-4a7f-9b2d-1e3c4d5f6a70` |
| `userId` | query | string (uuid) | UUID of the user the threshold is for. Omit with `teamId` for the organization's own. Example: `9c1f2a6e-3b7d-4e0a-8f21-5d6c7b8a9e01` |
| `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` | The threshold is ended, or none was set. | none |
| `400` | Request failed schema validation, or named both a team and a user | none |
| `401` | Missing or invalid API key in the X-API-Key header | `UnauthorizedError` |
| `403` | Insufficient permissions to manage policies | `ForbiddenError` |
| `404` | No team in your organization has this id, so nothing was read or changed. No user in your organization has this id, so nothing was read or changed. | `NotFoundError` |
| `422` | No threshold can stand on this usage type yet, so nothing was read or changed. | `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` |

**Example request**

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