Skip to main content
A DialNexa deployment that is misconfigured or has leaked credentials can become a tool for spam calls, toll fraud, or unauthorized data access. This page covers the specific steps you should take to lock down your deployment before it goes to production.

API Key Security

Your API key is the master credential for your DialNexa account. Anyone who has it can initiate calls, read transcripts, modify agents, and charge your wallet.
Never embed an API key in client-side code (browser JavaScript, mobile app bundles). API keys in client-side code are easily extracted and will be abused.
Best practices:
1

Use environment variables

Store API keys in environment variables or a secrets manager (AWS Secrets Manager, HashiCorp Vault, GCP Secret Manager). Never hardcode keys in source files.
2

Create per-service keys

Create a separate API key for each service or application that calls DialNexa. This way, if one key is compromised, you can revoke it without affecting other services.
3

Rotate keys regularly

Rotate API keys every 90 days as a baseline practice. After any team member departure or suspected exposure, rotate immediately.
4

Monitor key usage

Review API key usage logs in Settings → API Keys. Unexpected usage patterns (new IP addresses, unusual call volumes) indicate a potentially compromised key.
5

Revoke unused keys

If a key is no longer in use, revoke it. Every active key is an attack surface.
See API Keys for the full key management guide.

Webhook Validation

If your agents call webhook URLs (for custom tools, post-call events, etc.), those endpoints receive real call data. Securing them is essential. Validate webhook signatures: DialNexa signs all webhook requests with an HMAC-SHA256 signature using a shared secret you configure. Verify this signature on every incoming request:
import hmac
import hashlib

def verify_webhook(payload: bytes, signature: str, secret: str) -> bool:
    expected = hmac.new(
        secret.encode(),
        payload,
        hashlib.sha256
    ).hexdigest()
    return hmac.compare_digest(expected, signature)
The signature is sent in the X-DialNexa-Signature header. Reject any request where the signature does not match. Additional webhook hardening:
  • Allowlist DialNexa’s IP ranges: Restrict your webhook endpoint to only accept connections from DialNexa’s published IP ranges. Contact support for the current list.
  • Use HTTPS only: Never configure a webhook URL using plain HTTP. All webhook URLs must use TLS.
  • Implement idempotency: Webhooks may be delivered more than once in edge cases. Use the call_id field as an idempotency key to avoid processing the same event twice.
  • Set a short timeout: Respond to webhook requests within 5 seconds. Slow responses can cause the agent to stall on the call.

Restricting Outbound Numbers and Destinations

Unconstrained outbound calling is a toll fraud risk. Lock down who your agents can call: Outbound number allowlisting: In your agent or campaign configuration, specify an explicit list of allowed destination number patterns. Any call attempt to a number outside this list is blocked before dialing. Restrict international calling: By default, international calling is limited. Do not expand international calling access unless your use case genuinely requires it. High-premium international destinations (certain African, Caribbean, and Pacific country codes) are blocked by default due to toll fraud risk. Caller ID restriction: Pin your outbound calls to specific purchased numbers. Do not configure dynamic caller ID unless required - dynamic caller ID can be exploited to spoof numbers.

Rate Limiting Your API Usage

Apply rate limits in your own application layer before requests reach DialNexa. This contains the damage from credential compromise or runaway batch jobs:
# Example: token bucket rate limiter in your application

from datetime import datetime, timedelta

class CallRateLimiter:
    def __init__(self, max_calls_per_minute: int):
        self.max_calls = max_calls_per_minute
        self.calls = []
    
    def can_call(self) -> bool:
        now = datetime.utcnow()
        # Remove calls older than 1 minute
        self.calls = [c for c in self.calls if now - c < timedelta(minutes=1)]
        if len(self.calls) < self.max_calls:
            self.calls.append(now)
            return True
        return False
Recommended application-level limits:
ActionSuggested limit
Outbound calls30/minute per application instance
Batch campaign launch1 per hour
Agent config changes10 per minute
API key creation5 per day

Concurrency Caps

Set a conservative concurrency cap on your account to limit blast radius if a runaway process starts making too many calls:
  1. Go to Settings → Plan → Concurrency
  2. Set an active concurrency limit lower than your plan’s maximum if your normal operations don’t need the full limit
  3. For batch campaigns, set a campaign-level concurrency limit in the campaign settings
If an unexpected spike in concurrency occurs, new calls are queued or rejected rather than causing an uncontrolled cost event.

Securing Agent Webhooks from Prompt Injection

Callers can attempt to extract data from your tool endpoints by manipulating the agent into making unexpected tool calls. Defend at the tool endpoint level:
  • Validate all arguments: Never trust tool call arguments at face value. Validate types, formats, and value ranges before executing any database queries or external API calls.
  • Use parameterized queries: If a tool executes database queries, always use parameterized queries. Never construct SQL or NoSQL queries from raw LLM-generated strings.
  • Scope permissions tightly: The credentials used by your tool endpoints should have only the minimum permissions needed. A booking tool should only be able to write to the appointments table, not query user records.
  • Log all tool invocations: Log every tool call with its arguments and the call ID. This creates an audit trail for investigating abuse.

Environment Isolation

Keep development, staging, and production environments completely separate:
  • Use separate DialNexa accounts or workspaces for each environment
  • Use separate API keys per environment - never use a production key in development
  • Use separate phone numbers per environment - test calls should never go out on production numbers
  • Use separate webhook endpoints per environment

Monitoring for Abuse

Set up alerting to catch abuse early:
  • Daily cost alert: Configure a daily spend alert in Settings → Billing → Alerts. If your daily spend exceeds 2x your normal daily average, get notified immediately.
  • Failed call ratio alert: A spike in failed outbound calls often indicates a bad number list or misconfigured campaign. Monitor the failed/succeeded ratio in dashboard metrics.
  • API error rate: A high rate of API 4xx errors (especially 401 Unauthorized) may indicate someone probing your endpoints with invalid credentials.

Checklist Before Going to Production

ItemStatus
API keys stored in environment variables, not source code
Webhook URLs use HTTPS
Webhook signatures are validated on all endpoints
International calling disabled unless needed
Outbound caller ID pinned to specific numbers
Application-level rate limiting implemented
Daily spend alert configured
Development and production environments use separate keys
Tool endpoints use parameterized queries
Concurrency cap set appropriately