API routes
Every route the backend serves, grouped by domain. Paths registered by a DRF router carry a
trailing slash; hand-written path() entries do not. The difference is reproduced exactly
below — it matters when you call them.
Unless stated otherwise, /api/v1 routes require a JWT bearer token. Remember that DRF's
default permission in this project is AllowAny, so authorization is whatever each view
declares; see Backend → Authentication.
Root prefixes
| Prefix |
Module |
/admin/ |
Django admin |
/api/v1/ |
voip.urls |
/webhooks/ |
voip.urls_wh — current Twilio webhooks |
/twilio/hooks/ |
calls.urls — legacy Twilio routes |
/google/hooks/ |
google_hooks.urls — scheduler triggers |
handler404 and handler500 return JSON.
Auth and session
| Method |
Path |
View |
Description |
| POST |
/api/v1/login |
CustomTokenObtainPairView |
Email and password login; returns an access/refresh pair |
| POST |
/api/v1/login-firebase |
CustomTokenObtainPairFirebaseView |
Login with a Firebase ID token |
| POST |
/api/v1/login/refresh |
TokenRefreshView |
Exchange a refresh token for a new access token |
| POST |
/api/v1/tokenverify |
TokenVerifyView |
Check whether a token is still valid |
| POST |
/api/v1/logout |
LogoutView |
Blacklist the refresh token |
| POST |
/api/v1/reset_password/send_token |
password_reset_send_email_token |
Email a password-reset token |
| POST |
/api/v1/reset_password/check_token |
password_reset_check_email_token |
Validate a reset token |
| POST |
/api/v1/reset_password/set_password |
password_reset_change_password |
Set a new password with a valid token |
| GET, POST |
/api/v1/login_methods |
FirebaseUserView |
List linked Firebase identities; POST links a new one |
| POST |
/api/v1/login_methods/remove |
FirebaseUserRemoveView |
Unlink identities in bulk, deleting them in Firebase too |
| GET, POST |
/api/v1/login_methods_providers/ |
LoginMethodView |
List (public) or create login-method providers |
| GET, PUT, PATCH, DELETE |
/api/v1/login_methods_providers/{pk}/ |
LoginMethodView |
Retrieve, update or delete a provider |
Users
| Method |
Path |
View |
Description |
| GET |
/api/v1/user |
get_user_data |
The authenticated user's own profile |
| GET |
/api/v1/user-list |
UserListView |
Paginated users in the caller's company; ?filter= |
| PUT |
/api/v1/profile |
update_profile |
Update own profile |
| GET |
/api/v1/agents/user/ |
UserAgentsListApiView |
Company users usable as call agents |
| GET |
/api/v1/agents/user/{pk}/ |
UserAgentsListApiView |
One user agent |
Companies
| Method |
Path |
View |
Description |
| GET, POST |
/api/v1/company |
ListAndCreateCompaniesView |
Searchable company list (searchText, orderBy, asc, all); POST is admin-only |
| GET, PUT, DELETE |
/api/v1/company/<int:id> |
GetUpdateAndDeleteACompanyView |
One company |
| POST |
/api/v1/company/remove |
CompanyMultiRemoveView |
Bulk delete by ids* keys |
| GET |
/api/v1/company/validation |
CompanyValidationView |
Configuration errors for the caller's default company |
| POST |
/api/v1/company-controls/<int:id> |
CompanyControlsView |
Update feature-control flags |
Company users
| Method |
Path |
View |
Description |
| GET, POST |
/api/v1/companyUser |
ListAndCreateCompanyUserView |
Memberships; POST invites or creates |
| GET, PUT, DELETE |
/api/v1/companyUser/<int:id> |
GetUpdateAndDeleteCompanyUserView |
One membership |
| PUT |
/api/v1/companyUser/role/<int:id> |
CompanyUserRoleView |
Change a member's role |
| POST |
/api/v1/companyUser/remove |
CompanyUserMultiRemoveView |
Bulk delete |
| POST |
/api/v1/phone_number_agreement |
CompanyUserPhoneNumberTermsAgreementView |
Record acceptance of the phone-number terms |
| Method |
Path |
View |
Description |
| GET, POST |
/api/v1/contact |
ContactListAndCreateView |
Company address book |
| GET, PUT, DELETE |
/api/v1/contact/<int:contact_id> |
ContactGetUpdateAndDeleteView |
One contact |
| POST |
/api/v1/contact/remove |
ContactMultiRemoveView |
Bulk delete |
| POST |
/api/v1/contact/import |
ContactsFileImporterView |
Import from an uploaded vCard or CSV |
| POST |
/api/v1/contact/native-import |
NativeContactsImporterView |
Import device contacts as JSON, skipping blanks and duplicates |
Calls and call traces
| Method |
Path |
View |
Description |
| GET |
/api/v1/call |
ListCallView |
Call history; ?filter= by phone or contact |
| GET |
/api/v1/call/info/<id> |
CallInfoView |
One call in the caller's company |
| POST |
/api/v1/call/remove |
CallMultiRemoveView |
Bulk delete by calls_id* keys |
| POST |
/api/v1/call/add_callee |
ConfAddApiView |
Add a user agent, SIP credential or number to a live conference |
| POST |
/api/v1/webhook/call |
webhook_incoming_call |
Legacy incoming-call webhook; CSRF-exempt, Twilio-signature validated |
| GET |
/api/v1/availableCallTrace |
AvailableCallTraceView |
Claim the next call available to this agent |
| GET |
/api/v1/history/phoneNumber/<str:phone_number> |
HistoryPhoneNumberView |
Call history for one number |
| GET, POST |
/api/v1/stateTrace |
ListAndCreateStateTracesAPIView |
Agent state traces; POST records a status |
| GET |
/api/v1/stateTrace/heartbeat |
HeartBeatApiView |
Liveness heartbeat for the detected platform |
| POST |
/api/v1/stateTrace/set |
SetAgentStatusApiView |
Set the agent online or offline |
| GET |
/api/v1/calls/twilio/token |
AdapterTwilioTokenView |
Issue a Twilio Voice access token for the client |
GetAndCreateStateTracesAPIView is unreachable
It is registered on the identical /api/v1/stateTrace path as
ListAndCreateStateTracesAPIView, which always matches first. Its get and put also
require a state_trace_id kwarg that the route never supplies.
Recordings, transcriptions and voice messages
| Method |
Path |
View |
Description |
| GET |
/api/v1/call/extras/<call_id> |
CallExtrasView |
A call's recordings and transcriptions |
| GET, POST |
/api/v1/call-record |
CallRecordView |
Company recording and transcription settings |
| GET, POST |
/api/v1/call/messages/ |
CallMessageView |
Recorded or text-to-speech call messages |
| GET, PUT, PATCH, DELETE |
/api/v1/call/messages/{pk}/ |
CallMessageView |
One call message |
| POST |
/api/v1/call/messages/remove |
CallMessageMultiRemoveView |
Bulk delete |
Messages and SMS
| Method |
Path |
View |
Description |
| GET |
/api/v1/messages |
ListMessagesView |
SMS threads for the company |
| GET, POST, PUT |
/api/v1/messages/<str:phone_number> |
MessageView |
GET the conversation and mark it read; POST sends; PUT updates |
| GET, POST |
/api/v1/fail-call-sms |
FailCallSMSView |
The automatic SMS sent on a failed or missed call |
Phone numbers
| Method |
Path |
View |
Description |
| GET |
/api/v1/phoneNumber |
ListAndCreatePhoneNumberView |
The company's numbers. Despite the name, only get is defined |
| GET, PUT, DELETE |
/api/v1/phoneNumber/<int:phone_number_id> |
GetUpdateAndDeletePhoneNumberView |
Retrieve, update or release a number |
| POST |
/api/v1/phoneNumber/stripe/<int:id> |
PhoneNumberPayView |
Start Stripe checkout for a number; returns a url |
| GET, POST |
/api/v1/availablePhoneNumber |
ListPhoneNumberView |
GET searches Twilio for purchasable numbers; POST provisions one |
Extensions
| Method |
Path |
View |
Description |
| GET, POST |
/api/v1/extension |
ListAndCreateExtensionView |
Extensions for the company |
| GET, POST |
/api/v1/call-extensions/ |
CallExtensionView |
Call-routing extensions |
| GET, PUT, PATCH, DELETE |
/api/v1/call-extensions/{pk}/ |
CallExtensionView |
One call extension |
| POST |
/api/v1/call-extensions/remove |
CallExtensionsMultiRemoveView |
Bulk delete |
The extension detail route cannot match
It is registered literally as extension/int:extension_id — without the angle brackets
— so no numeric URL reaches GetUpdateAndDeleteExtensionView.
SIP
| Method |
Path |
View |
Description |
| GET, POST |
/api/v1/sip/domains/ |
SipDomainViewSet |
Twilio SIP domains |
| GET, PUT, PATCH, DELETE |
/api/v1/sip/domains/{pk}/ |
SipDomainViewSet |
One domain, synced with Twilio |
| GET, POST |
/api/v1/sip/credentials_list/ |
SipCredentialsListViewSet |
Credential lists attached to a domain |
| GET, PUT, PATCH, DELETE |
/api/v1/sip/credentials_list/{pk}/ |
SipCredentialsListViewSet |
One credential list |
| GET, POST |
/api/v1/sip/credentials/ |
SipCredentialViewSet |
SIP credentials |
| GET, PUT, PATCH, DELETE |
/api/v1/sip/credentials/{pk}/ |
SipCredentialViewSet |
One credential |
| PUT |
/api/v1/sip/credential/call_status/<pk> |
SipCredentialCallStatusView |
Flip a credential between available and occupied, updating its CallTrace |
| GET |
/api/v1/agents/sip/ |
SipAgentsListApiView |
SIP credentials usable as call agents |
| GET |
/api/v1/agents/sip/{pk}/ |
SipAgentsListApiView |
One SIP agent |
Notifications
| Method |
Path |
View |
Description |
| GET, POST |
/api/v1/notifications/ |
NotificationView |
The user's notifications; ?readed= filter |
| PUT |
/api/v1/notifications/{pk}/ |
NotificationView |
Update one, for example to mark it read. Only update is defined |
| POST |
/api/v1/fcm/token/ |
UserFCMTokenView |
Store or replace the user's FCM push token |
| GET, PUT |
/api/v1/notification-type-users/{pk}/ |
NotificationTypeUserView |
Per-member notification preferences. There is no list route |
Notes
| Method |
Path |
View |
Description |
| GET, POST |
/api/v1/notes/ |
NoteView |
Notes, with reminders, attached to calls or contacts |
| GET, PUT, PATCH, DELETE |
/api/v1/notes/{pk}/ |
NoteView |
One note |
| GET |
/api/v1/list-notes |
NotesListView |
Paginated note list |
| POST |
/api/v1/note/remove |
NotesMultiRemoveView |
Bulk delete |
Attention hours
| Method |
Path |
View |
Description |
| GET, POST |
/api/v1/attention-hours |
AttentionHoursView |
Business-hours configuration |
| GET, POST |
/api/v1/attention_hours/messages/ |
AttentionHoursMessageView |
Out-of-hours messages |
| GET, PUT, PATCH, DELETE |
/api/v1/attention_hours/messages/{pk}/ |
AttentionHoursMessageView |
One message |
| POST |
/api/v1/attention-hours/messages/remove |
AttentionHoursMessageMultiRemoveView |
Bulk delete |
| GET, POST |
/api/v1/attention_hours/contacts/ |
AttentionHoursWhiteListContactView |
Contacts allowed through outside business hours |
| GET, PUT, PATCH, DELETE |
/api/v1/attention_hours/contacts/{pk}/ |
AttentionHoursWhiteListContactView |
One whitelisted contact |
| POST |
/api/v1/attention-hours/contacts/remove |
AttentionHoursWhiteListContactMultiRemoveView |
Bulk delete |
Mixed spelling
The collection routes use an underscore (attention_hours/) while the bulk-remove
routes use a hyphen (attention-hours/). Both are live; neither is a typo you can fix
without breaking a client.
Redirects and masks
| Method |
Path |
View |
Description |
| GET, POST |
/api/v1/company-redirects |
CompanyRedirectsView |
Read or replace the redirect rule groups; JSON body only |
| GET, POST |
/api/v1/phone_number_masks/ |
PhoneNumberMaskView |
Phone-number masks |
| GET, PUT, PATCH, DELETE |
/api/v1/phone_number_masks/{pk}/ |
PhoneNumberMaskView |
One mask |
| POST |
/api/v1/phone_number_masks/remove |
PhoneNumberMasksMultiRemoveView |
Bulk delete, company admin only |
Dashboard
| Method |
Path |
View |
Description |
| GET |
/api/v1/dashboard |
DashboardStatusDataView |
Company metrics over the last ?days= (default 30) plus a twelve-month series |
Stripe and billing
| Method |
Path |
View |
Description |
| GET |
/api/v1/stripe/portal |
PortalLinkView |
A Stripe customer-portal url for the company |
| POST |
/api/v1/stripe/webhook |
webhook_stripe_subscription |
Signature-verified webhook. Handles customer.subscription.created; other events are accepted and ignored |
| POST |
/api/v1/phoneNumber/stripe/<int:id> |
PhoneNumberPayView |
Checkout for a phone-number subscription |
Landing (public)
| Method |
Path |
View |
Description |
| POST |
/api/v1/landing/contact |
ClientContactView |
AllowAny contact form; creates a contact and a note on the admin company |
| POST |
/api/v1/landing/newsletter |
NewsLetterView |
Newsletter subscribe, unsubscribe or deactivate by email |
Twilio voice webhooks
Every handler subclasses BaseAdapterCallView: POST only, wrapped in an atomic transaction,
guarded by the IsTwilio signature permission. See
Telephony for how they chain together.
| Path |
View |
Description |
/webhooks/twilio/call/error |
AdapterCallErrorView |
Twilio error callback |
/webhooks/twilio/call/new |
AdapterCallNewView |
Entry point; creates the outgoing conference or enters the inbound flow |
/webhooks/twilio/call/new/lang |
AdapterCallLangView |
Language-selection Gather, or skip |
/webhooks/twilio/call/new/msg |
AdapterCallMsgView |
Apply the language, play the greeting, or skip |
/webhooks/twilio/call/new/ext/dial |
AdapterCallExtDialView |
Extension-dialing Gather, or skip |
/webhooks/twilio/call/new/ext/call |
AdapterCallExtCallView |
Route to the extension matching the digits |
/webhooks/twilio/call/new/conf |
AdapterCallConfView |
Create the agent conference, or enqueue the caller (bounded by MULTI_AGENTS_MAX) |
/webhooks/twilio/call/dequeue |
AdapterCallDequeueView |
A call leaves the queue; normally redirects into conference setup |
/webhooks/twilio/call/status |
AdapterCallStatusView |
Per-leg status callback |
/webhooks/twilio/call/action/<sid> |
AdapterCallActionsView |
Action callback for Dial, Record and similar verbs |
/webhooks/twilio/call/conf/join/<sid> |
AdapterConfJoinView |
TwiML that puts a leg into the named conference |
/webhooks/twilio/call/conf/in-out/<sid> |
AdapterConfInOutView |
Participant join and leave events |
/webhooks/twilio/call/conf/completed/<sid> |
AdapterConfCompletedView |
Conference completed |
/webhooks/twilio/call/record |
AdapterCallRecordView |
Recording status callback |
/webhooks/twilio/call/voicemail |
AdapterCallVoiceMailView |
A completed voicemail recording |
EndPointsConfig.CALL_NEW_IN (new/in) is defined in
backend/settings/twilio/endpoints.py and exposed as EndPointsURLS.call_new_in, but no
path() registers it — there is no live /webhooks/twilio/call/new/in route.
Twilio SMS webhooks
| Path |
View |
Description |
/webhooks/twilio/sms/receive |
AdapterReceiveMessage |
Inbound SMS; stores it and attaches it to the thread |
/webhooks/twilio/sms/status |
AdapterStatusMessage |
Delivery status callback |
Legacy Twilio routes
| Method |
Path |
View |
Description |
| GET |
/twilio/hooks/token |
TokenView |
Access token with APNs or FCM push credentials by platform |
| POST |
/twilio/hooks/record |
RecordView |
Recording callback; stores it and queues transcription per company settings |
| POST |
/twilio/hooks/voicemail |
VoiceMailView |
Voicemail callback |
Present in backend/calls/urls.py but commented out, so not routed: voice,
dequeue_call, call-actions, call-actions/<sid>, status, conf-join/<sid>,
conf-leave/<sid>, conf-completed/<sid>.
Scheduler triggers
| Method |
Path |
View |
Description |
| POST |
/google/hooks/reminders |
RemindersWebhookView |
Fire notifications for note reminders due in the next minute |
| POST |
/google/hooks/records |
RecordsWebhookView |
record_task() — recording billing and auto-removal |
| POST |
/google/hooks/charges |
ChargesUpdaterView |
update_all_twilio_data() — refresh Twilio calls, recordings, messages and charges |
These three have no authentication
They mutate billing state and are reachable by anyone who knows the URL. See
Known issues.
Notes on this reference
- There is no logs API. The settings UI has a "logs" section, but nothing under
/api/v1 serves it.
voip/messages/urls_api.py is an empty urlpatterns included at path("/", ...), which
mounts it at /api/v1//. It is dead either way.
PATCH on viewset rows comes from the router's standard mapping. NotificationView is a
plain ViewSet defining only list, create and update, so PATCH there returns 405.