Skip to content

Telephony ​

Connect your Plivo, Twilio, Vonage, or Telnyx account to use for outbound and inbound PSTN legs. Rymi encrypts provider credentials before storage.

Self-serve BYOC carrier costs are not bundled into Rymi's platform minute price. Your carrier bills PSTN minutes, number rental, taxes, and add-ons directly. Rymi bills at the agent's per-minute rate: its managed SKU price, or for a custom agent the stack's component cost plus the flat $0.02/min platform fee. Enterprise plans can bundle telecom under a custom agreement.

List Available Providers ​

GET/v1/telephony/providers

Returns the full carrier catalog with the credential field shapes the dashboard uses to render dynamic connect forms. No auth required, since field metadata is not sensitive.

Response 200 ​

json
{
  "providers": [
    {
      "id": "twilio",
      "displayName": "Twilio",
      "credentialFields": [
        { "key": "auth_id", "label": "Account SID", "type": "text", "required": true },
        { "key": "auth_token", "label": "Auth Token", "type": "secret", "required": true }
      ]
    }
  ]
}

Validate Without Saving ​

POST/v1/telephony/validate

Pings the carrier's API and returns whether the credentials authenticate, without storing them. Rate-limited to 3 attempts per 5 minutes per tenant.

Request Body ​

Same shape as Connect Provider.

Response 200 ​

json
{ "valid": true, "accountName": "Acme Twilio" }
json
{ "valid": false, "error": "Invalid credentials: could not authenticate with the provider" }

Errors ​

StatusMeaning
400Unsupported provider
401Missing Rymi auth context
429Too many validation attempts; wait and retry

Connect Provider ​

POST/v1/telephony/connect

Only one active telephony carrier is used per tenant at a time. Connecting a new provider deactivates the previous active carrier.

Request Body ​

FieldTypeRequiredDefaultDescription
providerstringYes-plivo, twilio, vonage, or telnyx
auth_idstringYes (Plivo/Twilio/Telnyx)-Plivo Auth ID, Twilio Account SID, or Telnyx API Key
auth_tokenstringYes (Plivo/Twilio)-Provider auth token. For Telnyx this is the Connection ID and is optional, Rymi auto-creates a TeXML app when omitted
api_keystringYes (Vonage)-Vonage API key
api_secretstringYes (Vonage)-Vonage API secret
application_idstringYes (Vonage)-Vonage Voice Application ID
private_keystringYes (Vonage)-Vonage Voice private key (PEM)
auth_secretstringNo-Optional webhook signing secret (Telnyx Ed25519 verification)
signature_secretstringNo-Optional Vonage signature secret for webhook verification (required to receive inbound calls)

Example: Twilio ​

bash
curl -X POST https://api.rymi.live/v1/telephony/connect \
  -H "Authorization: Bearer YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "provider": "twilio",
    "auth_id": "ACxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx",
    "auth_token": "your_twilio_auth_token"
  }'
ts
const result = await rymi.telephony.connect({
  provider: "twilio",
  auth_id: "ACxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx",
  auth_token: "your_twilio_auth_token",
});
python
result = rymi.telephony.connect(
    provider="twilio",
    auth_id="ACxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx",
    auth_token="your_twilio_auth_token",
)

Example: Plivo ​

bash
curl -X POST https://api.rymi.live/v1/telephony/connect \
  -H "Authorization: Bearer YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "provider": "plivo",
    "auth_id": "your_plivo_auth_id",
    "auth_token": "your_plivo_auth_token"
  }'
ts
const result = await rymi.telephony.connect({
  provider: "plivo",
  auth_id: "your_plivo_auth_id",
  auth_token: "your_plivo_auth_token",
});
python
result = rymi.telephony.connect(
    provider="plivo",
    auth_id="your_plivo_auth_id",
    auth_token="your_plivo_auth_token",
)

Example: Vonage ​

bash
curl -X POST https://api.rymi.live/v1/telephony/connect \
  -H "Authorization: Bearer YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "provider": "vonage",
    "api_key": "your_vonage_api_key",
    "api_secret": "your_vonage_api_secret",
    "application_id": "your_vonage_voice_application_id",
    "private_key": "-----BEGIN PRIVATE KEY-----\n...\n-----END PRIVATE KEY-----",
    "signature_secret": "your_vonage_signature_secret"
  }'
ts
const result = await rymi.telephony.connect({
  provider: "vonage",
  api_key: "your_vonage_api_key",
  api_secret: "your_vonage_api_secret",
  application_id: "your_vonage_voice_application_id",
  private_key: "-----BEGIN PRIVATE KEY-----\n...\n-----END PRIVATE KEY-----",
  signature_secret: "your_vonage_signature_secret",
});
python
result = rymi.telephony.connect(
    provider="vonage",
    api_key="your_vonage_api_key",
    api_secret="your_vonage_api_secret",
    application_id="your_vonage_voice_application_id",
    private_key="-----BEGIN PRIVATE KEY-----\n...\n-----END PRIVATE KEY-----",
    signature_secret="your_vonage_signature_secret",
)

Example: Telnyx ​

bash
curl -X POST https://api.rymi.live/v1/telephony/connect \
  -H "Authorization: Bearer YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "provider": "telnyx",
    "auth_id": "your_telnyx_api_key",
    "auth_token": "your_telnyx_connection_id",
    "auth_secret": "your_telnyx_webhook_signing_secret"
  }'

Response 200 ​

json
{
  "status": "connected",
  "provider": "twilio",
  "account_name": "Acme Twilio",
  "message": "twilio account connected successfully"
}

Errors ​

StatusMeaning
400Missing or unsupported provider, missing provider-specific credentials, or invalid carrier credentials (validation failed)
401Missing Rymi auth context
429Too many credential connection attempts in a short window
500Credential storage failed

Status ​

GET/v1/telephony/status

Returns the current telephony connection state for the authenticated tenant. No query parameters.

Example Request ​

bash
curl https://api.rymi.live/v1/telephony/status \
  -H "Authorization: Bearer YOUR_API_KEY"
ts
const status = await rymi.telephony.status();
python
status = rymi.telephony.status()

Response 200 ​

json
{
  "connected": true,
  "provider": "twilio",
  "account_name": "Acme Twilio",
  "test_pool": { "enabled": true, "countries": ["US", "IN"] }
}

test_pool is always present, on both the connected and disconnected branches, and reports the shared test-number pool for the tenant.

FieldTypeDescription
connectedbooleanWhether a telephony provider is currently connected
providerstring or nullActive provider: plivo, twilio, vonage, or telnyx
account_namestring or nullDisplay name from the provider account
test_poolobjectShared test-number pool status: { enabled: boolean, countries: string[] }

Errors ​

StatusMeaning
401Missing or invalid API key
500Provider status lookup failed

Provider Numbers ​

GET/v1/telephony/numbers

Returns carrier-owned numbers synced into Rymi for the connected provider. Read-only: it does not search, buy, release, assign, or unassign carrier numbers.

Example Request ​

bash
curl https://api.rymi.live/v1/telephony/numbers \
  -H "Authorization: Bearer YOUR_API_KEY"
ts
const { numbers } = await rymi.telephony.numbers();
python
result = rymi.telephony.numbers()

Response 200 ​

json
{
  "numbers": [
    {
      "id": "num_123",
      "provider": "twilio",
      "phone_number": "+15551234567",
      "number_type": "local",
      "number_status": "active",
      "assigned_app_id": null,
      "backend_agent_id": "550e8400-e29b-41d4-a716-446655440000",
      "synced_at": "2026-04-01T10:00:00Z",
      "agents": { "id": "550e8400-e29b-41d4-a716-446655440000", "name": "Support Bot" }
    }
  ]
}
FieldTypeDescription
idstringInternal number record ID
providerstringCarrier provider name
phone_numberstringPhone number in E.164 format
number_typestring or nullCarrier-reported number type (e.g. local, tollfree)
number_statusstringactive or inactive
assigned_app_idstring or nullCarrier application/connection the number is bound to, if any
backend_agent_iduuid or nullAgent attached to this number, if any
synced_atstring or nullTimestamp of the last carrier sync for this number
agentsobject or nullAttached agent { id, name }, joined from backend_agent_id

Errors ​

StatusMeaning
401Missing or invalid API key
500Provider number lookup failed

Disconnect ​

POST/v1/telephony/disconnect

Deactivates the current telephony provider. No request body required.

Example Request ​

bash
curl -X POST https://api.rymi.live/v1/telephony/disconnect \
  -H "Authorization: Bearer YOUR_API_KEY"
ts
const result = await rymi.telephony.disconnect();
python
result = rymi.telephony.disconnect()

Response 200 ​

json
{
  "status": "disconnected",
  "message": "Telephony disconnected."
}

Errors ​

StatusMeaning
401Missing or invalid API key
500Disconnect operation failed

Sync Numbers from Carrier ​

POST/v1/telephony/sync-numbers

Pulls phone-number inventory from the connected carrier and upserts it into provider_numbers. Numbers no longer present in the carrier inventory are removed locally. Rate-limited to one sync per 2 minutes per tenant.

Example Request ​

bash
curl -X POST https://api.rymi.live/v1/telephony/sync-numbers \
  -H "Authorization: Bearer YOUR_API_KEY"

Response 200 ​

json
{
  "numbers": [
    {
      "phone_number": "+15551234567",
      "number_type": "local",
      "provider": "twilio"
    }
  ],
  "synced_at": "2026-04-01T10:00:00Z"
}

Errors ​

StatusMeaning
400No active telephony provider connected, or provider doesn't support sync
429Sync rate-limited; wait 2 minutes between syncs
500Carrier API call failed

Number Management ​

Rymi does not search or purchase carrier numbers. Provision numbers in your carrier account, sync them via POST /v1/telephony/sync-numbers, then use the Numbers API to attach them to agents.