Voice agents spend money on every minute, and public widgets and phone numbers can be reached by anyone. This page lists the controls that limit what an attacker or a bug can do, from the API edge to the phone line.
API access#
| Control | Default | Where |
|---|---|---|
| Per-IP rate limit, before authentication | 3,000 requests per minute (RATE_LIMIT_PER_IP) |
Server |
| Per-key rate limit | 600 per minute (RATE_LIMIT_PER_KEY), or the key's own limit |
API keys |
| Key scopes | Full access when no scopes are set | API keys |
| Key IP allowlist | Any IP | API keys |
| Sign-in rate limits | 30 per IP and 10 per email per minute on password sign-in | Sign-in and 2FA |
| Close public sign-up | Open | DISABLE_SIGNUP=1 |
Rate limits use a sliding one-minute window, shared across API instances through Redis when REDIS_URL is set. Over the limit, the API returns 429 with retry-after and x-ratelimit-* headers.
If a key leaks#
- Create a new key with the same access and deploy it.
- Delete the leaked key on Settings, API Keys. Requests with it fail immediately.
- If it was the webhook key, set the new key as the webhook key and update your receivers.
- Check the audit log for actions with the leaked key's name as actor, and Call History for calls you did not expect.
Give each server its own key with only the scopes it needs, so a leak is contained.
Public widgets and browser calls#
Public keys are designed to sit in page source, so they carry their own protections. See Public keys.
| Control | Effect |
|---|---|
| Allowed domains | Only requests with an Origin on the list are accepted |
| Route allowlist | A public key can only start web calls and chats |
| Fixed agent | The key's voice agent and chat agents are the only ones it can use |
| Per-IP rate | 30 requests per minute per IP per key (PUBLIC_KEY_IP_RATE_PER_MINUTE) |
| Requests per minute | Optional cap for the whole key |
| reCAPTCHA with Minimum score | Requests scoring below the threshold are refused Needs keys |
| Blocked countries | Refuses requests from listed countries, using the country header from your CDN |
| Credit and budget | Chats and calls stop when credit or the monthly budget runs out |
Web calls whose browser never joins end after 5 minutes with error_user_not_joined, so unused tokens do not hold concurrency.
Spend controls#
| Control | Effect | Where |
|---|---|---|
| Prepaid credit | New calls and chats are refused with 402 at zero balance |
Billing |
| Monthly budget | budget_alert webhook at 80%; at 100%, budget_reached and new calls and chats are refused |
Billing |
| Concurrency limit | Caps simultaneous calls | Limits and concurrency |
| Max call duration | Each call ends at max_call_duration_ms (default 1 hour) |
Agent settings |
| Silence timeout | Calls with no speech end at end_call_after_silence_ms |
Agent settings |
| Alerting | Rules on call_count, total_call_cost, concurrency_used, api_error_count and other metrics fire a signed alert_triggered webhook |
Alerting |
Set a monthly budget even with auto-recharge on. Auto-recharge keeps buying credit; the budget is what stops runaway spend.
Telephony fraud#
| Control | Effect |
|---|---|
allowed_outbound_country_list on each number |
Outbound calls to other countries are refused with 400 |
allowed_inbound_country_list on each number |
Inbound callers from other countries are rejected |
| CPS per number | Outbound dials are paced (default 4 per second on Telnyx numbers, 10 on your own trunk) |
| Reserved inbound slots | Outbound bursts cannot take every line |
| Business verification | When the deployment requires it, numbers, outbound calls and SMS need an approved business profile (Business verification) |
| Do-not-call | honor_internal_dnc on outbound and batch calls skips contacts marked do-not-call. With enable_dnc_detection, a caller who asks not to be called is marked automatically |
| Inbound trunk restrictions | allowed_inbound_addresses or inbound credentials on imported trunks limit who can send calls to your agent |
Restrict outbound countries to the ones you call. International destinations are where toll fraud costs the most.
Abusive callers#
| Control | Effect |
|---|---|
| Guardrail input topics | Detect harassment, jailbreak attempts and other topics in what the caller says |
scam input topic |
Ends the call with scam_detected when a caller attempts a scam |
scope_boundaries in the Agent Handbook |
The agent declines unrelated requests and does not reveal its instructions |
| Custom function signatures | Your endpoints can verify x-tried-signature so only Tried can call them |
Guardrails cost $0.01 per minute when any topic is configured.
Outbound requests to your systems#
Requests Tried makes to URLs you configure (webhooks, custom functions, workflow steps, knowledge base crawling) refuse private and reserved network addresses, checked on the address actually dialled. A misconfigured or malicious URL cannot reach internal services in the Tried deployment. Verify webhook and function signatures on your side and reject requests older than 5 minutes; see Webhooks.