> ## 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.

# Rotate SIP Endpoint Password

> Username-and-password trunks only. Issues the trunk a new SIP password and
returns it **once**, in `sip_password`. The username stays the same. Send
no body (or an empty JSON object): Yappr issues the password, so it can't
be chosen.

The old password stops working within seconds, and calls already in
progress are not dropped. Enter the new password in your phone system
right away. If it registers, it learns of the change only at its next
registration refresh, which fails until the new password is in.

Requires `sip_endpoints:manage`; in the dashboard, only workspace owners
and admins. Limit: 10 attempts per trunk in an hour that runs from the
first attempt. The limit counts attempts, not new passwords issued.


Issues a username-and-password trunk a new SIP password and returns it **once**,
in `sip_password`. The username stays the same. Use it when a password was lost or
may have leaked. Send no body (or an empty JSON object): Yappr issues the password,
so it can't be chosen.

Requires `sip_endpoints:manage`; in the dashboard, only workspace owners and admins
can issue a new password. Limit: 10 attempts per trunk in an hour that runs from
the first attempt. The limit counts attempts, not new passwords issued.

```bash theme={null}
curl -X POST https://api.goyappr.com/sip-endpoints/8d0c5f4e-2b1a-4c3d-9e8f-7a6b5c4d3e2f/rotate-password \
  -H "Authorization: Bearer ypr_live_..."
```

```json theme={null}
{
  "data": {
    "id": "8d0c5f4e-2b1a-4c3d-9e8f-7a6b5c4d3e2f",
    "name": "Main office PBX",
    "auth_mode": "credentials",
    "slug": null,
    "sip_uri": null,
    "sip_username": "yp4k7d2m9x1q8w3z",
    "max_concurrent_calls": 5,
    "sip_connection": {
      "server": "sip.telnyx.com",
      "alternate_servers": ["sip.telnyx.eu", "sip.telnyx.me"],
      "transports": [
        { "protocol": "tls", "port": 5061, "recommended": true },
        { "protocol": "tcp", "port": 5060 },
        { "protocol": "udp", "port": 5060 }
      ],
      "registration": "optional"
    },
    "inbound_agent_id": "3f1c2b9e-7a4d-4e21-9c55-1b2d3e4f5a6b",
    "is_active": true,
    "last_call_at": "2026-10-01T14:05:12Z",
    "created_at": "2026-10-01T12:00:00Z",
    "updated_at": "2026-10-01T12:00:00Z",
    "sip_password": "N3wExampleOnlyNotARealPassword99"
  }
}
```

<Warning>
  The new password is in this response only. Store it now: neither the API nor the
  dashboard can show it again.
</Warning>

## What happens to calls

* **The old password stops working within seconds.** Your phone system's next call
  with it is refused with SIP `403 Forbidden`, so enter the new password right away.
* **Calls in progress are not dropped.**
* **A phone system that registers** learns of the change only at its next
  registration refresh, and that refresh fails until the new password is in.

To switch with no gap at all, [create](/api-reference/sip-endpoints/create) a second
trunk on the same agent, move your phone system to it, then
[delete](/api-reference/sip-endpoints/delete) the old trunk.

A SIP address endpoint has no password. Its address can't be changed either: create
a new endpoint, point your phone system at its `sip_uri`, then delete the old one.

## Errors

| Status | `code` | Meaning |
| - | - | - |
| 400 | `SIP_ENDPOINT_REQUEST_INVALID` | The body is JSON with a field, or JSON that is not an object: this call takes no body. The password did not change. A body that is not JSON at all is ignored, and the password is changed as if you had sent none. |
| 400 | `SIP_ENDPOINT_QUERY_INVALID` | The request has a query parameter: this call takes none. The password did not change. |
| 401 | `MISSING_KEY`, `INVALID_KEY`, `EXPIRED_KEY` | The API key is missing, not recognised or expired. |
| 403 | `INSUFFICIENT_SCOPE` | The API key lacks `sip_endpoints:manage`. |
| 403 | `FORBIDDEN_ROLE` | Dashboard: only workspace owners and admins can issue a new password. |
| 404 | `SIP_ENDPOINT_NOT_FOUND` | No SIP endpoint with this id in this workspace. |
| 409 | `SIP_ENDPOINT_NOT_CREDENTIALS` | This is a SIP address endpoint, which has no password. |
| 409 | `SIP_TRUNK_NOT_PROVISIONED` | This trunk's username and password were never finished, or are no longer set up at Yappr's carrier. Delete it and create a new one. |
| 429 | `RATE_LIMITED` | This trunk already had 10 attempts at a new password in the current hour, which runs from its first attempt. The limit counts attempts, so an attempt that failed can count too. The password did not change; try again once the hour is up. |
| 500 | `INTERNAL_ERROR` | Yappr could not load the trunk. The password did not change; try again. |
| 502 | `SIP_TRUNK_PROVISIONING_FAILED` | The new password could not be set or confirmed at Yappr's carrier. `error` says whether the current password still works. Try again in a minute: the password from the next successful answer is the one that works. |


## OpenAPI

````yaml POST /sip-endpoints/{id}/rotate-password
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:
  /sip-endpoints/{id}/rotate-password:
    post:
      tags:
        - SIP Endpoints
      summary: Issue a new SIP password
      description: >
        Username-and-password trunks only. Issues the trunk a new SIP password
        and

        returns it **once**, in `sip_password`. The username stays the same.
        Send

        no body (or an empty JSON object): Yappr issues the password, so it
        can't

        be chosen.


        The old password stops working within seconds, and calls already in

        progress are not dropped. Enter the new password in your phone system

        right away. If it registers, it learns of the change only at its next

        registration refresh, which fails until the new password is in.


        Requires `sip_endpoints:manage`; in the dashboard, only workspace owners

        and admins. Limit: 10 attempts per trunk in an hour that runs from the

        first attempt. The limit counts attempts, not new passwords issued.
      operationId: rotateSipEndpointPassword
      parameters:
        - in: path
          name: id
          required: true
          schema:
            type: string
            format: uuid
      responses:
        '200':
          description: >-
            The trunk, with its new password in `sip_password`. Store it now; it
            is never shown again.
          content:
            application/json:
              schema:
                type: object
                properties:
                  data:
                    $ref: '#/components/schemas/SipEndpointWithPassword'
        '400':
          description: |
            The password did not change.
            - `SIP_ENDPOINT_REQUEST_INVALID` — the body is JSON with a field, or
              JSON that is not an object: this call takes no body. A body that is
              not JSON at all is ignored, and the password is changed as if none
              had been sent.
            - `SIP_ENDPOINT_QUERY_INVALID` — the request has a query parameter;
              this call takes none.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error'
        '401':
          description: >-
            `MISSING_KEY`, `INVALID_KEY` or `EXPIRED_KEY` — the API key is
            missing, not recognised or expired.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error'
        '403':
          description: >-
            `INSUFFICIENT_SCOPE` — the API key lacks `sip_endpoints:manage`.
            `FORBIDDEN_ROLE` — dashboard sessions only: just workspace owners
            and admins can issue a new password.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error'
        '404':
          description: >-
            `SIP_ENDPOINT_NOT_FOUND` — no SIP endpoint with this id in this
            workspace.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error'
        '409':
          description: >
            The password did not change.

            - `SIP_ENDPOINT_NOT_CREDENTIALS` — this is a SIP address endpoint,
            which
              has no password. To move it to a new address, create a new endpoint,
              point your phone system at it, then delete this one.
            - `SIP_TRUNK_NOT_PROVISIONED` — this trunk's username and password
            were
              never finished, or are no longer set up at Yappr's carrier. Delete it
              and create a new one.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error'
        '429':
          description: >
            `RATE_LIMITED` — this trunk already had 10 attempts at a new
            password

            in the current hour, which runs from its first attempt. The limit

            counts attempts, so an attempt that failed can count too. The
            password

            did not change; try again once the hour is up.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error'
        '500':
          description: >-
            `INTERNAL_ERROR` — Yappr could not load the trunk. The password did
            not change; try again.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error'
        '502':
          description: |
            `SIP_TRUNK_PROVISIONING_FAILED` — the new password could not be set
            or confirmed at Yappr's carrier. `error` says whether the current
            password still works. Try again in a minute: the password from the
            next successful answer is the one that works.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error'
components:
  schemas:
    SipEndpointWithPassword:
      description: >
        The endpoint, as [create](/api-reference/sip-endpoints/create) and

        [rotate-password](/api-reference/sip-endpoints/rotate-password) return
        it.

        On a username-and-password trunk it carries `sip_password`, the only

        time the password is ever returned.
      allOf:
        - $ref: '#/components/schemas/SipEndpoint'
        - type: object
          properties:
            sip_password:
              type: string
              description: >
                Username-and-password trunks only: the trunk's SIP password, 32

                letters and digits. Store it now: neither the API nor the
                dashboard

                can show it again. If it is lost,

                [issue a new one](/api-reference/sip-endpoints/rotate-password).
              example: Ex4mpleOnlyNotARealPassword12345
    Error:
      type: object
      properties:
        error:
          type: string
        code:
          type: string
    SipEndpoint:
      type: object
      description: >
        A SIP endpoint lets your own phone system (a PBX, a contact-center

        platform or a SIP provider) send calls to a Yappr agent, without a Yappr

        phone number. It comes in two kinds, set by `auth_mode` when you create
        it:


        - `credentials`: **username and password** (recommended). Yappr issues a
          SIP username and password. Your phone system sends calls to
          `sip.telnyx.eu` or `sip.telnyx.com` with them, dialling any number or
          extension, and the endpoint's agent answers every call. A call with a
          wrong username or password is refused before it reaches Yappr. The
          password is returned only once: by
          [create](/api-reference/sip-endpoints/create) and by
          [rotate-password](/api-reference/sip-endpoints/rotate-password).
        - `uri`: **SIP address only**. Your phone system dials the endpoint's
          `sip_uri`, with no username or password. The address is the secret:
          anyone who has it can call the agent.

        `sip_username`, `max_concurrent_calls` and `sip_connection` appear on

        username-and-password trunks only, and `allowed_source_ips` on SIP
        address

        endpoints only. List, get and update never return a password. A SIP

        address endpoint's `slug` and `sip_uri` are its credential, and a
        trunk's

        `sip_username` is half of its, so list and get return them only to a key

        that also holds `sip_endpoints:manage`; with `sip_endpoints:read` alone

        they are `null`. The [setup guide](/concepts/sip-trunks) covers the
        phone

        system side.
      required:
        - id
        - name
        - auth_mode
        - slug
        - sip_uri
        - inbound_agent_id
        - is_active
        - last_call_at
        - created_at
        - updated_at
      properties:
        id:
          type: string
          format: uuid
        name:
          type: string
          example: Main office PBX
        auth_mode:
          type: string
          enum:
            - credentials
            - uri
          description: >
            `credentials`: a username-and-password trunk. `uri`: a SIP address

            endpoint. Endpoints created before username-and-password trunks

            existed are `uri`. It cannot be changed after the endpoint is
            created.
          example: credentials
        slug:
          type:
            - string
            - 'null'
          description: >
            SIP address endpoints: the user part of `sip_uri`, made of a
            readable

            prefix (the `slug` you sent, or one derived from `name`), a hyphen
            and

            24 random characters, about 120 bits that cannot be guessed. `null`
            on

            username-and-password trunks, and on list and get for a key without

            `sip_endpoints:manage`.
          example: after-hours-bz3r3mtypuwuw8tpdw3x392s
        sip_uri:
          type:
            - string
            - 'null'
          description: >
            SIP address endpoints: the full address your phone system dials,
            over

            UDP or TCP (port 5060) or TLS (port 5061). Anyone who has it can
            call

            the agent, so treat it like an API key. `null` on
            username-and-password

            trunks, and on list and get for a key without
            `sip_endpoints:manage`.
          example: sip:after-hours-bz3r3mtypuwuw8tpdw3x392s@yappr-byoc.sip.telnyx.com
        sip_username:
          type:
            - string
            - 'null'
          description: >
            Username-and-password trunks only. The SIP username your phone
            system

            authenticates with: `yp` followed by 14 lowercase letters and
            digits.

            It never changes; only the password can be replaced. `null` on list

            and get for a key without `sip_endpoints:manage`, and on a trunk
            whose

            setup never finished (switched off; delete it and create a new one).
          example: yp4k7d2m9x1q8w3z
        max_concurrent_calls:
          type: integer
          minimum: 1
          maximum: 8
          description: |
            Username-and-password trunks only. The most calls the trunk takes at
            once, counting calls ringing and in progress: 1 to 8, 2 unless you
            changed it. The next call is refused with SIP `486 Busy Here`.
          example: 5
        sip_connection:
          $ref: '#/components/schemas/SipConnection'
        inbound_agent_id:
          type: string
          format: uuid
          description: The agent that answers every call on this endpoint.
        is_active:
          type: boolean
          description: >
            `false` switches the endpoint off: new calls are refused before they

            are answered (SIP `603 Decline`) until you switch it back on. Calls
            in

            progress are not affected.
        last_call_at:
          type:
            - string
            - 'null'
          format: date-time
        allowed_source_ips:
          type:
            - array
            - 'null'
          description: |
            SIP address endpoints only. Source addresses recorded with the
            endpoint, for your records. **Calls are not checked against this
            list**: a call to the address is answered wherever it comes from.
            `null` when none is recorded.
          items:
            type: string
            example: 203.0.113.0/24
        created_at:
          type: string
          format: date-time
        updated_at:
          type: string
          format: date-time
    SipConnection:
      type: object
      description: |
        Username-and-password trunks only: where and how your phone system sends
        the trunk's calls. It is the same on every trunk. The
        [setup guide](/concepts/sip-trunks) explains each value.
      required:
        - server
        - alternate_servers
        - transports
        - registration
      properties:
        server:
          type: string
          description: >
            The SIP server (proxy, registrar) your phone system sends the
            trunk's

            calls to, for example in the US. From Israel or Europe,

            `sip.telnyx.eu` (in `alternate_servers`) is closer. If your system

            asks for a realm, the realm is the server name you send to.
          example: sip.telnyx.com
        alternate_servers:
          type: array
          items:
            type: string
          description: >
            Other servers that take the same username and password: use

            `sip.telnyx.eu` from Israel or Europe, and any other one for a
            backup

            route. The realm follows the server you use.
          example:
            - sip.telnyx.eu
            - sip.telnyx.me
        transports:
          type: array
          description: |
            The transports and ports to send the trunk's calls on. TLS (1.2 or
            1.3) is recommended. Telnyx publishes the same transports and ports
            for the alternate servers.
          items:
            type: object
            required:
              - protocol
              - port
            properties:
              protocol:
                type: string
                enum:
                  - tls
                  - tcp
                  - udp
              port:
                type: integer
              recommended:
                type: boolean
                description: '`true` on the transport to prefer. Absent on the others.'
          example:
            - protocol: tls
              port: 5061
              recommended: true
            - protocol: tcp
              port: 5060
            - protocol: udp
              port: 5060
        registration:
          type: string
          enum:
            - optional
          description: >
            `optional`: each call is checked against the username and password,
            so

            registering is not what lets a call in. Keep the connection open

            anyway: over TLS or TCP, register the trunk or send keep-alives (SIP

            `OPTIONS`) every 30 seconds or less; over UDP behind NAT or a

            firewall, send keep-alives every 30 seconds or less even if your

            system registers, because a registration is refreshed only every few

            minutes. Otherwise the agent's hang-up may not reach your phone
            system

            ([setup guide](/concepts/sip-trunks#register-or-send-keep-alives)).
  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**.

````

This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.