TelgeaDevelopers

Working with the Telgea Open API

Get started with the Telgea API in under 5 minutes.

Telgea Open API

The Telgea Open API follows conventional REST API standards, aligned around various resources that can be managed through the API.

Prerequisites

To work with the Open API, ensure you have:

  • A Telgea organization account
  • An API key: see Authentication for how you get one

Make Your First Request

The quickest first call needs no code: open the playground, paste your API key, and send List users. It is a read, so it changes nothing.

Or from a terminal:

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

The response includes a paginated list of users in your organization.

There is no sandbox

Every call — from the playground or from your code — runs against your own live organization. Creating a user creates a real user, and provisioning creates a real line.

Authentication

All API requests require an API key passed in the x-api-key header. Each key holds a set of permissions that decide which operations it can call, and every operation in the API reference names the permission it needs. How you receive a key is described under Authentication.

Include the key in every request:

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

Missing or invalid API keys return a 401 Unauthorized status code. Insufficient permissions return 403 Forbidden.

To check a key before writing any code, paste it into the playground and send a read such as List users. A 403 there names the permission the key is missing.

Error Handling

The Telgea Open API uses standard HTTP status codes and returns every failure as RFC 9457 Problem Details, served as application/problem+json. Success responses come in the form of 200 OK, 201 Created or 204 No Content. The error index lists every problem type the API returns, each with its own page.

StatuscodeWhen
400VALIDATION_ERRORThe request does not match the endpoint's schema. Nothing was processed.
400BAD_REQUESTThe request was refused, and no more specific code describes why — for instance, the resource is not in a state that allows the action.
400INVALID_REQUESTThe request combines parameters that cannot be used together, so nothing was processed. Returned by the user-plan endpoints of the Enterprise API; other endpoints return BAD_REQUEST, which new integrations should handle.
401UNAUTHORIZEDThe x-api-key header is missing or invalid.
403FORBIDDENThe key is valid but lacks the permission this endpoint requires.
403ORGANIZATION_ACCESS_REVOKEDYour organization's access to the API has been revoked. Contact support to restore it.
403COUNTRY_NOT_SUPPORTEDThe request names a country that is not enabled for your organization.
404NOT_FOUNDNo matching resource exists in your organization.
405METHOD_NOT_ALLOWEDThe path does not accept this method. The Allow response header lists the ones it does.
409CONFLICTThe request conflicts with an existing resource. Nothing was created or changed.
422UNPROCESSABLE_ENTITYThe request was understood but cannot be processed with these values.
429RATE_LIMIT_EXCEEDEDThe key has used its quota for the current window. Retry-After says when it resets.
429TOO_MANY_REQUESTSRequests for this action arrive faster than it allows, such as a second SIM replacement inside its cooldown. Retry with backoff.
500INTERNAL_ERRORRetry with exponential backoff, then contact Telgea with the requestId.
503SERVICE_UNAVAILABLEA system the request depends on is temporarily unavailable. Retry with exponential backoff; if the request creates or changes something, read the resource back first.

Error Response Format

Every error body is a flat JSON object with the content type application/problem+json. It always carries these members:

  • type — a URI naming the kind of failure. It opens that error's page on this site, which says when it occurs and what to do about it.
  • title — a short summary of the problem type. It is the same on every occurrence.
  • status — the HTTP status of the response.
  • detail — what went wrong on this request, in one sentence.
  • code — a stable machine-readable code. Branch on code or type, never on the detail text.
  • requestId — identifies the request in Telgea's logs. Quote it when you contact support.

Some errors add extension members after these, named in camelCase, such as fields on a validation error or missingPermission on a permission error. The error schemas in the API reference list the members each operation's errors can carry. Ignore any member you do not recognize.

{
  "type": "https://developer.telgea.com/errors/http/NOT_FOUND",
  "title": "Not found",
  "status": 404,
  "detail": "No resource matching this request exists in your organization.",
  "code": "NOT_FOUND",
  "requestId": "req_123"
}

Validation Errors

A VALIDATION_ERROR adds fields, listing one entry per rejected field (at most 20). Every entry describes the same request location: query, path and body are validated in that order, and the first that fails answers the request.

{
  "type": "https://developer.telgea.com/errors/http/VALIDATION_ERROR",
  "title": "Validation error",
  "status": 400,
  "detail": "The request does not match this endpoint's schema, so nothing was processed.",
  "code": "VALIDATION_ERROR",
  "requestId": "req_123",
  "fields": [
    {
      "field": "fields.authorizationCode",
      "location": "body",
      "code": "REQUIRED",
      "message": "This field is required."
    }
  ]
}

location is one of body, query, path, header or cookie. code is one of REQUIRED, INVALID_TYPE, INVALID_FORMAT, INVALID_VALUE, TOO_SMALL, TOO_LARGE, UNKNOWN_FIELD or INVALID. field is a dotted path, with [i] for array indices, and is empty when the failure is about the request as a whole rather than one field.

Permission Errors

A 403 raised by a missing API-key permission adds missingPermission, naming the permission the key lacks.

{
  "type": "https://developer.telgea.com/errors/http/FORBIDDEN",
  "title": "Forbidden",
  "status": 403,
  "detail": "This API key is missing the users:read permission.",
  "code": "FORBIDDEN",
  "requestId": "req_123",
  "missingPermission": "users:read"
}

Pagination

List endpoints paginate in one of two ways. Resource collections use page numbers; the usage feed uses a cursor, because records keep arriving while you read.

Page-numbered endpoints

/v1/users, /v1/numbers and /v1/port-ins/number/{numberId} take page and pageSize query parameters and return:

{
  "page": 1,
  "pageSize": 50,
  "itemsCount": 142,
  "items": []
}
  • itemsCount is the total across all pages; the number of pages is Math.ceil(itemsCount / pageSize)
  • An empty items array with itemsCount: 0 means no results match your query
  • page is 1-indexed, and the default and maximum pageSize differ per endpoint:
EndpointDefault pageSizeMaximum pageSize
/v1/users1050
/v1/teams (Enterprise API)5050
/v1/numbers (Partner API)50100
/v1/user-plans (Enterprise API)50100
/v1/port-ins/number/{numberId}50100

The usage feed

/v1/usage takes pageSize (default 50, maximum 100) and an opaque cursor, and returns:

{
  "items": [],
  "nextCursor": "eyJjIjoiMjAyNi0wOS0xMVQwODozMDowMC4xMjM0NTZaIiwicyI6ImRhdGEiLCJpIjoiY2RyXzEifQ",
  "hasMore": true
}

Omit cursor for the first page, then pass the previous response's nextCursor to fetch the next one. Stop when hasMore is false; nextCursor is null once the feed is exhausted. The feed takes no page parameter and reports no total.

Rate Limits

Each API key allows 1000 requests per 24 hours, shared across every endpoint. A request over the budget returns 429 with the code RATE_LIMIT_EXCEEDED; wait for the window to reset before retrying. When polling usage, walk the whole organization with the default page size rather than issuing one request per subscriber.

Retries and Idempotency

Every POST, PATCH and DELETE accepts an optional Idempotency-Key header: a value unique to the request, of 1 to 255 printable ASCII characters. A UUID is the usual choice.

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

If the connection drops before the response reaches you, send the request again with the same key: rather than provisioning a second line or failing with a conflict, the API returns the original response.

  • A key identifies one request to one endpoint, and is remembered for 24 hours.
  • Within that window the same key replays the original outcome, including a failure, which is not re-attempted. Change the key whenever you mean to send a new request, including after correcting a rejected one.
  • Keys are private to your API key and organization.
  • The header is ignored on GET, and a malformed one is rejected with 400 before the request has any effect.

Next Steps

On this page