Store Telnyx Credentials
Validates Telnyx API credentials (unless validation is skipped) and securely stores the API key, public key, and optional account SID for the authenticated agency. The public key is required for webhook signature verification.
Endpoint
| Property | Value |
|---|---|
| Function Name | store-telnyx-credentials |
| HTTP Method | POST |
| Authentication | Supabase JWT (Bearer token) |
| Required Role | agency_owner |
Request
Headers
Authorization: Bearer <supabase_jwt_token>
Content-Type: application/json
Body
| Field | Type | Required | Description |
|---|---|---|---|
telnyx_api_key | string | Yes | Telnyx API key (must be at least 20 characters) |
telnyx_public_key | string | Yes | Telnyx public key for webhook signature verification |
telnyx_account_sid | string | No | Telnyx account SID |
skip_validation | boolean | No | If true, skips API key validation against Telnyx. Defaults to false. |
Response
Success (200)
{
"success": true,
"validated": true,
"webhook_url": "https://<supabase-url>/functions/v1/webhook-ingest/<agency_id>/<webhook_secret>",
"next_steps": [
"Configure Telnyx Voice Application",
"Import telephony config to Ultravox"
],
"telephony_ready": false
}
The next_steps array varies depending on whether the Ultravox API key has already been configured:
- Ultravox key present:
["Configure Telnyx Voice Application", "Import telephony config to Ultravox"] - Ultravox key absent:
["Configure Ultravox API key first", "Then provision Telnyx resources"]
The telephony_ready field is false until full provisioning is complete.
Error Responses
| Status | Condition |
|---|---|
| 400 | telnyx_api_key is missing or not a string |
| 400 | telnyx_public_key is missing or not a string |
| 400 | API key format is invalid (shorter than 20 characters) |
| 400 | API key validation failed against Telnyx (includes hint to use skip_validation: true) |
| 401 | Missing or invalid authorization header |
| 403 | User is not an agency user or is not an agency_owner |
| 404 | Agency not found when storing credentials |
| 405 | HTTP method is not POST |
| 500 | Failed to store credentials in the database |
Behavior
- Authenticates the user via Supabase JWT and verifies they have the
agency_ownerrole - Validates that
telnyx_api_keyandtelnyx_public_keyare present and are strings - Validates the API key format (minimum 20 characters)
- Unless
skip_validationistrue, validates the API key againstGET https://api.telnyx.com/v2/available_phone_numbers?filter[country_code]=US&filter[limit]=1- HTTP 200 or 429 (rate limited) both count as valid
- Returns an error with a hint about
skip_validationif validation fails
- Stores the credentials via the
store_telnyx_credentialsRPC function, which handles encryption internally - If validation passed, updates the
agenciestable withtelnyx_api_key_validated_attimestamp - Retrieves the agency's
webhook_secretand checks whether the Ultravox API key is already configured - Returns a webhook URL and context-aware next steps
Database Tables Read/Written
| Table | Operation | Purpose |
|---|---|---|
users | Read | Verify user role and agency membership |
agencies | Read | Retrieve webhook secret and check Ultravox key status |
agencies | Write | Update telnyx_api_key_validated_at timestamp |
RPC Functions Called
| Function | Purpose |
|---|---|
store_telnyx_credentials | Encrypt and store the Telnyx API key, public key, and account SID |
External APIs Called
| API | Method | Endpoint | Purpose |
|---|---|---|---|
| Telnyx | GET | /v2/available_phone_numbers?filter[country_code]=US&filter[limit]=1 | Validate the API key (unless skip_validation is set) |
Related Functions
- Validate Telnyx Key -- Validate a Telnyx key without storing it
- Save Ultravox Integration -- Store the Ultravox API key
- Provision Telephony -- Full telephony provisioning (requires both keys stored)
- Import Telnyx to Ultravox -- Import stored Telnyx credentials into Ultravox