VoiceGateway // DOCS

HTTP API Reference

The VoiceGateway HTTP API runs via `voicegw serve` (default port 8080). It provides read-only observability endpoints and full CRUD for managing providers, models, and projects.

HTTP API Reference

The VoiceGateway HTTP API runs via voicegw serve (default port 8080). It provides read-only observability endpoints and full CRUD for managing providers, models, and projects.

Start the server:

Shell
voicegw serve --port 8080

Health

GET /health

Returns the health status and uptime of the gateway.

Response:

JSON
{
  "status": "ok",
  "uptime_seconds": 3621.4,
  "version": "0.1.0"
}

Example:

Shell
curl http://localhost:8080/health

Status and Models

GET /v1/status

Returns the configuration status of all providers and high-level counts.

Response:

JSON
{
  "providers": {
    "deepgram": { "configured": true, "type": "cloud" },
    "openai": { "configured": true, "type": "cloud" },
    "whisper": { "configured": true, "type": "local" }
  },
  "model_count": 8,
  "project_count": 3
}

Example:

Shell
curl http://localhost:8080/v1/status

GET /v1/models

List all registered models across all modalities.

Query parameters:

ParameterTypeDefaultDescription
projectstringnullIf set, filters to models used by this project's default stack.

Response:

JSON
{
  "models": {
    "deepgram/nova-3": {
      "modality": "stt",
      "provider": "deepgram",
      "model": "nova-3"
    },
    "openai/gpt-4o-mini": {
      "modality": "llm",
      "provider": "openai",
      "model": "gpt-4o-mini"
    }
  },
  "project": null
}

Example:

Shell
curl http://localhost:8080/v1/models
curl "http://localhost:8080/v1/models?project=tonys-pizza"

Costs and Latency

GET /v1/costs

Return cost summary for a period, optionally filtered by project.

Query parameters:

ParameterTypeDefaultDescription
periodstring"today"One of: today, week, month, all.
projectstringnullFilter by project ID.

Response:

JSON
{
  "period": "today",
  "project": null,
  "total": 1.2345,
  "by_provider": {
    "deepgram": { "cost": 0.5123, "requests": 42 },
    "openai": { "cost": 0.7222, "requests": 18 }
  },
  "by_model": {
    "deepgram/nova-3": { "cost": 0.5123, "requests": 42 }
  },
  "by_project": {
    "tonys-pizza": { "cost": 0.8100, "requests": 35 }
  }
}

Example:

Shell
curl "http://localhost:8080/v1/costs?period=week"
curl "http://localhost:8080/v1/costs?period=month&project=tonys-pizza"

GET /v1/latency

Return latency statistics for the given period.

Query parameters:

ParameterTypeDefaultDescription
periodstring"today"One of: today, week, month.
projectstringnullFilter by project ID.

Response:

Returns per-model latency statistics including average TTFB and total latency.

Example:

Shell
curl "http://localhost:8080/v1/latency?period=today"
curl "http://localhost:8080/v1/latency?period=week&project=my-app"

Projects

GET /v1/projects

List all configured projects with today's stats.

Response:

JSON
{
  "projects": [
    {
      "id": "tonys-pizza",
      "name": "Tony's Pizza",
      "description": "Pizza ordering voice agent",
      "daily_budget": 10.0,
      "default_stack": "premium",
      "tags": ["production"],
      "accent": "#e74c3c"
    }
  ],
  "stats": {
    "tonys-pizza": {
      "cost_today": 2.45,
      "requests_today": 120
    }
  }
}

Example:

Shell
curl http://localhost:8080/v1/projects

GET /v1/projects/{project_id}

Return full details for a single project including today's spend and budget status.

Response:

JSON
{
  "id": "tonys-pizza",
  "name": "Tony's Pizza",
  "description": "Pizza ordering voice agent",
  "daily_budget": 10.0,
  "budget_action": "warn",
  "default_stack": "premium",
  "tags": ["production"],
  "accent": "#e74c3c",
  "today_spend": 2.45,
  "budget_status": "ok",
  "today": { "cost_today": 2.45, "requests_today": 120 },
  "costs_today": { "total": 2.45, "by_provider": {}, "by_model": {} }
}

Example:

Shell
curl http://localhost:8080/v1/projects/tonys-pizza

POST /v1/projects

Create a new project (stored in SQLite).

Request body:

JSON
{
  "project_id": "new-app",
  "name": "New App",
  "description": "A new voice agent",
  "daily_budget": 5.0,
  "budget_action": "warn",
  "default_stack": "premium",
  "tags": ["staging"]
}

Response:

JSON
{
  "project_id": "new-app",
  "source": "db",
  "created": true
}

Example:

Shell
curl -X POST http://localhost:8080/v1/projects \
  -H "Content-Type: application/json" \
  -d '{"project_id":"new-app","name":"New App","daily_budget":5.0}'

PATCH /v1/projects/{project_id}

Update a managed project. Only projects created via the API (source "db") can be updated.

Request body: Any subset of fields from the POST body.

Response:

JSON
{
  "project_id": "new-app",
  "updated": true
}

Example:

Shell
curl -X PATCH http://localhost:8080/v1/projects/new-app \
  -H "Content-Type: application/json" \
  -d '{"daily_budget":10.0}'

DELETE /v1/projects/{project_id}

Delete a managed project. Requires ?confirm=true to actually delete. Without the parameter, returns a preview of what would be deleted.

Query parameters:

ParameterTypeDefaultDescription
confirmbooleanfalseMust be true to perform the deletion.

Response (preview):

JSON
{
  "would_delete": { "project_id": "new-app" }
}

Response (confirmed):

JSON
{
  "deleted": "new-app"
}

Example:

Shell
# Preview
curl -X DELETE "http://localhost:8080/v1/projects/new-app"
# Confirm
curl -X DELETE "http://localhost:8080/v1/projects/new-app?confirm=true"

::: warning YAML-defined projects cannot be deleted via the API. A 403 is returned. :::


Providers

GET /v1/providers

List all providers (YAML-defined and managed).

Response:

JSON
{
  "providers": [
    {
      "provider_id": "deepgram",
      "source": "yaml",
      "api_key_masked": "sk-a...1f2b",
      "base_url": null
    }
  ]
}

Example:

Shell
curl http://localhost:8080/v1/providers

POST /v1/providers

Add a new provider (stored in SQLite). The provider type must be one of the supported types.

Request body:

JSON
{
  "provider_id": "deepgram-staging",
  "provider_type": "deepgram",
  "api_key": "sk-your-api-key",
  "base_url": null
}

Response:

JSON
{
  "provider_id": "deepgram-staging",
  "source": "db",
  "api_key_masked": "sk-y...key"
}

Example:

Shell
curl -X POST http://localhost:8080/v1/providers \
  -H "Content-Type: application/json" \
  -d '{"provider_id":"deepgram-staging","provider_type":"deepgram","api_key":"sk-your-key"}'

PATCH /v1/providers/{provider_id}

Update a managed provider's API key, base URL, or type.

Example:

Shell
curl -X PATCH http://localhost:8080/v1/providers/deepgram-staging \
  -H "Content-Type: application/json" \
  -d '{"api_key":"sk-new-key"}'

DELETE /v1/providers/{provider_id}

Delete a managed provider. Requires ?confirm=true.

Query parameters:

ParameterTypeDefaultDescription
confirmbooleanfalseMust be true to perform the deletion.

Example:

Shell
# Preview
curl -X DELETE "http://localhost:8080/v1/providers/deepgram-staging"
# Confirm
curl -X DELETE "http://localhost:8080/v1/providers/deepgram-staging?confirm=true"

POST /v1/providers/{provider_id}/test

Test connectivity to a provider by running its health check.

Response:

JSON
{
  "status": "ok",
  "latency_ms": 142
}

Example:

Shell
curl -X POST http://localhost:8080/v1/providers/deepgram/test

Models

POST /v1/models

Register a new model (stored in SQLite).

Request body:

JSON
{
  "modality": "stt",
  "provider_id": "deepgram",
  "model_name": "nova-3",
  "display_name": "Deepgram Nova 3",
  "default_language": "en"
}

Response:

JSON
{
  "model_id": "deepgram/nova-3",
  "source": "db",
  "created": true
}

Example:

Shell
curl -X POST http://localhost:8080/v1/models \
  -H "Content-Type: application/json" \
  -d '{"modality":"stt","provider_id":"deepgram","model_name":"nova-3"}'

DELETE /v1/models/{model_id}

Delete a managed model. Requires ?confirm=true. The model_id is a path parameter (e.g., deepgram/nova-3).

Example:

Shell
# Preview
curl -X DELETE "http://localhost:8080/v1/models/deepgram/nova-3"
# Confirm
curl -X DELETE "http://localhost:8080/v1/models/deepgram/nova-3?confirm=true"

Logs and Metrics

GET /v1/logs

Return recent request logs.

Query parameters:

ParameterTypeDefaultDescription
limitinteger100Number of rows (1-1000).
modalitystringnullFilter: stt, llm, or tts.
projectstringnullFilter by project ID.

Response: An array of log records, each containing timestamp, project, modality, model_id, cost_usd, total_latency_ms, status.

Example:

Shell
curl "http://localhost:8080/v1/logs?limit=20&modality=stt"
curl "http://localhost:8080/v1/logs?project=tonys-pizza&limit=50"

GET /v1/metrics

Return Prometheus-format metrics (plain text).

Response (text/plain):

Plain text
# HELP voicegw_uptime_seconds Process uptime
# TYPE voicegw_uptime_seconds gauge
voicegw_uptime_seconds 3621.4
# HELP voicegw_providers_configured Configured providers
# TYPE voicegw_providers_configured gauge
voicegw_providers_configured 5
# HELP voicegw_cost_usd_total Total cost in USD (today)
# TYPE voicegw_cost_usd_total counter
voicegw_cost_usd_total{period="today"} 1.234500
voicegw_requests_total{provider="deepgram"} 42
voicegw_cost_usd_total{provider="deepgram"} 0.512300

Example:

Shell
curl http://localhost:8080/v1/metrics

Audit Log

GET /v1/audit-log

Return audit log entries for CRUD operations performed via the API.

Query parameters:

ParameterTypeDefaultDescription
limitinteger50Number of entries (1-500).
entity_typestringnullFilter: provider, model, or project.
entity_idstringnullFilter by specific entity ID.
actionstringnullFilter: create, update, or delete.

Response: An array of audit log entries.

Example:

Shell
curl "http://localhost:8080/v1/audit-log?entity_type=provider&limit=10"
curl "http://localhost:8080/v1/audit-log?action=delete"

On this page