---
title: "Register your own number"
description: "Trillet OEM API: Registers a number you or your customer already own, over a SIP trunk or a Twilio account."
openapi: /public/openapi/trillet-oem.yaml POST /partner/v1/tenants/{tenantId}/numbers/external
lastUpdated: "2026-10-28"
---

> **For AI agents:** the complete documentation index is at [llms.txt](https://docs.trillet.ai/llms.txt). Append `.md` to any page URL for its markdown version.

`POST https://api.trillet.ai/partner/v1/tenants/{tenantId}/numbers/external`

Registers a number you or your customer already own, over a SIP trunk or a Twilio account.
Trillet does not bill these numbers. Needs `numbers:write`. `Idempotency-Key` is required.

## Authentication

- `partnerKey` — http bearer (tpk_live_...)

## Header parameters

- `Idempotency-Key` (string, required) — 1 to 255 printable ASCII characters, no spaces. A retry with the same key and request returns the stored response for 24 hours instead of running again.

## Request body

- Content type: `application/json`
  - request body (object)
    - `phoneNumber` (string, required) — E.164 format. A number can be registered only once across Trillet.
    - `provider` (string, required, one of: sip, twilio)
    - `credentials` (object, required) — For `sip`: `sipUri` (where Trillet sends outbound calls), optional `username` and `password`, and optional `ipAddresses` your carrier sends calls from. For `twilio`: `accountSid` and `authToken`.

## Response 201

The number.
  - response (object)
    - `object` (string, required)
    - `id` (string, required) — Use it as `phoneNumberId` when binding the number to an agent.
    - `tenantId` (string, required)
    - `phoneNumber` (string, required) — E.164 format.
    - `provider` (string | null)
    - `type` (string | null)
    - `external` (boolean, required) — `true` for numbers you registered yourself.
    - `status` (string | null)
    - `agentId` (string | null)
    - `callFlowId` (string | null)
    - `billing` — Present for numbers bought through Trillet OEM, `null` for your own numbers.
      - (oneOf)
        - value (null)
        - value (object)
          - `monthlyPrice` (number | null) — Monthly price in USD.
          - `nextChargeAt` (string | null, date-time)
          - `status` (string, one of: active, past_due)
    - `createdAt` (string | null, date-time)

## Response 400

`invalid_request`, or `number_registration_failed` with the reason.
  - response (object)
    - `error` (object, required)
      - `type` (string, required, one of: invalid_request_error, authentication_error, permission_error, conflict_error, rate_limit_error, api_error, idempotency_error)
      - `code` (string, required) — A stable code. Handle errors by `code`, not by `message`.
      - `message` (string, required)
      - `param` (string) — The request field the error is about, when there is one.
      - `requestId` (string | null) — Include it when you contact support. Not present on idempotency errors.

## Response 401

The partner key is missing, malformed, unknown or revoked (`partner_key_required`, `invalid_api_key`, `partner_not_enabled`).
  - response (object)
    - `error` (object, required)
      - `type` (string, required, one of: invalid_request_error, authentication_error, permission_error, conflict_error, rate_limit_error, api_error, idempotency_error)
      - `code` (string, required) — A stable code. Handle errors by `code`, not by `message`.
      - `message` (string, required)
      - `param` (string) — The request field the error is about, when there is one.
      - `requestId` (string | null) — Include it when you contact support. Not present on idempotency errors.

## Response 403

`missing_scope`, or `key_restricted` on webhook endpoint routes.
  - response (object)
    - `error` (object, required)
      - `type` (string, required, one of: invalid_request_error, authentication_error, permission_error, conflict_error, rate_limit_error, api_error, idempotency_error)
      - `code` (string, required) — A stable code. Handle errors by `code`, not by `message`.
      - `message` (string, required)
      - `param` (string) — The request field the error is about, when there is one.
      - `requestId` (string | null) — Include it when you contact support. Not present on idempotency errors.

## Response 404

Not found, or not yours. For example `tenant_not_found`.
  - response (object)
    - `error` (object, required)
      - `type` (string, required, one of: invalid_request_error, authentication_error, permission_error, conflict_error, rate_limit_error, api_error, idempotency_error)
      - `code` (string, required) — A stable code. Handle errors by `code`, not by `message`.
      - `message` (string, required)
      - `param` (string) — The request field the error is about, when there is one.
      - `requestId` (string | null) — Include it when you contact support. Not present on idempotency errors.

## Response 409

Conflict with the current state of the resource.
  - response (object)
    - `error` (object, required)
      - `type` (string, required, one of: invalid_request_error, authentication_error, permission_error, conflict_error, rate_limit_error, api_error, idempotency_error)
      - `code` (string, required) — A stable code. Handle errors by `code`, not by `message`.
      - `message` (string, required)
      - `param` (string) — The request field the error is about, when there is one.
      - `requestId` (string | null) — Include it when you contact support. Not present on idempotency errors.

## Response 422

`idempotency_key_reused`: the same `Idempotency-Key` was sent with a different request.
  - response (object)
    - `error` (object, required)
      - `type` (string, required, one of: invalid_request_error, authentication_error, permission_error, conflict_error, rate_limit_error, api_error, idempotency_error)
      - `code` (string, required) — A stable code. Handle errors by `code`, not by `message`.
      - `message` (string, required)
      - `param` (string) — The request field the error is about, when there is one.
      - `requestId` (string | null) — Include it when you contact support. Not present on idempotency errors.


---

📦 **OpenAPI specs:** Every OpenAPI specification referenced by this documentation is available as a single download — https://docs.trillet.ai/api-specs.zip
