API reference
Phone numbers
The account's numbers, SIP, Twilio or Telnyx: list them, choose the agent that answers each one, and register or delete SIP numbers.
/v1/phonesPATCH/v1/phones/{phoneId}PATCH/v1/phones/sip/{phoneId}DELETE/v1/phones/sip/{phoneId}GET/v1/phones/sipPOST/v1/phones/sipList phone numbers
/v1/phonesList every phone number of the authenticated tenant, whatever the way it reached the account: a connected SIP trunk, or a number imported from a vendor such as Twilio or Telnyx. Use GET /phones/sip to list only the SIP ones. Filter on an entity to get only its numbers.
Authorization
AuthorizationstringrequiredBearer <API key>, a key created at app.callshift.ai/api-keys.
Query parameters
pageintegerlimitintegerentityIdstring<uuid>Return only the items of this entity. Send this or entityExternalId, not both.
entityExternalIdstringReturn only the items of the entity with this external id. Send this or entityId, not both.
Responses
Phones listed successfully
dataobject[]requiredShow child attributes
idstring<uuid>requiredphoneNumberstringrequiredproviderenum<string>requiredHow the number reached the account: a connected SIP trunk, or an import from the vendor.
siptwiliotelnyxisOutboundAllowedbooleanrequiredagentobject | nullrequiredShow child attributes
idstring<uuid>requirednamestringrequiredentityIdstring<uuid> | nullrequiredThe number's entity, or null when the number is shared.
pageCountnumberrequiredInvalid request
successenum<boolean>requiredfalseerrorobjectrequiredShow child attributes
nameenum<string>requiredZodErrorissuesobject[]requiredShow child attributes
codestringrequiredpathstring | number[]requiredmessagestringrequiredUnauthorized
errorstringrequiredEntity not found
errorstringrequiredInternal server error
errorstringrequiredcurl "https://api.callshift.ai/v1/phones" \
-H "Authorization: Bearer $CALLSHIFT_API_KEY"const res = await fetch("https://api.callshift.ai/v1/phones", {
headers: {
Authorization: `Bearer ${process.env.CALLSHIFT_API_KEY}`,
},
});
const data = await res.json();import os
import requests
res = requests.get(
"https://api.callshift.ai/v1/phones",
headers={"Authorization": f"Bearer {os.environ['CALLSHIFT_API_KEY']}"},
)
print(res.json()){
"data": [
{
"id": "0d3a7e6b-2b8e-4c5b-9c4e-5f4b9d2a1c8e",
"phoneNumber": "+15550001234",
"provider": "twilio",
"isOutboundAllowed": true,
"agent": {
"id": "550e8400-e29b-41d4-a716-446655440000",
"name": "Alice"
},
"entityId": null
}
],
"pageCount": 3
}{
"success": false,
"error": {
"name": "ZodError",
"issues": [
{
"code": "invalid_enum_value",
"path": [
"contacts",
0,
"email"
],
"message": "Invalid email"
}
]
}
}{
"error": "Authentication error"
}{
"error": "Entity not found"
}{
"error": "Internal server error"
}Update a phone number
/v1/phones/{phoneId}Set (or clear, with null) the agent that answers inbound calls on this number, and the entity it belongs to, whatever its provider: SIP, Twilio or Telnyx. Use GET /phones to find the phone id.
Authorization
AuthorizationstringrequiredBearer <API key>, a key created at app.callshift.ai/api-keys.
Path parameters
phoneIdstring<uuid>requiredBody application/json
agentIdstring<uuid> | nullAgent answering inbound calls on this number; null unassigns it.
entityIdstring<uuid> | nullThe entity the item belongs to, or null to make it shared. Send this or entityExternalId, not both.
entityExternalIdstring | nullYour external id of the entity the item belongs to, or null to make it shared. Send this or entityId, not both.
Responses
Phone updated successfully
successbooleanrequiredInvalid payload, or agent not found in this account
errorstringrequiredUnauthorized
errorstringrequiredPhone or entity not found
errorstringrequiredThe change would link items of two different entities. The error names them.
errorstringrequiredInternal server error
errorstringrequiredcurl -X PATCH "https://api.callshift.ai/v1/phones/550e8400-e29b-41d4-a716-446655440000" \
-H "Authorization: Bearer $CALLSHIFT_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"agentId": "550e8400-e29b-41d4-a716-446655440000"
}'const res = await fetch("https://api.callshift.ai/v1/phones/550e8400-e29b-41d4-a716-446655440000", {
method: "PATCH",
headers: {
Authorization: `Bearer ${process.env.CALLSHIFT_API_KEY}`,
"Content-Type": "application/json",
},
body: JSON.stringify({
"agentId": "550e8400-e29b-41d4-a716-446655440000"
}),
});
const data = await res.json();import os
import requests
res = requests.patch(
"https://api.callshift.ai/v1/phones/550e8400-e29b-41d4-a716-446655440000",
headers={"Authorization": f"Bearer {os.environ['CALLSHIFT_API_KEY']}"},
json={
"agentId": "550e8400-e29b-41d4-a716-446655440000",
},
)
print(res.json()){
"success": true
}{
"error": "Invalid payload, or agent not found in this account"
}{
"error": "Authentication error"
}{
"error": "Phone or entity not found"
}{
"error": "The change would link items of two different entities. The error names them"
}{
"error": "Internal server error"
}Update a SIP phone number
/v1/phones/sip/{phoneId}Same as PATCH /v1/phones/{phoneId}, which works for every provider. Calls-per-second is a property of the SIP trunk, see GET /v1/trunks.
Authorization
AuthorizationstringrequiredBearer <API key>, a key created at app.callshift.ai/api-keys.
Path parameters
phoneIdstring<uuid>requiredBody application/json
agentIdstring<uuid> | nullAgent answering inbound calls on this number; null unassigns it.
entityIdstring<uuid> | nullThe entity the item belongs to, or null to make it shared. Send this or entityExternalId, not both.
entityExternalIdstring | nullYour external id of the entity the item belongs to, or null to make it shared. Send this or entityId, not both.
Responses
Phone updated successfully
successbooleanrequiredInvalid payload, or agent not found in this account
errorstringrequiredUnauthorized
errorstringrequiredPhone or entity not found
errorstringrequiredThe change would link items of two different entities. The error names them.
errorstringrequiredInternal server error
errorstringrequiredcurl -X PATCH "https://api.callshift.ai/v1/phones/sip/550e8400-e29b-41d4-a716-446655440000" \
-H "Authorization: Bearer $CALLSHIFT_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"agentId": "550e8400-e29b-41d4-a716-446655440000"
}'const res = await fetch("https://api.callshift.ai/v1/phones/sip/550e8400-e29b-41d4-a716-446655440000", {
method: "PATCH",
headers: {
Authorization: `Bearer ${process.env.CALLSHIFT_API_KEY}`,
"Content-Type": "application/json",
},
body: JSON.stringify({
"agentId": "550e8400-e29b-41d4-a716-446655440000"
}),
});
const data = await res.json();import os
import requests
res = requests.patch(
"https://api.callshift.ai/v1/phones/sip/550e8400-e29b-41d4-a716-446655440000",
headers={"Authorization": f"Bearer {os.environ['CALLSHIFT_API_KEY']}"},
json={
"agentId": "550e8400-e29b-41d4-a716-446655440000",
},
)
print(res.json()){
"success": true
}{
"error": "Invalid payload, or agent not found in this account"
}{
"error": "Authentication error"
}{
"error": "Phone or entity not found"
}{
"error": "The change would link items of two different entities. The error names them"
}{
"error": "Internal server error"
}Delete a SIP phone number
/v1/phones/sip/{phoneId}Delete a SIP phone number and detach it from its outbound SIP trunk.
Authorization
AuthorizationstringrequiredBearer <API key>, a key created at app.callshift.ai/api-keys.
Path parameters
phoneIdstring<uuid>requiredResponses
SIP phone deleted successfully
No content.
Unauthorized
errorstringrequiredPhone not found
errorstringrequiredInternal server error
errorstringrequiredcurl -X DELETE "https://api.callshift.ai/v1/phones/sip/550e8400-e29b-41d4-a716-446655440000" \
-H "Authorization: Bearer $CALLSHIFT_API_KEY"const res = await fetch("https://api.callshift.ai/v1/phones/sip/550e8400-e29b-41d4-a716-446655440000", {
method: "DELETE",
headers: {
Authorization: `Bearer ${process.env.CALLSHIFT_API_KEY}`,
},
});
console.log(res.status); // 204import os
import requests
res = requests.delete(
"https://api.callshift.ai/v1/phones/sip/550e8400-e29b-41d4-a716-446655440000",
headers={"Authorization": f"Bearer {os.environ['CALLSHIFT_API_KEY']}"},
)
print(res.status_code) # 204No content{
"error": "Authentication error"
}{
"error": "Phone not found"
}{
"error": "Internal server error"
}List SIP phone numbers
/v1/phones/sipList all SIP phone numbers for the authenticated tenant, optionally only those of one entity.
Authorization
AuthorizationstringrequiredBearer <API key>, a key created at app.callshift.ai/api-keys.
Query parameters
pageintegerlimitintegerentityIdstring<uuid>Return only the items of this entity. Send this or entityExternalId, not both.
entityExternalIdstringReturn only the items of the entity with this external id. Send this or entityId, not both.
Responses
SIP phones listed successfully
dataobject[]requiredShow child attributes
idstring<uuid>requiredphoneNumberstringrequiredagentobject | nullrequiredShow child attributes
idstring<uuid>requirednamestringrequiredentityIdstring<uuid> | nullrequiredThe number's entity, or null when the number is shared.
pageCountnumberrequiredInvalid request
successenum<boolean>requiredfalseerrorobjectrequiredShow child attributes
nameenum<string>requiredZodErrorissuesobject[]requiredShow child attributes
codestringrequiredpathstring | number[]requiredmessagestringrequiredUnauthorized
errorstringrequiredEntity not found
errorstringrequiredInternal server error
errorstringrequiredcurl "https://api.callshift.ai/v1/phones/sip" \
-H "Authorization: Bearer $CALLSHIFT_API_KEY"const res = await fetch("https://api.callshift.ai/v1/phones/sip", {
headers: {
Authorization: `Bearer ${process.env.CALLSHIFT_API_KEY}`,
},
});
const data = await res.json();import os
import requests
res = requests.get(
"https://api.callshift.ai/v1/phones/sip",
headers={"Authorization": f"Bearer {os.environ['CALLSHIFT_API_KEY']}"},
)
print(res.json()){
"data": [
{
"id": "0d3a7e6b-2b8e-4c5b-9c4e-5f4b9d2a1c8e",
"phoneNumber": "+15550001234",
"agent": {
"id": "550e8400-e29b-41d4-a716-446655440000",
"name": "Alice"
},
"entityId": null
}
],
"pageCount": 3
}{
"success": false,
"error": {
"name": "ZodError",
"issues": [
{
"code": "invalid_enum_value",
"path": [
"contacts",
0,
"email"
],
"message": "Invalid email"
}
]
}
}{
"error": "Authentication error"
}{
"error": "Entity not found"
}{
"error": "Internal server error"
}Create a SIP phone number
/v1/phones/sipConnect a SIP trunk and register the phone number for the authenticated tenant.
Authorization
AuthorizationstringrequiredBearer <API key>, a key created at app.callshift.ai/api-keys.
Body application/json
phoneNumberstringrequiredagentIdstring<uuid> | nullsipTrunkIdstring<uuid>Attach the number to an existing SIP trunk. When set, the trunk definition fields are ignored.
namestringName for a newly created trunk. Defaults to the termination URI.
terminationUristringtransportenum<number>SIP transport: 1=UDP, 2=TCP, 3=TLS
123sipUsernamestring | nullsipPasswordstring | nullrequireInboundAuthbooleanGenerate credentials the carrier must send on inbound calls. Defaults to false; ignored when sipTrunkId is set.
entityIdstring<uuid> | nullThe entity the item belongs to, or null to make it shared. Send this or entityExternalId, not both.
entityExternalIdstring | nullYour external id of the entity the item belongs to, or null to make it shared. Send this or entityId, not both.
Responses
SIP phone created successfully
idstring<uuid>requiredInvalid agent
errorstringrequiredUnauthorized
errorstringrequiredSIP trunk or entity not found
errorstringrequiredPhone number already exists, or the agent belongs to another entity
errorstringrequiredInternal server error
errorstringrequiredcurl -X POST "https://api.callshift.ai/v1/phones/sip" \
-H "Authorization: Bearer $CALLSHIFT_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"phoneNumber": "+33187654321",
"name": "acme-sip",
"terminationUri": "sip.example.com",
"transport": 1,
"sipUsername": "acme",
"sipPassword": "your-sip-password",
"agentId": "550e8400-e29b-41d4-a716-446655440000"
}'const res = await fetch("https://api.callshift.ai/v1/phones/sip", {
method: "POST",
headers: {
Authorization: `Bearer ${process.env.CALLSHIFT_API_KEY}`,
"Content-Type": "application/json",
},
body: JSON.stringify({
"phoneNumber": "+33187654321",
"name": "acme-sip",
"terminationUri": "sip.example.com",
"transport": 1,
"sipUsername": "acme",
"sipPassword": "your-sip-password",
"agentId": "550e8400-e29b-41d4-a716-446655440000"
}),
});
const data = await res.json();import os
import requests
res = requests.post(
"https://api.callshift.ai/v1/phones/sip",
headers={"Authorization": f"Bearer {os.environ['CALLSHIFT_API_KEY']}"},
json={
"phoneNumber": "+33187654321",
"name": "acme-sip",
"terminationUri": "sip.example.com",
"transport": 1,
"sipUsername": "acme",
"sipPassword": "your-sip-password",
"agentId": "550e8400-e29b-41d4-a716-446655440000",
},
)
print(res.json()){
"id": "550e8400-e29b-41d4-a716-446655440000"
}{
"error": "Invalid agent"
}{
"error": "Authentication error"
}{
"error": "SIP trunk or entity not found"
}{
"error": "Phone number already exists, or the agent belongs to another entity"
}{
"error": "Internal server error"
}