Rotating a SIP credential without a drain window drops every in-flight call the moment the old credential is revoked. The safe approach is a two-phase pattern: create the new credential, provision it on your SIP client, wait for all active calls to complete, then revoke the old one. This post explains exactly how to implement that pattern using the Sautikit API.
A Sautikit SIP credential is a username/password pair bound to a specific phone number in your workspace. When your SIP client (a softphone, a PBX, or a media server) registers with Sautikit's SIP infrastructure, it authenticates using this credential. All calls placed or received through that number are associated with the credential that registered for it.
Credentials are scoped to a number, not to a workspace. This means you can have multiple numbers in one workspace with independent credential rotation schedules. Rotating the credential on +254712345678 has no effect on calls active on +254711000000.
You can retrieve the current SIP credentials for a number:
The realm is your account UUID. It is stable across credential rotations: the realm identifies the account, not the credential. Hardcoding the realm in your SIP client configuration is an anti-pattern: it couples your client configuration to the account's internal identifier. Extract it from the WWW-Authenticate header on first registration instead:
SIP uses Digest authentication (RFC 3261 §22.4). The authentication lifecycle works like this:
Your SIP client sends a REGISTER or INVITE request.
Sautikit responds with 401 Unauthorized carrying a WWW-Authenticate header containing a nonce.
Your client sends a second request with a Authorization: Digest header containing the computed response.
Sautikit validates the credential and returns 200 OK.
The credential is authenticated at the session establishment step. Once a call is active (post-200 OK for the INVITE), the credential is not re-checked on every in-flight packet. The call's media session uses the already-authenticated context.
What happens on revocation is this: the next REGISTER or re-INVITE from your SIP client will be rejected with 403 Forbidden. For active calls, this matters because many SIP clients send periodic re-INVITE packets for session keepalive or quality negotiation. If the credential is gone when that re-INVITE arrives, Sautikit sends 403 and the client tears down the call.
To see this in a SIP trace, capture with:
tcpdump -i any -w sip.pcap port 5060
Then open in Wireshark and filter sip. You will see the re-INVITE and immediately after, the 403 Forbidden response if the credential was revoked mid-call.
Update your SIP client configuration (or your secrets manager reference) to use the new username and password. Trigger a REGISTER and confirm authentication succeeds before proceeding:
# Using sipsak to verify registrationsipsak -s sip:ts_NEW01J2K3M4N5P6@sip.sautikit.com \ --password "rnd_9X8w7v6u5t4s3r2q"# Should return: SIP/2.0 200 OK
Wait until the response shows "total": 0. The drain window must be at least equal to your p99 call duration. For Kenyan fintech voice OTP flows, this is typically 45–90 seconds. For conference calls, it can be 90 minutes. Measure your p99 before setting the window:
# Get the 99th percentile call duration for the past 7 dayscurl -s "https://api.sautikit.com/v1/calls?number_id=num_abc123&created_after=2026-06-27T00:00:00Z&limit=1000" \ -H "Authorization: Bearer $SAUTIKIT_API_KEY" \ | jq '[.calls[].duration_seconds] | sort | .[length * 0.99 | floor]'
In your staging environment, place a long-duration call (using Record with no timeout as the voice action, so the call stays active), then run the rotation script. Verify that:
The new credential registers successfully while the old credential is still active.
The drain loop detects the in-progress call and waits.
The call completes naturally (or you manually end it via the dashboard).
The drain loop sees zero active calls and proceeds to revocation.
During the drain, watch the active call count metric in the Sautikit dashboard alongside your SIP client's registration status. What you want to see:
New credential: REGISTERED
Old credential: REGISTERED (still authenticating, sustaining in-flight calls)
Active calls on the number: decreasing toward zero
The moment you see active_calls = 0 and both credentials are REGISTERED, it is safe to revoke. If the new credential shows REGISTRATION_FAILED at any point, halt the rotation and debug before proceeding; revoking the old credential with the new one broken would cut all call capacity.