> ## Documentation Index
> Fetch the complete documentation index at: https://docs.goyappr.com/llms.txt
> Use this file to discover all available pages before exploring further.

# Connect a Telnyx Account

> Save a Telnyx API key made just for Yappr. The key is checked with Telnyx
first; nothing is saved if Telnyx refuses it. Then
[choose the Call Control App](/api-reference/carrier-accounts/connection) and
[add your numbers](/api-reference/carrier-accounts/add-number). Requires
`carrier_accounts:manage`. Limit: 10 per workspace per day.


Connect **your own Telnyx account** so agents can call from the numbers you already
own there. Yappr places those calls on your Telnyx account, with your API key, so
Telnyx bills you for the phone minutes and its calling fees. Yappr still bills the
agent minutes. Requires `carrier_accounts:manage`, which API keys do not have by
default: create a key with it (the dashboard's full access includes it).

Carrier accounts are available in every workspace.
[GET /carrier-accounts/status](/api-reference/carrier-accounts/status) answers
`{ "enabled": true }` unless Yappr has switched them off for yours.

Set Telnyx up first: Level 2 verification, an outbound voice profile with your
destination countries allowed, and an API key made just for Yappr. The
[setup guide](/concepts/bring-your-own-carrier) walks through it.

```bash theme={null}
curl -X POST https://api.goyappr.com/carrier-accounts \
  -H "Authorization: Bearer ypr_live_..." \
  -H "Content-Type: application/json" \
  -d '{
    "name": "Main Telnyx account",
    "api_key": "KEY0199…",
    "public_key": "3MYsSvZbhKUP9VZ1pRgGNlDtJGbNkFMhTqwPjGEgUoY="
  }'
```

```json theme={null}
{
  "data": {
    "id": "7c1e…",
    "name": "Main Telnyx account",
    "provider": "telnyx",
    "api_key_last4": "9XyZ",
    "public_key_set": true,
    "signature_verified": false,
    "connection": null,
    "status": "untested",
    "numbers": []
  },
  "webhook_url": "https://voice.goyappr.com/webhook/telnyx?ca=7c1e…&t=…",
  "telnyx": {
    "connections": [{ "id": "2890…", "name": "My app", "active": true, "outbound_voice_profile_id": "2890…" }],
    "outbound_voice_profiles": [
      { "id": "2890…", "name": "Israel", "enabled": true, "allowed_destinations": ["IL"],
        "daily_spend_limit": "20.00", "daily_spend_limit_enabled": true, "channel_limit": 4 }
    ]
  }
}
```

| Field        | Rule                                                                                                                                                       |
| ------------ | ---------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `name`       | 1–100 characters.                                                                                                                                          |
| `api_key`    | A Telnyx API key. Telnyx is asked first; if it refuses the key, **nothing is saved**. Stored encrypted and never returned.                                 |
| `public_key` | Optional, recommended: your account's public key (Keys & Credentials → Public Key). Yappr uses it to check that call events really come from your account. |

Telnyx API keys cannot be limited to certain actions, so use a key made only for
Yappr: switching it off in Telnyx stops Yappr's calls from your account at once.

Next: [choose the Call Control App](/api-reference/carrier-accounts/connection).

## Errors

| Status | `code`                                                                  | Meaning                                                                                                        |
| ------ | ----------------------------------------------------------------------- | -------------------------------------------------------------------------------------------------------------- |
| 400    | `INVALID_NAME`, `INVALID_API_KEY`, `INVALID_PUBLIC_KEY`, `INVALID_JSON` | Fix the field named in `error`.                                                                                |
| 403    | `CARRIER_ACCOUNTS_NOT_ENABLED`                                          | Yappr has switched carrier accounts off for this workspace. Nothing was sent to Telnyx. Contact Yappr support. |
| 422    | `TELNYX_KEY_REJECTED`                                                   | Telnyx refused the key. Check it is switched on and pasted in full.                                            |
| 422    | `KEY_IS_YAPPR_ACCOUNT`                                                  | The key belongs to Yappr's own Telnyx account.                                                                 |
| 429    | `RATE_LIMITED`                                                          | 10 accounts connected in this workspace today.                                                                 |
| 503    | `TELNYX_UNAVAILABLE`                                                    | Telnyx did not answer. Nothing was saved.                                                                      |


## OpenAPI

````yaml POST /carrier-accounts
openapi: 3.1.0
info:
  title: Yappr API
  description: >
    Create and manage AI voice agents, purchase phone numbers, configure tools,
    and initiate calls — all via REST.
  version: 1.0.0
  contact:
    url: https://goyappr.com
servers:
  - url: https://api.goyappr.com
    description: Production
security:
  - apiKey: []
paths:
  /carrier-accounts:
    post:
      tags:
        - Carrier Accounts
      summary: Connect a Telnyx account
      description: >
        Save a Telnyx API key made just for Yappr. The key is checked with
        Telnyx

        first; nothing is saved if Telnyx refuses it. Then

        [choose the Call Control
        App](/api-reference/carrier-accounts/connection) and

        [add your numbers](/api-reference/carrier-accounts/add-number). Requires

        `carrier_accounts:manage`. Limit: 10 per workspace per day.
      operationId: createCarrierAccount
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/CarrierAccountCreate'
      responses:
        '201':
          description: Connected (status `untested`, no app yet)
          content:
            application/json:
              schema:
                type: object
                properties:
                  data:
                    $ref: '#/components/schemas/CarrierAccount'
                  webhook_url:
                    type: string
                    format: uri
                    description: The URL a Call Control App you made must use.
                  telnyx:
                    type: object
                    description: >-
                      The Call Control Apps and outbound voice profiles your key
                      can see (same shape as the test result's `telnyx`).
        '400':
          description: >-
            `INVALID_NAME`, `INVALID_API_KEY`, `INVALID_PUBLIC_KEY` or
            `INVALID_JSON`.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error'
        '403':
          $ref: '#/components/responses/CarrierAccountsNotEnabled'
        '422':
          description: >-
            `TELNYX_KEY_REJECTED` — Telnyx refused the key.
            `KEY_IS_YAPPR_ACCOUNT` — the key belongs to Yappr's own Telnyx
            account.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error'
        '429':
          description: '`RATE_LIMITED` — 10 accounts connected today.'
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error'
        '503':
          description: >-
            `TELNYX_UNAVAILABLE` — Telnyx did not answer. Nothing changed; try
            again.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error'
components:
  schemas:
    CarrierAccountCreate:
      type: object
      required:
        - name
        - api_key
      properties:
        name:
          type: string
          minLength: 1
          maxLength: 100
          example: Main Telnyx account
        api_key:
          type: string
          format: password
          writeOnly: true
          description: >
            A Telnyx API key created just for Yappr (Account Settings → API
            Keys).

            Checked with Telnyx before anything is saved; stored encrypted;
            never returned.
        public_key:
          type: string
          writeOnly: true
          description: >-
            Your account's public key (Keys & Credentials → Public Key), 44
            characters of base64. Recommended.
          example: 3MYsSvZbhKUP9VZ1pRgGNlDtJGbNkFMhTqwPjGEgUoY=
    CarrierAccount:
      type: object
      description: >
        Your own Telnyx account, connected so agents can call from the numbers
        you

        own there. Yappr places each call **on your Call Control App, with your
        API

        key**, so the call runs on your Telnyx account and Telnyx bills you for
        it.

        The API key is write-only: no response ever contains it.
      properties:
        id:
          type: string
          format: uuid
        name:
          type: string
          example: Main Telnyx account
        provider:
          type: string
          enum:
            - telnyx
        api_key_last4:
          type: string
          example: 9XyZ
          description: >-
            The last four characters of the saved key. The key itself is never
            returned.
        api_key_updated_at:
          type: string
          format: date-time
        public_key_set:
          type: boolean
          description: Whether you saved your account's public key.
        signature_verified:
          type: boolean
          description: >
            `true` once a call event from Telnyx verified against your public
            key.

            From then on every event for this account must carry a valid
            signature.
        connection:
          type: object
          nullable: true
          description: >-
            The Call Control App calls go through. `null` until you [choose
            one](/api-reference/carrier-accounts/connection).
          properties:
            id:
              type: string
              example: '2890000000000000001'
            created_by_yappr:
              type: boolean
            outbound_voice_profile_id:
              type: string
              nullable: true
        status:
          type: string
          enum:
            - untested
            - active
            - paused
          description: >
            `untested` — no call answered on your app since you connected or
            turned it

            back on. `active` — the last answered call ran on your app. `paused`
            —

            Telnyx refused your key, your app is gone, or Telnyx refused 5 calls
            in a

            row; every number on the account is paused (`is_active: false`)
            until you

            fix the cause and call
            [reactivate](/api-reference/carrier-accounts/reactivate).
        pause_reason:
          type: string
          nullable: true
          enum:
            - key_rejected
            - connection_invalid
            - carrier_rejections
        last_error:
          type: object
          nullable: true
          properties:
            code:
              type: string
              description: >-
                `carrier_rejected`, `key_rejected`, `connection_invalid`,
                `public_key_mismatch`, `connection_mismatch`, `inbound_on_app`
                or `number_released`.
            sip_code:
              type: string
              nullable: true
              example: '403'
              description: >-
                The SIP code Telnyx ended a ringing call with (`401`, `403`,
                `407`, …). `null` when Telnyx refused over its API instead: the
                call itself before it rang, a command on it, or a test.
            at:
              type: string
              format: date-time
              nullable: true
        last_success_at:
          type: string
          format: date-time
          nullable: true
        last_tested_at:
          type: string
          format: date-time
          nullable: true
        numbers:
          type: array
          items:
            $ref: '#/components/schemas/PhoneNumber'
        webhook_url:
          type: string
          format: uri
          description: >
            The exact webhook URL a Call Control App you made must use. Returned
            only

            to workspace owners and admins, and to API keys with

            `carrier_accounts:manage`. It carries a secret for your account:
            treat it

            like a password.
        created_at:
          type: string
          format: date-time
        updated_at:
          type: string
          format: date-time
    Error:
      type: object
      properties:
        error:
          type: string
        code:
          type: string
    PhoneNumber:
      type: object
      properties:
        id:
          type: string
          format: uuid
        number:
          type: string
          example: '+972551234567'
        friendly_name:
          type: string
          nullable: true
        provider:
          type: string
          description: >
            Where the number comes from: `telnyx` for a number bought from
            Yappr,

            `external` for a number in your own Telnyx account, added to a

            [carrier account](/api-reference/carrier-accounts/add-number).
        status:
          type: string
          enum:
            - active
            - pending_requirements
            - suspended
        is_active:
          type: boolean
        inbound_agent_id:
          type: string
          format: uuid
          nullable: true
        outbound_agent_id:
          type: string
          format: uuid
          nullable: true
        sip_inbound_configured:
          type: boolean
        sip_outbound_configured:
          type: boolean
        country_code:
          type: string
          nullable: true
        monthly_cost:
          type: number
          nullable: true
        created_at:
          type: string
          format: date-time
        carrier_account:
          type: object
          nullable: true
          description: >
            The Telnyx account an `external` number calls through. `null` on
            numbers

            bought from Yappr.
          properties:
            id:
              type: string
              format: uuid
            name:
              type: string
            provider:
              type: string
              enum:
                - telnyx
            status:
              type: string
              enum:
                - untested
                - active
                - paused
        ownership_verified_at:
          type: string
          format: date-time
          nullable: true
          description: >
            When your Telnyx API key last proved that this `external` number is
            an

            active number in your account. `null` means Telnyx no longer lists
            it: the

            number is not callable until a
            [test](/api-reference/carrier-accounts/test)

            finds it again. Always `null` on numbers bought from Yappr.
  responses:
    CarrierAccountsNotEnabled:
      description: >
        `CARRIER_ACCOUNTS_NOT_ENABLED` — Yappr has switched calling out through
        your own

        Telnyx account off for this workspace. It is available in every
        workspace, so this

        is only the emergency-off answer; contact Yappr support. Every
        carrier-accounts

        route answers this while it is off (check with

        [GET /carrier-accounts/status](/api-reference/carrier-accounts/status)).
        An API key

        without the route's scope gets a 403 of its own.
      content:
        application/json:
          schema:
            allOf:
              - $ref: '#/components/schemas/Error'
              - type: object
                properties:
                  enabled:
                    type: boolean
                    example: false
          example:
            error: >-
              Calling out through your own Telnyx account is switched off for
              this workspace. Contact Yappr support.
            code: CARRIER_ACCOUNTS_NOT_ENABLED
            enabled: false
  securitySchemes:
    apiKey:
      type: http
      scheme: bearer
      bearerFormat: API Key
      description: >-
        Your Yappr API key (e.g. `ypr_live_...`). Generate one in the dashboard
        under **Settings → API Keys**.

````