Skip to main content
POST
/
ingest
/
usage
curl --request POST \
  --url https://api.fenra.io/ingest/usage \
  --header 'Content-Type: application/json' \
  --header 'X-Api-Key: <api-key>' \
  --data '
{
  "provider": "openai",
  "model": "gpt-4o",
  "usage": [
    {
      "type": "tokens",
      "metrics": {
        "input_tokens": 150,
        "output_tokens": 50,
        "total_tokens": 200
      }
    }
  ],
  "context": {
    "billable_customer_id": "acme-corp"
  }
}
'
{
"status": "queued",
"events_queued": 2,
"message": "2 transaction(s) queued for processing",
"results": [
{
"transaction_index": 0,
"message_id": "abc123-def456"
},
{
"transaction_index": 1,
"message_id": "ghi789-jkl012"
}
]
}
Send AI usage transactions for cost tracking.

Request Formats

Single Transaction

{
  "provider": "openai",
  "model": "gpt-4o",
  "usage": [{
    "type": "tokens",
    "metrics": {
      "input_tokens": 100,
      "output_tokens": 50,
      "total_tokens": 150
    }
  }],
  "context": {
    "billable_customer_id": "my-company"
  }
}

Bulk Request

{
  "transactions": [
    { "provider": "openai", "model": "gpt-4o", ... },
    { "provider": "anthropic", "model": "claude-3-5-sonnet", ... }
  ]
}

Context

Only billable_customer_id is required in the context object. You can add any additional fields. They will be stored and available for filtering in your dashboard.
{
  "context": {
    "billable_customer_id": "acme-corp"
  }
}

Response Codes

CodeMeaning
202 AcceptedAll transactions queued
207 Multi-StatusSome succeeded, some failed
400 Bad RequestValidation error
401 UnauthorizedInvalid API key
500 Internal ErrorServer error

Examples

Basic Request

curl -X POST 'https://api.fenra.io/ingest/usage' \
  -H 'Content-Type: application/json' \
  -H 'X-Api-Key: YOUR_API_KEY' \
  -d '{
    "provider": "openai",
    "model": "gpt-4o",
    "usage": [{
      "type": "tokens",
      "metrics": {
        "input_tokens": 100,
        "output_tokens": 50,
        "total_tokens": 150
      }
    }],
    "context": {
      "billable_customer_id": "my-company"
    }
  }'
Response:
{
  "status": "queued",
  "events_queued": 1,
  "message": "1 transaction(s) queued for processing",
  "results": [{
    "transaction_index": 0,
    "message_id": "abc123-def456-ghi789"
  }]
}

Error Responses

Validation Error (400)

{
  "error": {
    "code": "validation_error",
    "message": "Request validation failed",
    "details": [
      {
        "field": "context.billable_customer_id",
        "code": "required",
        "message": "billable_customer_id is required"
      }
    ]
  }
}

Unauthorized (401)

{
  "error": {
    "code": "unauthorized",
    "message": "Invalid or missing API key"
  }
}

Partial Success (207)

{
  "status": "partial_success",
  "events_queued": 1,
  "events_failed": 1,
  "message": "1 transaction(s) queued, 1 transaction(s) failed",
  "results": [
    {
      "transaction_index": 0,
      "message_id": "abc123"
    },
    {
      "transaction_index": 1,
      "message_id": null,
      "error": "Validation failed"
    }
  ]
}

See Also

Authorizations

X-Api-Key
string
header
required

API key for authentication. Must be associated with an active organization.

Body

application/json

Either a single transaction or a bulk request containing multiple transactions

provider
enum<string>
required

AI provider. Fenra automatically applies the correct pricing for each provider. Use 'custom' for providers not yet supported, combined with custom pricing configuration in your dashboard.

Available options:
openai,
gemini,
bedrock,
anthropic,
xai,
deepseek,
custom
model
string
required

The model identifier (e.g., 'gpt-4o', 'claude-3-opus', 'gemini-pro')

Minimum string length: 1
Examples:

"gpt-4o"

"claude-3-opus"

"gemini-1.5-pro"

usage
(Tokens · object | Images · object | Audio · object | Video · object | Requests · object | Custom · object)[]
required

Array of usage entries. Each usage type may appear at most once per transaction.

Minimum array length: 1
context
object
required

Only billable_customer_id is required. Add any additional fields (environment, feature, user_id, team, etc.) and they will appear in your dashboard for filtering, alerts, and reports.

model_tier
string

Optional model tier classification for custom pricing tiers

provider_usage_raw
object

Optional raw usage data from the provider for debugging or auditing

Response

All transactions queued successfully

status
string
required

Status indicating all transactions were queued

Allowed value: "queued"
events_queued
integer
required

Number of transactions successfully queued

Required range: x >= 1
message
string
required

Human-readable success message

results
object[]
required