noburn.devdocs

API Reference

Direct REST API for event ingestion and custom integrations.

The noburn REST API accepts events from any language or runtime. Use it if your language doesn't have an SDK yet, or if you want full control over the request.

Authentication

All API requests use Bearer token authentication with your project's SDK key:

Authorization: Bearer sk-nb-xxxxxxxxxxxxxxxx

SDK keys are project-scoped. A key can only write events to its associated project.


POST /api/v1/events

Records an LLM event (blocked or allowed). This is the core ingestion endpoint — the SDK wraps this call.

Runtime: Edge (Vercel Edge Functions) Target latency: p99 < 150ms

The server returns 202 immediately and processes the event asynchronously. Budget evaluation, alert rule checks, and webhook dispatches happen after the response.

Request

POST https://noburn.dev/api/v1/events
Authorization: Bearer sk-nb-xxxxxxxxxxxxxxxx
Content-Type: application/json
{
  "project_id": "550e8400-e29b-41d4-a716-446655440000",
  "model": "gpt-4o",
  "tokens_in": 1423,
  "tokens_out": 487,
  "cost_usd": 0.00848,
  "was_blocked": false,
  "end_user_id": "user_abc123",
  "block_reason": null,
  "latency_ms": 1240,
  "timestamp": "2025-01-15T14:32:00.000Z"
}

Request body

FieldTypeRequiredDescription
project_idstring (uuid)Must match the project associated with your SDK key
modelstringModel identifier. Max 255 characters
tokens_innumberPrompt token count
tokens_outnumberCompletion token count
cost_usdnumberCost in USD. Use your provider's per-token pricing
was_blockedbooleantrue if the call was blocked before reaching the LLM
end_user_idstringPer-user identifier for spend tracking. Max 255 characters
block_reasonstringWhy the call was blocked. Max 500 characters
latency_msnumberEnd-to-end call latency in milliseconds
timestampstring (ISO 8601)Defaults to server time if omitted

Response

HTTP/1.1 202 Accepted

No response body. A 202 means the event was accepted and queued for processing.

Error responses

StatusCodeReason
400BAD_REQUESTMissing required fields or invalid types
401INVALID_KEYMissing or malformed Authorization header
403INVALID_KEYSDK key is valid but project_id doesn't match
429RATE_LIMITExceeded 1,000 requests/minute per IP

Rate limits

TierLimit
All plans1,000 requests/min per IP

Set Retry-After header is included on 429 responses.

Example — raw fetch (Node.js)

await fetch('https://noburn.dev/api/v1/events', {
  method: 'POST',
  headers: {
    'Authorization': `Bearer ${process.env.NOBURN_SDK_KEY}`,
    'Content-Type': 'application/json',
  },
  body: JSON.stringify({
    project_id: process.env.NOBURN_PROJECT_ID,
    model: 'gpt-4o',
    tokens_in: 1423,
    tokens_out: 487,
    cost_usd: 0.00848,
    was_blocked: false,
    latency_ms: 1240,
  }),
});

Example — curl

curl -X POST https://noburn.dev/api/v1/events \
  -H "Authorization: Bearer sk-nb-xxxxxxxxxxxxxxxx" \
  -H "Content-Type: application/json" \
  -d '{
    "project_id": "550e8400-e29b-41d4-a716-446655440000",
    "model": "claude-3-5-sonnet-20241022",
    "tokens_in": 800,
    "tokens_out": 200,
    "cost_usd": 0.00284,
    "was_blocked": true,
    "block_reason": "budget_exceeded"
  }'

Cost calculation reference

noburn stores whatever cost_usd you send. Use your LLM provider's pricing:

ModelInput (per 1M tokens)Output (per 1M tokens)
gpt-4o$2.50$10.00
gpt-4o-mini$0.15$0.60
claude-3-5-sonnet-20241022$3.00$15.00
claude-3-haiku-20240307$0.25$1.25
gemini-1.5-pro$1.25$5.00
def calculate_cost(model: str, tokens_in: int, tokens_out: int) -> float:
    pricing = {
        "gpt-4o":        (2.50 / 1e6, 10.00 / 1e6),
        "gpt-4o-mini":   (0.15 / 1e6,  0.60 / 1e6),
        "claude-3-5-sonnet-20241022": (3.00 / 1e6, 15.00 / 1e6),
    }
    input_price, output_price = pricing.get(model, (0.001 / 1e6, 0.002 / 1e6))
    return tokens_in * input_price + tokens_out * output_price

GET /api/v1/policy

Fetches the enabled policy rules for a project. baar-core calls this on BAARRouter initialization to load server-configured rules.

Runtime: Edge (Vercel Edge Functions)

Query parameters

ParameterRequiredDescription
project_idYour project UUID

Request

GET /api/v1/policy?project_id=<your-project-id>
Authorization: Bearer sk-nb-xxxxxxxxxxxxxxxx

Response

{
  "rules": [
    { "when": { "utilization": ">= 0.8" }, "then": "force_small" },
    { "when": { "model": "gpt-4o" },       "then": "block" }
  ]
}

Rules are returned in evaluation order (position ascending). Only enabled rules are included. An empty rules array means no rules are configured — all calls proceed normally.

Error responses

StatusMeaning
401Missing or invalid SDK key
403SDK key does not belong to the requested project_id
400project_id query param missing

Error codes

CodeHTTP StatusDescription
UNAUTHORIZED401Not signed in
FORBIDDEN403Signed in but access denied
INVALID_KEY401/403SDK key missing, invalid, or project mismatch
NOT_FOUND404Resource doesn't exist
BAD_REQUEST400Invalid request body
RATE_LIMIT429Too many requests
PLAN_LIMIT_EXCEEDED402Action requires plan upgrade
INTERNAL_ERROR500Server error — retry with backoff

On this page