Admin
Manage application configurations, including webhook URLs, API keys, and rate limits. Admin endpoints are authenticated separately from app endpoints using a server-level admin API key.
Authentication
Section titled “Authentication”All admin endpoints require the X-Admin-API-Key header. This key is set via the ADMIN_API_KEY environment variable on the gateway server. Validation uses constant-time comparison to prevent timing attacks.
| Header | Description |
|---|---|
X-Admin-API-Key | Server-level admin API key. Required for all admin endpoints. |
Authentication errors
| Status | Condition |
|---|---|
503 | ADMIN_API_KEY environment variable not set. Admin endpoints are disabled. |
401 | Missing X-Admin-API-Key header or invalid key. |
Create or update app
Section titled “Create or update app”POST /admin/apps/{app_id}
Create or update an application’s configuration including webhook URL, API key, and rate limits. If the app already exists, its configuration is overwritten.
Path parameters
| Parameter | Description | Validations |
|---|---|---|
app_id | Application identifier. | Alphanumeric, underscore, hyphen only. Max 64 chars. Regex ^[a-zA-Z0-9_-]+$. |
Request body
| Field | Type | Required | Description | Validations |
|---|---|---|---|---|
webhook_url | string | optional | Webhook delivery URL. Empty string disables webhooks. | Valid HTTP/HTTPS URL. HTTPS required unless ALLOW_HTTP_WEBHOOKS=true. Must not resolve to private/loopback IPs unless ALLOW_LOCALHOST_WEBHOOKS=true. |
api_key | string | optional | API key for this app’s authentication via X-API-Key. | If provided, at least 16 chars, only printable non-space characters. |
rate_limit | integer | optional | Max requests per minute. 0 uses the default (100). | ≥ 0. Max 10000. |
events | string[] | optional | Whitelist of event names to deliver. Omit or send an empty array to receive all events. | Each value must be a canonical event name (see Webhooks overview). |
Response — 200 OK
{ "success": true, "app_id": "my-app", "webhook_url": "https://your-app.com/webhooks", "rate_limit": 200}curl -X POST https://gateway.example.com/admin/apps/my-app \ -H "X-Admin-API-Key: your-admin-key" \ -H "Content-Type: application/json" \ -d '{"webhook_url": "https://your-app.com/webhooks", "api_key": "sk_live_abc123", "rate_limit": 200}'Triggered webhooks — none. This is an administrative endpoint.
Get app configuration
Section titled “Get app configuration”GET /admin/apps/{app_id}
Retrieve an application’s full configuration including webhook URL, API key, and rate limits.
Response — 200 OK
{ "success": true, "app_id": "my-app", "webhook_url": "https://your-app.com/webhooks", "api_key": "sk_live_abc123", "rate_limit": 200}Error — 404 Not Found
{ "success": false, "app_id": "my-app", "error": "App not found"}Triggered webhooks — none. This is a read-only endpoint.
Delete app
Section titled “Delete app”DELETE /admin/apps/{app_id}
Delete an application’s configuration. The app must exist or a 404 is returned. Active sessions belonging to this app are not affected — they will fail authentication on subsequent requests.
Response — 200 OK
{ "success": true, "app_id": "my-app"}Triggered webhooks — none. This is an administrative endpoint.
Admin health check
Section titled “Admin health check”GET /admin/health
Admin-authenticated health check. Returns service status and current UTC timestamp.
{ "status": "ok", "timestamp": "2026-03-21T12:00:00Z"}Recent errors
Section titled “Recent errors”GET /admin/recent-errors
Return the most recent server-side error events for ops debugging. Each entry contains a timestamp, trace correlation, request location, status code, the affected app, and a sanitized error message.
{ "total": 1, "errors": [ { "timestamp": "2026-05-06T12:00:00Z", "trace_id": "abcd-1234", "method": "POST", "path": "/api/v1/dial", "pattern": "/api/v1/dial", "status_code": 503, "app_id": "my-app", "error": "no outbound capacity" } ]}Caller ID management
Section titled “Caller ID management”Manage the allow-list of caller IDs your app may present on outbound dials. Only numbers on the list are accepted as from in POST /api/v1/dial.
Replace allow-list — PUT /admin/apps/{app_id}/cids
Replace the caller-ID allow-list for the app. The request body is a bare JSON array of caller-ID strings (Israeli domestic format), e.g. ["527121102", "747713001"]. Returns 200 with the resulting list.
Today’s behaviour: the handler appends to the existing set (it does not delete entries missing from the request). True replace semantics are tracked as a future improvement; until then, callers needing a hard replace should also call
DELETE /admin/apps/{app_id}/cids/{number}for each removal.
Get allow-list — GET /admin/apps/{app_id}/cids
Return the current allow-list for the app.
Remove a caller ID — DELETE /admin/apps/{app_id}/cids/{number}
Remove a single caller ID from the allow-list. Returns 200 on success, 404 if either app or number is unknown.
Metrics
Section titled “Metrics”GET /metrics
Prometheus exposition-format metrics. Intended for ops scraping and alerting; not part of the consumer API contract. No authentication is enforced at the gateway level — protect this endpoint at the network layer (e.g. Kubernetes NetworkPolicy or ingress allow-list).
Webhook URL security
Section titled “Webhook URL security”When creating or updating an app, the webhook_url is validated against SSRF attacks:
- Must be a valid URL with
httporhttpsscheme. - HTTPS is required in production. Set
ALLOW_HTTP_WEBHOOKS=trueto allow HTTP in development. - Must not resolve to private IP ranges (10/8, 172.16/12, 192.168/16) or loopback addresses.
- Set
ALLOW_LOCALHOST_WEBHOOKS=trueto allow localhost/loopback in development. - An empty string is allowed and disables webhooks for the app.
Error responses
Section titled “Error responses”See the Rate limits guide for cooldown windows and 429 retry semantics.
| Status | Condition |
|---|---|
400 | Invalid app_id format, invalid JSON payload, or invalid webhook_url. |
401 | Missing or invalid X-Admin-API-Key. |
404 | App not found (for GET and DELETE). |
500 | Internal error saving, retrieving, or deleting app config. |
503 | ADMIN_API_KEY not configured, or Redis not available. |