API reference
Entities
Units of the account, such as the clubs of a franchise or the clients of a call center, that group agents, phone numbers and webhooks.
/v1/entitiesPOST/v1/entitiesGET/v1/entities/{entityId}PATCH/v1/entities/{entityId}DELETE/v1/entities/{entityId}POST/v1/entities/{entityId}/move-itemsList entities
/v1/entitiesAn entity is a subdivision of your account — a club of a franchise, a client of a call center, a practice — that groups agents, phone numbers and webhooks. Items that belong to no entity are shared and usable by every entity. An entity is not a security boundary: every API key sees the whole account.
Entities are sorted by name, each with the number of agents, phone numbers and webhooks it holds.
Authorization
AuthorizationstringrequiredBearer <API key>, a key created at app.callshift.ai/api-keys.
Query parameters
pageintegerlimitintegerexternalIdstringReturn only the entity with this exact external id.
Responses
Entities listed successfully
dataobject[]requiredShow child attributes
idstring<uuid>requirednamestringrequiredexternalIdstring | nullrequiredYour own identifier for the entity, unique within the account.
createdAtstringrequiredupdatedAtstringrequiredusageobjectrequiredWhat the entity holds. Deleted agents and numbers are not counted.
Show child attributes
agentsintegerrequiredphoneNumbersintegerrequiredwebhooksintegerrequiredpageCountnumberrequiredInvalid request
successenum<boolean>requiredfalseerrorobjectrequiredShow child attributes
nameenum<string>requiredZodErrorissuesobject[]requiredShow child attributes
codestringrequiredpathstring | number[]requiredmessagestringrequiredUnauthorized
errorstringrequiredInternal server error
errorstringrequiredcurl "https://api.callshift.ai/v1/entities?externalId=club-42" \
-H "Authorization: Bearer $CALLSHIFT_API_KEY"const res = await fetch("https://api.callshift.ai/v1/entities?externalId=club-42", {
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/entities?externalId=club-42",
headers={"Authorization": f"Bearer {os.environ['CALLSHIFT_API_KEY']}"},
)
print(res.json()){
"data": [
{
"id": "550e8400-e29b-41d4-a716-446655440000",
"name": "Lyon Part-Dieu",
"externalId": "club-42",
"createdAt": "2026-01-01T00:00:00.000Z",
"updatedAt": "2026-01-01T00:00:00.000Z",
"usage": {
"agents": 3,
"phoneNumbers": 2,
"webhooks": 1
}
}
],
"pageCount": 3
}{
"success": false,
"error": {
"name": "ZodError",
"issues": [
{
"code": "invalid_enum_value",
"path": [
"contacts",
0,
"email"
],
"message": "Invalid email"
}
]
}
}{
"error": "Authentication error"
}{
"error": "Internal server error"
}Create an entity
/v1/entitiesAn entity is a subdivision of your account — a club of a franchise, a client of a call center, a practice — that groups agents, phone numbers and webhooks. Items that belong to no entity are shared and usable by every entity. An entity is not a security boundary: every API key sees the whole account.
The name and the external id must each be unique within the account. When the external id is taken, the 409 carries the id of the entity that holds it, so provisioning can be retried safely.
Authorization
AuthorizationstringrequiredBearer <API key>, a key created at app.callshift.ai/api-keys.
Body application/json
namestringrequiredexternalIdstring | nullYour own identifier for the entity, unique within the account.
Responses
Entity created successfully
idstring<uuid>requirednamestringrequiredexternalIdstring | nullrequiredYour own identifier for the entity, unique within the account.
createdAtstringrequiredupdatedAtstringrequiredInvalid request
successenum<boolean>requiredfalseerrorobjectrequiredShow child attributes
nameenum<string>requiredZodErrorissuesobject[]requiredShow child attributes
codestringrequiredpathstring | number[]requiredmessagestringrequiredUnauthorized
errorstringrequiredThe name or the external id is already used by another entity
errorstringrequiredexistingEntityIdstring<uuid>Set when the external id is taken: the entity that holds it, so a retried provisioning can adopt it.
Internal server error
errorstringrequiredcurl -X POST "https://api.callshift.ai/v1/entities" \
-H "Authorization: Bearer $CALLSHIFT_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"name": "Lyon Part-Dieu",
"externalId": "club-42"
}'const res = await fetch("https://api.callshift.ai/v1/entities", {
method: "POST",
headers: {
Authorization: `Bearer ${process.env.CALLSHIFT_API_KEY}`,
"Content-Type": "application/json",
},
body: JSON.stringify({
"name": "Lyon Part-Dieu",
"externalId": "club-42"
}),
});
const data = await res.json();import os
import requests
res = requests.post(
"https://api.callshift.ai/v1/entities",
headers={"Authorization": f"Bearer {os.environ['CALLSHIFT_API_KEY']}"},
json={
"name": "Lyon Part-Dieu",
"externalId": "club-42",
},
)
print(res.json()){
"id": "550e8400-e29b-41d4-a716-446655440000",
"name": "Lyon Part-Dieu",
"externalId": "club-42",
"createdAt": "2026-01-01T00:00:00.000Z",
"updatedAt": "2026-01-01T00:00:00.000Z"
}{
"success": false,
"error": {
"name": "ZodError",
"issues": [
{
"code": "invalid_enum_value",
"path": [
"contacts",
0,
"email"
],
"message": "Invalid email"
}
]
}
}{
"error": "Authentication error"
}{
"error": "The name or the external id is already used by another entity",
"existingEntityId": "550e8400-e29b-41d4-a716-446655440000"
}{
"error": "Internal server error"
}Get an entity
/v1/entities/{entityId}Get a single entity by id. To look one up by your own identifier, list entities with the externalId filter.
Authorization
AuthorizationstringrequiredBearer <API key>, a key created at app.callshift.ai/api-keys.
Path parameters
entityIdstring<uuid>requiredResponses
Entity retrieved successfully
idstring<uuid>requirednamestringrequiredexternalIdstring | nullrequiredYour own identifier for the entity, unique within the account.
createdAtstringrequiredupdatedAtstringrequiredUnauthorized
errorstringrequiredEntity not found
errorstringrequiredInternal server error
errorstringrequiredcurl "https://api.callshift.ai/v1/entities/550e8400-e29b-41d4-a716-446655440000" \
-H "Authorization: Bearer $CALLSHIFT_API_KEY"const res = await fetch("https://api.callshift.ai/v1/entities/550e8400-e29b-41d4-a716-446655440000", {
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/entities/550e8400-e29b-41d4-a716-446655440000",
headers={"Authorization": f"Bearer {os.environ['CALLSHIFT_API_KEY']}"},
)
print(res.json()){
"id": "550e8400-e29b-41d4-a716-446655440000",
"name": "Lyon Part-Dieu",
"externalId": "club-42",
"createdAt": "2026-01-01T00:00:00.000Z",
"updatedAt": "2026-01-01T00:00:00.000Z"
}{
"error": "Authentication error"
}{
"error": "Entity not found"
}{
"error": "Internal server error"
}Update an entity
/v1/entities/{entityId}Rename an entity, or change or remove its external id.
Authorization
AuthorizationstringrequiredBearer <API key>, a key created at app.callshift.ai/api-keys.
Path parameters
entityIdstring<uuid>requiredBody application/json
namestringexternalIdstring | nullnull removes the external id.
Responses
Entity updated successfully
idstring<uuid>requirednamestringrequiredexternalIdstring | nullrequiredYour own identifier for the entity, unique within the account.
createdAtstringrequiredupdatedAtstringrequiredInvalid request
successenum<boolean>requiredfalseerrorobjectrequiredShow child attributes
nameenum<string>requiredZodErrorissuesobject[]requiredShow child attributes
codestringrequiredpathstring | number[]requiredmessagestringrequiredUnauthorized
errorstringrequiredEntity not found
errorstringrequiredThe name or the external id is already used by another entity
errorstringrequiredexistingEntityIdstring<uuid>Set when the external id is taken: the entity that holds it, so a retried provisioning can adopt it.
Internal server error
errorstringrequiredcurl -X PATCH "https://api.callshift.ai/v1/entities/550e8400-e29b-41d4-a716-446655440000" \
-H "Authorization: Bearer $CALLSHIFT_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"name": "Lyon Part-Dieu Centre"
}'const res = await fetch("https://api.callshift.ai/v1/entities/550e8400-e29b-41d4-a716-446655440000", {
method: "PATCH",
headers: {
Authorization: `Bearer ${process.env.CALLSHIFT_API_KEY}`,
"Content-Type": "application/json",
},
body: JSON.stringify({
"name": "Lyon Part-Dieu Centre"
}),
});
const data = await res.json();import os
import requests
res = requests.patch(
"https://api.callshift.ai/v1/entities/550e8400-e29b-41d4-a716-446655440000",
headers={"Authorization": f"Bearer {os.environ['CALLSHIFT_API_KEY']}"},
json={
"name": "Lyon Part-Dieu Centre",
},
)
print(res.json()){
"id": "550e8400-e29b-41d4-a716-446655440000",
"name": "Lyon Part-Dieu",
"externalId": "club-42",
"createdAt": "2026-01-01T00:00:00.000Z",
"updatedAt": "2026-01-01T00:00:00.000Z"
}{
"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": "The name or the external id is already used by another entity",
"existingEntityId": "550e8400-e29b-41d4-a716-446655440000"
}{
"error": "Internal server error"
}Delete an entity
/v1/entities/{entityId}Delete an entity that holds nothing. While it still holds agents, phone numbers or webhooks the request is refused with what remains, rather than silently making those items shared.
Authorization
AuthorizationstringrequiredBearer <API key>, a key created at app.callshift.ai/api-keys.
Path parameters
entityIdstring<uuid>requiredResponses
Entity deleted successfully
No content.
Unauthorized
errorstringrequiredEntity not found
errorstringrequiredThe entity still holds agents, phone numbers or webhooks. Move them first.
errorstringrequiredusageobjectrequiredWhat the entity holds. Deleted agents and numbers are not counted.
Show child attributes
agentsintegerrequiredphoneNumbersintegerrequiredwebhooksintegerrequiredInternal server error
errorstringrequiredcurl -X DELETE "https://api.callshift.ai/v1/entities/550e8400-e29b-41d4-a716-446655440000" \
-H "Authorization: Bearer $CALLSHIFT_API_KEY"const res = await fetch("https://api.callshift.ai/v1/entities/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/entities/550e8400-e29b-41d4-a716-446655440000",
headers={"Authorization": f"Bearer {os.environ['CALLSHIFT_API_KEY']}"},
)
print(res.status_code) # 204No content{
"error": "Authentication error"
}{
"error": "Entity not found"
}{
"error": "The entity still holds agents, phone numbers or webhooks. Move them first",
"usage": {
"agents": 3,
"phoneNumbers": 2,
"webhooks": 1
}
}{
"error": "Internal server error"
}Move everything an entity holds
/v1/entities/{entityId}/move-itemsMove all of the entity's agents, phone numbers and webhooks to another entity, or make them shared, so it can be merged into another or wound down and then deleted. The entity itself is kept, and the calls it made keep it.
Authorization
AuthorizationstringrequiredBearer <API key>, a key created at app.callshift.ai/api-keys.
Path parameters
entityIdstring<uuid>requiredBody application/json
entityIdstring<uuid> | nullThe entity to move the items to, or null to make them shared. Send this or entityExternalId.
entityExternalIdstring | nullYour external id of the entity to move the items to, or null to make them shared. Send this or entityId.
Responses
How many of each item moved
movedobjectrequiredWhat the entity holds. Deleted agents and numbers are not counted.
Show child attributes
agentsintegerrequiredphoneNumbersintegerrequiredwebhooksintegerrequiredInvalid request
successenum<boolean>requiredfalseerrorobjectrequiredShow child attributes
nameenum<string>requiredZodErrorissuesobject[]requiredShow child attributes
codestringrequiredpathstring | number[]requiredmessagestringrequiredUnauthorized
errorstringrequiredThe entity or the target entity was not found
errorstringrequiredInternal server error
errorstringrequiredcurl -X POST "https://api.callshift.ai/v1/entities/550e8400-e29b-41d4-a716-446655440000/move-items" \
-H "Authorization: Bearer $CALLSHIFT_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"entityExternalId": "club-7"
}'const res = await fetch("https://api.callshift.ai/v1/entities/550e8400-e29b-41d4-a716-446655440000/move-items", {
method: "POST",
headers: {
Authorization: `Bearer ${process.env.CALLSHIFT_API_KEY}`,
"Content-Type": "application/json",
},
body: JSON.stringify({
"entityExternalId": "club-7"
}),
});
const data = await res.json();import os
import requests
res = requests.post(
"https://api.callshift.ai/v1/entities/550e8400-e29b-41d4-a716-446655440000/move-items",
headers={"Authorization": f"Bearer {os.environ['CALLSHIFT_API_KEY']}"},
json={
"entityExternalId": "club-7",
},
)
print(res.json()){
"moved": {
"agents": 3,
"phoneNumbers": 2,
"webhooks": 1
}
}{
"success": false,
"error": {
"name": "ZodError",
"issues": [
{
"code": "invalid_enum_value",
"path": [
"contacts",
0,
"email"
],
"message": "Invalid email"
}
]
}
}{
"error": "Authentication error"
}{
"error": "The entity or the target entity was not found"
}{
"error": "Internal server error"
}