Skip to main content

STIR/SHAKEN Hosted Certificate

The user may choose to sign their own calls using their own Stir Shaken certificate via the Telnyx hosted signing solution.

Workflow

Upload the Stir Shaken Certificate

Request

POST https://api.telnyx.com/v2/stir_shaken_certs
Authorization: Bearer {REPLACE_ME}
Content-Type: application/json

{
"x5u_url": "https://certificates.transnexus.com/xxx/xxxx.pem",
"private_key": "-----BEGIN EC PRIVATE KEY-----\nMIGHAgE...\n-----END EC PRIVATE KEY-----"
}

Parameter

What you sendWhy we need itWhere it is used
x5u_url (HTTPS URL string)A public URL that returns the X.509 certificate containing the public key, usually hosted by your STI-CA (e.g., TransNexus) or on your own server.PASSporT headers include this URL so downstream STIR/SHAKEN verifiers can fetch the certificate, check its TNAuthList, and verify the signature. Placed in the PASSporT header ("x5u": "<your-url>") of every signed call.
private_key (PEM-formatted EC-P256 or RSA-2048 key)The unencrypted private key that belongs to your STIR/SHAKEN certificate.We use this key to cryptographically sign every PASSporT we attach to your outbound calls. Without it, we cannot generate a valid Identity header. Only our secure signing service ever sees or stores it (encrypted at rest).
warning

\n must be present in the private key, e.g. -----BEGIN EC PRIVATE KEY-----\n[INSERT_PRIVATE_KEY_STRING_HERE]\n-----END EC PRIVATE KEY-----

Response

{
"data": {
"id": "57167e5a-9389-49e9-8530-a7f0702ba325",
"user_id": "1a8752a5-63e8-4c16-9655-d2c515f42aed",
"org_id": "1a8752a5-63e8-4c16-9655-d2c515f42aed",
"x5u_url": "https://certificates.transnexus.com/xxx/xxxx.pem",
"created_at": "2025-06-09T20:07:35.006250Z",
"updated_at": null
}
}

Associate the certificate to an outbound voice profile

PATCH https://api.telnyx.com/v2/outbound_voice_profiles/:id
Authorization: Bearer {REPLACE_ME}
Content-Type: application/json

{
...
"stir_shaken_cert_id": "e25c6e2e-4f77-42fb-b8d3-e5d8d0c7d019"
...
}

Cost

$100 per certificate per month.

Signing Validation

  1. Set up an IP connection with a valid public IP. This IP doesn't need to work. Enable "Receive SHAKEN/STIR Identity SIP header"

Enable S/S Header

  1. Assign a US phone number to this connection.
  2. Call this US phone number from a connection with outbound voice profile that has the Stir Shaken certificate. Make sure the CLI is a US phone number on your account.
  3. The call is expected to fail with "Temporarily Unavailable (code: 480)".
  4. Go to https://portal.telnyx.com/#/debugging/sip-call-flow-tool and find the inbound call legs.
  5. In the SIP flow, examine the INVITE message. The Identity header is expected to be present.

SIP INVITE

  1. The Identity header is of this expected format:
Identity:[LONG_STRING].[LONG_STRING].[LONG_STRING];info=<https://[YOUR_CERT_URL]>;alg=ES256;ppt="shaken"
  1. Use https://jwt.io/, paste in [LONG_STRING].[LONG_STRING].[LONG_STRING] and decode it.

JWT Decoded

  1. Take the first part of the public certificate.

Public Cert

  1. Paste it into "JWT Signature Verification". "Valid public key" should show.

Valid Key