dexcost
API Reference

API Reference

REST API for event ingestion, analytics, and data export.

All requests require a Bearer API key issued from app.dexcost.io.

Authorization: Bearer dx_live_...
Content-Type: application/json

Base URL: https://api.dexcost.io (illustrative — your workspace’s actual ingest host is shown on the API Keys page in the dashboard)


Ingestion

POST /v1/ingest

Batch-ingest events and tasks in a single request. This is the primary endpoint used by SDK sync workers.

POST /v1/ingest
Authorization: Bearer dx_live_...

{
  "tasks": [...],
  "events": [...]
}

Request body

FieldTypeDescription
tasksTask[]Array of task objects (see schema below).
eventsEvent[]Array of event objects.

Both arrays are optional — you can send tasks only, events only, or both.

Response

{
  "accepted": 12,
  "rejected": 0,
  "errors": []
}

POST /v1/events

Ingest a single event.

POST /v1/events
Authorization: Bearer dx_live_...

{
  "event_id": "evt_abc123",
  "task_id": "task_xyz456",
  "event_type": "llm_call",
  "customer_id": "acme-corp",
  "project_id": "chatbot-v2",
  "provider": "openai",
  "model": "gpt-4o",
  "input_tokens": 1200,
  "output_tokens": 480,
  "cost_usd": "0.0096",
  "cost_confidence": "exact",
  "pricing_source": "openai_api",
  "is_retry": false,
  "created_at": "2026-04-06T12:00:00Z"
}

Event types: llm_call, external_cost, compute_cost, retry_marker

Cost confidence values: exact, computed, estimated, unknown

Response: 201 Created with the stored event object.


POST /v1/tasks

Create or upsert a task record.

POST /v1/tasks
Authorization: Bearer dx_live_...

{
  "task_id": "task_xyz456",
  "task_type": "resolve_ticket",
  "customer_id": "acme-corp",
  "project_id": "chatbot-v2",
  "status": "success",
  "started_at": "2026-04-06T12:00:00Z",
  "ended_at": "2026-04-06T12:00:03Z"
}

Status values: pending, success, failed

Response: 201 Created with the stored task object.


Reports

All report endpoints support the following common query parameters:

ParameterTypeDescription
fromISO 8601 dateStart of time range (inclusive).
toISO 8601 dateEnd of time range (inclusive).
customer_idstringFilter to a single customer.
project_idstringFilter to a single project.
granularityday | week | monthTime bucket size. Default: day.

GET /v1/api/reports/cost

Total cost broken down by time bucket and dimension.

GET /v1/api/reports/cost?from=2026-04-01&to=2026-04-06&granularity=day
Authorization: Bearer dx_live_...

Response

{
  "data": [
    {
      "date": "2026-04-01",
      "total_cost_usd": "12.4500",
      "llm_cost_usd": "10.2000",
      "external_cost_usd": "1.8000",
      "compute_cost_usd": "0.4500",
      "total_tokens": 1240000
    }
  ],
  "summary": {
    "total_cost_usd": "74.7000",
    "period_days": 6
  }
}

GET /v1/api/reports/waste — Cost Health

Retry cost analysis — cost spent on failed attempts that were retried.

GET /v1/api/reports/waste?from=2026-04-01&to=2026-04-06
Authorization: Bearer dx_live_...

Response

{
  "data": [
    {
      "date": "2026-04-01",
      "retry_cost_usd": "0.8400",
      "retry_count": 42,
      "retry_cost_pct": "6.74"
    }
  ],
  "summary": {
    "total_retry_cost_usd": "5.0400",
    "total_retries": 252,
    "avg_retry_cost_pct": "6.74"
  }
}

GET /v1/api/reports/profitability

Per-customer margin analysis. Requires revenue data to be configured.

GET /v1/api/reports/profitability?from=2026-04-01&to=2026-04-06
Authorization: Bearer dx_live_...

Response

{
  "data": [
    {
      "customer_id": "acme-corp",
      "revenue_usd": "500.00",
      "cost_usd": "42.80",
      "margin_usd": "457.20",
      "margin_pct": "91.44"
    }
  ]
}

Customers

GET /v1/api/customers

List all customers with aggregated cost and usage.

GET /v1/api/customers?from=2026-04-01&to=2026-04-06&limit=50&offset=0
Authorization: Bearer dx_live_...

Query parameters

ParameterTypeDefaultDescription
limitinteger50Maximum records to return. Max: 500.
offsetinteger0Records to skip (for pagination).
sortcost_usd | tokens | retry_cost_usdcost_usdSort field.
orderasc | descdescSort direction.

Response

{
  "data": [
    {
      "customer_id": "acme-corp",
      "total_cost_usd": "42.80",
      "llm_cost_usd": "38.20",
      "retry_cost_usd": "2.10",
      "total_tokens": 428000,
      "task_count": 312,
      "first_seen": "2026-03-01T00:00:00Z",
      "last_seen": "2026-04-06T11:45:00Z"
    }
  ],
  "pagination": {
    "total": 148,
    "limit": 50,
    "offset": 0,
    "has_more": true
  }
}

Error format

All errors follow a consistent structure:

{
  "error": {
    "code": "invalid_api_key",
    "message": "The API key provided is invalid or has been revoked.",
    "status": 401
  }
}

Common error codes

CodeStatusDescription
invalid_api_key401Missing or invalid Bearer token.
insufficient_permissions403Key does not have access to this resource.
not_found404Resource does not exist.
validation_error422Request body failed schema validation.
rate_limited429Too many requests. Retry after the Retry-After header.
internal_error500Unexpected server error.

Pagination

All list endpoints use offset pagination:

GET /v1/api/customers?limit=50&offset=50

The response always includes a pagination object:

{
  "pagination": {
    "total": 148,
    "limit": 50,
    "offset": 50,
    "has_more": true
  }
}

Iterate by incrementing offset by limit until has_more is false.

On this page