curl --request POST \
--url https://api.goyappr.com/sip-endpoints/{id}/rotate-password \
--header 'Authorization: Bearer <token>'import requests
url = "https://api.goyappr.com/sip-endpoints/{id}/rotate-password"
headers = {"Authorization": "Bearer <token>"}
response = requests.post(url, headers=headers)
print(response.text)const options = {method: 'POST', headers: {Authorization: 'Bearer <token>'}};
fetch('https://api.goyappr.com/sip-endpoints/{id}/rotate-password', options)
.then(res => res.json())
.then(res => console.log(res))
.catch(err => console.error(err));<?php
$curl = curl_init();
curl_setopt_array($curl, [
CURLOPT_URL => "https://api.goyappr.com/sip-endpoints/{id}/rotate-password",
CURLOPT_RETURNTRANSFER => true,
CURLOPT_ENCODING => "",
CURLOPT_MAXREDIRS => 10,
CURLOPT_TIMEOUT => 30,
CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
CURLOPT_CUSTOMREQUEST => "POST",
CURLOPT_HTTPHEADER => [
"Authorization: Bearer <token>"
],
]);
$response = curl_exec($curl);
$err = curl_error($curl);
curl_close($curl);
if ($err) {
echo "cURL Error #:" . $err;
} else {
echo $response;
}package main
import (
"fmt"
"net/http"
"io"
)
func main() {
url := "https://api.goyappr.com/sip-endpoints/{id}/rotate-password"
req, _ := http.NewRequest("POST", url, nil)
req.Header.Add("Authorization", "Bearer <token>")
res, _ := http.DefaultClient.Do(req)
defer res.Body.Close()
body, _ := io.ReadAll(res.Body)
fmt.Println(string(body))
}HttpResponse<String> response = Unirest.post("https://api.goyappr.com/sip-endpoints/{id}/rotate-password")
.header("Authorization", "Bearer <token>")
.asString();require 'uri'
require 'net/http'
url = URI("https://api.goyappr.com/sip-endpoints/{id}/rotate-password")
http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true
request = Net::HTTP::Post.new(url)
request["Authorization"] = 'Bearer <token>'
response = http.request(request)
puts response.read_body{
"data": {
"id": "3c90c3cc-0d44-4b50-8888-8dd25736052a",
"name": "Main office PBX",
"auth_mode": "credentials",
"slug": "after-hours-bz3r3mtypuwuw8tpdw3x392s",
"sip_uri": "sip:after-hours-bz3r3mtypuwuw8tpdw3x392s@yappr-byoc.sip.telnyx.com",
"inbound_agent_id": "3c90c3cc-0d44-4b50-8888-8dd25736052a",
"is_active": true,
"last_call_at": "2023-11-07T05:31:56Z",
"created_at": "2023-11-07T05:31:56Z",
"updated_at": "2023-11-07T05:31:56Z",
"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"
},
"allowed_source_ips": [
"203.0.113.0/24"
],
"sip_password": "Ex4mpleOnlyNotARealPassword12345"
}
}{
"error": "<string>",
"code": "<string>"
}{
"error": "<string>",
"code": "<string>"
}{
"error": "<string>",
"code": "<string>"
}{
"error": "<string>",
"code": "<string>"
}{
"error": "<string>",
"code": "<string>"
}{
"error": "<string>",
"code": "<string>"
}{
"error": "<string>",
"code": "<string>"
}{
"error": "<string>",
"code": "<string>"
}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.
curl --request POST \
--url https://api.goyappr.com/sip-endpoints/{id}/rotate-password \
--header 'Authorization: Bearer <token>'import requests
url = "https://api.goyappr.com/sip-endpoints/{id}/rotate-password"
headers = {"Authorization": "Bearer <token>"}
response = requests.post(url, headers=headers)
print(response.text)const options = {method: 'POST', headers: {Authorization: 'Bearer <token>'}};
fetch('https://api.goyappr.com/sip-endpoints/{id}/rotate-password', options)
.then(res => res.json())
.then(res => console.log(res))
.catch(err => console.error(err));<?php
$curl = curl_init();
curl_setopt_array($curl, [
CURLOPT_URL => "https://api.goyappr.com/sip-endpoints/{id}/rotate-password",
CURLOPT_RETURNTRANSFER => true,
CURLOPT_ENCODING => "",
CURLOPT_MAXREDIRS => 10,
CURLOPT_TIMEOUT => 30,
CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
CURLOPT_CUSTOMREQUEST => "POST",
CURLOPT_HTTPHEADER => [
"Authorization: Bearer <token>"
],
]);
$response = curl_exec($curl);
$err = curl_error($curl);
curl_close($curl);
if ($err) {
echo "cURL Error #:" . $err;
} else {
echo $response;
}package main
import (
"fmt"
"net/http"
"io"
)
func main() {
url := "https://api.goyappr.com/sip-endpoints/{id}/rotate-password"
req, _ := http.NewRequest("POST", url, nil)
req.Header.Add("Authorization", "Bearer <token>")
res, _ := http.DefaultClient.Do(req)
defer res.Body.Close()
body, _ := io.ReadAll(res.Body)
fmt.Println(string(body))
}HttpResponse<String> response = Unirest.post("https://api.goyappr.com/sip-endpoints/{id}/rotate-password")
.header("Authorization", "Bearer <token>")
.asString();require 'uri'
require 'net/http'
url = URI("https://api.goyappr.com/sip-endpoints/{id}/rotate-password")
http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true
request = Net::HTTP::Post.new(url)
request["Authorization"] = 'Bearer <token>'
response = http.request(request)
puts response.read_body{
"data": {
"id": "3c90c3cc-0d44-4b50-8888-8dd25736052a",
"name": "Main office PBX",
"auth_mode": "credentials",
"slug": "after-hours-bz3r3mtypuwuw8tpdw3x392s",
"sip_uri": "sip:after-hours-bz3r3mtypuwuw8tpdw3x392s@yappr-byoc.sip.telnyx.com",
"inbound_agent_id": "3c90c3cc-0d44-4b50-8888-8dd25736052a",
"is_active": true,
"last_call_at": "2023-11-07T05:31:56Z",
"created_at": "2023-11-07T05:31:56Z",
"updated_at": "2023-11-07T05:31:56Z",
"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"
},
"allowed_source_ips": [
"203.0.113.0/24"
],
"sip_password": "Ex4mpleOnlyNotARealPassword12345"
}
}{
"error": "<string>",
"code": "<string>"
}{
"error": "<string>",
"code": "<string>"
}{
"error": "<string>",
"code": "<string>"
}{
"error": "<string>",
"code": "<string>"
}{
"error": "<string>",
"code": "<string>"
}{
"error": "<string>",
"code": "<string>"
}{
"error": "<string>",
"code": "<string>"
}{
"error": "<string>",
"code": "<string>"
}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.
curl -X POST https://api.goyappr.com/sip-endpoints/8d0c5f4e-2b1a-4c3d-9e8f-7a6b5c4d3e2f/rotate-password \
-H "Authorization: Bearer ypr_live_..."
{
"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"
}
}
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.
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. |
Authorizations
Your Yappr API key (e.g. ypr_live_...). Generate one in the dashboard under Settings → API Keys.
Path Parameters
Response
The trunk, with its new password in sip_password. Store it now; it is never shown again.
The endpoint, as create and
rotate-password return it.
On a username-and-password trunk it carries sip_password, the only
time the password is ever returned.
Show child attributes
Show child attributes