Skip to main content
Status: Private preview Spec version: 2025-08-18 Breaking changes possible

Table of Contents

  1. Quick Start (under 5 minutes)
  2. Concepts
  3. API Reference
  4. Resources
  5. Operational Notes & Best Practices
  6. Changelog
  7. Reference Status Codes

1) Quick Start (under 5 minutes)

🔮 Note that all API usage examples are provided using cUrl and bash commands. Adapt these API calls to whatever language / environment your LLM-powered application is running in.

Authentication

To get started you’ll need a Brixo API key provided to you by your account team. Pass the API key as a Bearer in the Authorization HTTP request header like so:
curl -sv https://api.brixo.com/instrumentation/tracing/v1/observations \
  -H "Authorization: Bearer $BRIXO_KEY" \
  -H "Accept: application/vnd.api+json"
There are two ways to share your inference with us:

1. Proxy your inference through the Brixo Proxy

  • Brixo Proxy (to ANY LLM provider): https://proxy.brixo.com/<llm_provider_url>
  • LLM Provider credentials: Either pass the same authentication headers you’d send directly to the LLM provider (e.g., Authorization: Bearer <key>, x-api-key: <key>), or let Brixo store/manage the LLM provider keys for you so you don’t have to pass them in your API calls every time.

2. Send traces to us offline

  • Tracing ingest (sidecar/offline): https://api.brixo.com/instrumentation/tracing/v1/

Copy, Paste, and Run Examples

Replace $BRIXO_KEY with your Brixo API Key and, if using the Brixo Proxy, any LLM provider keys.

1.1 Set up env

export BRIXO_KEY="<YOUR_BRIXO_API_KEY>"
export LLM_PROVIDER_KEY="<YOUR_LLM_PROVIDER_API_KEY>" # if using the Brixo Proxy

1.2 Hello World via Brixo Proxy (OpenAI example)

🛠️ Managed API keys: If Brixo stores your LLM Provider API keys, omit the LLM_PROVIDER_KEY env var (above) and the Authorization header (below).
curl -sv -X POST [https://proxy.brixo.com/api.openai.com/v1/chat/completions](https://proxy.brixo.com/api.openai.com/v1/chat/completions) \
  -H "Content-Type: application/json" \
  -H "Brixo-Auth: Bearer $BRIXO_KEY" \
  -H "Authorization: Bearer $LLM_PROVIDER_KEY" \
  -d '{
    "model": "gpt-4o-mini",
    "messages": [{"role":"user","content":"Say hello in one word"}]
  }'

1.3 Sidecar trace (send Brixo a completed inference)

curl -sv -X POST https://api.brixo.com/instrumentation/tracing/v1/traces \
  -H 'Accept: application/vnd.api+json' \
  -H "Authorization: Bearer $BRIXO_KEY" \
  -H 'Content-Type: application/vnd.api+json' \
  -d '{
  "data": {
    "type": "string",
    "attributes": {
      "client": {},
      "error": {},
      "metadata": {},
      "metrics": { "latency_ms": 400 },
      "environment": "production",
      "started_at": "2025-09-23T03:26:40.132Z",
      "ended_at": "2025-09-23T03:26:40.132Z",
      "observations": [
        {
          "kind": "llm",
          "started_at": "2025-09-23T03:26:40.132Z",
          "ended_at": "2025-09-23T03:26:40.132Z",
          "provider": "openai",
          "model": "gpt-5",
          "endpoint": "chat/completions",
          "parameters": {
					  "temperature": 1.0,
					  "top_p": 1.0,
					  "frequency_penalty": 0,
					  "presence_penalty": 0,
					  "n": 1,
					  "stream": false
					},
            "input": {
					    "messages": [
					      { "role": "user", "content": "Hi there!" }
					    ]
					  },
					  "output": {
					    "messages": [
					      { "role": "assistant", "content": "Hello, how can I help you today?" }
					    ]
					  },
          "usage": {},
          "cost": {},
          "metrics": { "latency_ms": 400 },
          "metadata": {}
        }
      ]
    }
  }
}'

1.4 Attach observations to a trace

curl -sv -X POST https://api.brixo.com/instrumentation/tracing/v1/observations \
  -H 'Accept: application/vnd.api+json' \
  -H "Authorization: Bearer $BRIXO_KEY" \
  -H 'Content-Type: application/vnd.api+json' \
  -d '{
  "data": {
    "type": "string",
    "attributes": {
      "kind": "llm",
      "started_at": "2025-09-23T03:32:10.844Z",
      "ended_at": "2025-09-23T03:32:10.844Z",
      "provider": "openai",
      "model": "gpt-4",
      "endpoint": "chat/completions",
      "metrics": { "latency_ms": 400 },
      "parameters": { "temperature": 0.2, "max_output_tokens": 512 },
      "input": { "messages": [{ "role": "user", "content": "How do I reset my password?" }] },
      "output": {
        "messages": [
          { "role": "assistant", "content": "Hello, how can I help you today?" }
        ]
      }
    },
    "relationships": {
      "trace": {
        "data": {
          "type": "string",
          "id": 1
        }
      }
    }
  }
}'

2) Concepts

  • Trace: Logical unit of work for an inference (request/response, timings, costs, metadata).
  • Observation: Child event attached to a trace (retrievals, tool calls, feedback/scores, spans).

3) API Reference

  1. Create Trace
  2. Create Observations (scoped by Trace)
  3. Create Trace with Observations

JSON:API • Conventions

  • Media type
    • Requests: Content-Type: application/vnd.api+json
    • Responses: Content-Type: application/vnd.api+json
    • Clients SHOULD send Accept: application/vnd.api+json
  • Top-level members: data | errors | meta | links | jsonapi (optional)
  • Auth: Authorization: Bearer <Brixo_API_key>
  • Timestamps: RFC3339 (e.g., 2025-09-17T12:34:56Z)

Create Trace

  • Route: POST /instrumentation/tracing/v1/
  • Purpose: Create an empty trace, with the intention of subsequently adding one or more observations using the Create Observations endpoint.
Request
{
  "data": {
    "type": "trace",
    "attributes": {
      "name": "agent_session",
      "project": "acme",
      "environment": "prod",
      "client": { "sdk": "gc-sdk", "version": "1.2.0" },
      "metadata": { "release": "2025.09.1" },
      "started_at": "2025-09-17T12:00:00Z"
    }
  }
}
Response — 201 Created
{
  "data": {
    "type": "trace",
    "id": "tr_01JABC",
    "attributes": {
      "name": "agent_session",
      "project": "acme",
      "environment": "prod",
      "client": { "sdk": "gc-sdk", "version": "1.2.0" },
      "metadata": { "release": "2025.09.1" },
      "started_at": "2025-09-17T12:00:00Z",
      "ended_at": null,
      "status": null,
      "error": null,
      "metrics": [],
      "ingested_at": "2025-09-17T12:00:01Z"
    },
    "links": { "self": "/traces/tr_01JABC" }
  }
}

Create Observations (scoped by Trace)

  • Route: POST /tracing/v1/observations
  • Purpose: Create an observation within a trace.
Request
{
  "data": {
    "type": "string",
    "attributes": {
      "kind": "llm",
      "started_at": "2025-09-23T03:32:10.844Z",
      "ended_at": "2025-09-23T03:32:10.844Z",
      "status": "success",
      "provider": "openai",
      "model": "gpt-4",
      "endpoint": "chat/completions",
      "parameters": { "temperature": 0.2, "max_output_tokens": 512 },
      "input": { "messages": [{ "role": "user", "content": "How do I reset my password?" }] },
      "output": { "a": 1 },
      "usage": {},
      "cost": {},
      "metrics": {},
      "metadata": {}
    },
    "relationships": {
      "trace": {
        "data": {
          "type": "trace",
          "id": 1
        }
      }
    }
  }
}
Response — 201 Created
{
  "data": {
    "type": "observation",
    "id": "ob_01JXYZ",
    "attributes": {
      "name": "draft_answer",
      "kind": "llm",
      "started_at": "2025-09-17T12:01:03Z",
      "ended_at": null,
      "status": null,
      "error": null,
      "provider": "openai",
      "model": "gpt-4o-mini",
      "model_version": null,
      "parameters": { "temperature": 0.2, "max_output_tokens": 512 },
      "endpoint": "chat.completions",
      "region": null,
      "provider_request_id": null,
      "provider_response_id": null,
      "input": { "messages": [{ "role": "user", "content": "How do I reset my password?" }] },
      "output": null,
      "usage": null,
      "cost": null,
      "metrics": [],
      "metadata": { "release": "2025.09.1" },
      "ingested_at": "2025-09-17T12:01:04Z"
    },
    "relationships": {
      "trace": {
        "data": { "type": "trace", "id": "tr_01JABC" },
        "links": { "related": "/traces/tr_01JABC" }
      }
    },
    "links": { "self": "/traces/tr_01JABC/observations/ob_01JXYZ" }
  }
}

Create Trace with Observations

  • Route: POST /instrumentation/tracing/v1/traces
  • Purpose: Create a trace and its observations in one request.
  • Note: The request is a pragmatic extension (JSON:API normally expects identifiers in relationships). Responses are canonical JSON:API.

Request (schema)

{
  "data": {
    "type": "trace",
    "attributes": {
      "name": "agent_session",
      "environment": "prod",
      "started_at": "2025-09-17T12:00:00Z"
    }
  },
  "relationships": {
    "observations": {
      "data": [
        {
          "type": "observation",
          "attributes": {
            "kind": "llm",
            "name": "draft_answer",
            "started_at": "2025-09-17T12:01:03Z",
            "provider": "openai",
            "model": "gpt-4o-mini",
            "input": { "messages": [{ "role": "user", "content": "Q1" }] }
          }
        },
        {
          "type": "observation",
          "attributes": {
            "kind": "tool",
            "name": "search",
            "started_at": "2025-09-17T12:01:10Z",
            "input": { "query": "reset password" }
          }
        }
      ]
    }
  }
}

Semantics & Rules

  • data (trace)
    • type must be "trace
  • relationships.observations.data
    • Array of full observation resource objects.
    • Each item must have type: "observation" and valid attributes per the Observation resource spec.

Response Objects

201 Created — success

{
  "data": {
    "type": "trace",
    "id": "tr_01JABC",
    "attributes": { "...": "..." },
    "links": { "self": "/traces/tr_01JABC" }
  },
  "included": [
    {
      "type": "observation",
      "id": "ob_01",
      "attributes": { "...": "..." },
      "relationships": { "trace": { "data": { "type": "trace", "id": "tr_01JABC" } } },
      "links": { "self": "/traces/tr_01JABC/observations/ob_01" }
    },
    {
      "type": "observation",
      "id": "ob_02",
      "attributes": { "...": "..." },
      "relationships": { "trace": { "data": { "type": "trace", "id": "tr_01JABC" } } },
      "links": { "self": "/traces/tr_01JABC/observations/ob_02" }
    }
  ]
}

422 Unprocessable Entity

{
  "errors": [
    {
      "status": "422",
      "code": "validation_failed",
      "title": "Validation failed",
      "detail": "started_at is required",
      "source": { "pointer": "/relationships/observations/data/1/attributes/started_at" }
    }
  ]
}

4) Resources

1) Trace

Type: trace Route (plural): /traces
A trace is a container for a run/session

Attributes

AttributeDetailsType / FormatNotes & Validation
nameoptionalstring (1–128)Human-readable label.
projectoptionalstring (1–128)Logical grouping.
environmentrequiredstringe.g., prod, staging, dev, or custom.
clientoptionalobject{ sdk?: string, version?: string, user_agent?: string }.
metadataoptionalobjectFreeform JSON; ≤ 16 KB serialized, depth ≤ 3.
started_atoptionalRFC3339 timestampTrace start.
ended_atoptionalRFC3339 timestampMust be ≥ started_at.
statusoptionalenumOne of: success, error, timeout, cancelled.
erroroptionalobject{ code: string, type?: string, message: string, retryable?: boolean }.
metricsoptionalarray<object>{ name: string (1–64, [A-Za-z0-9_.-]), value: number, scale?: string, source?: "human" | "auto", at?: RFC3339 }.

2) Observation

Type: observation All routes are nested: /traces/{trace_id}/observations[...]
An observation is an atomic step inside a trace (e.g., LLM call, tool call, retrieval, eval).

Attributes

AttributeDetailsType / FormatNotes & Validation
nameoptionalstring (1–128)Step label.
kindrequiredenumOne of: llm, tool, retrieval, rerank, eval, system.
started_atrequiredRFC3339 timestampStep start time.
ended_atrequiredRFC3339 timestampMust be ≥ started_at.
statusoptionalenumOne of: success, error, timeout, cancelled.
erroroptionalobject{ code, type?, message, retryable?, provider_code? }.
providerrequiredstringe.g., openai, anthropic, vertex.
modelrequiredstringe.g., gpt-4o-mini.
model_versionoptionalstringProvider/model release string.
parametersrequiredobjectE.g., temperature, top_p, max_output_tokens, stop, seed, tool_choice.
endpointrequiredstringe.g., chat.completions.
regionoptionalstringCloud/region id.
provider_request_idoptionalstringUpstream correlation.
provider_response_idoptionalstringUpstream correlation.
inputrequiredobjectFreeform JSON (any valid object).
outputrequiredobjectFreeform JSON (any valid object).
usageoptionalobject{ input_tokens?, output_tokens?, total_tokens?, compute_time_ms?, input_time_ms?, output_time_ms?, total_time_ms? } (non-negative).
costoptionalobject{ total: number, currency?: string = "USD", estimated?: boolean } (non-negative).
metricsoptionalarray<object>Same shape as trace metrics.
metadataoptionalobjectFreeform JSON; ≤ 16 KB serialized, depth ≤ 3.
ingested_atserver definedRFC3339 timestampServer receive/commit time.

Relationships (JSON:API form in responses)

"relationships": {
  "trace": { "data": { "type": "trace", "id": "<trace_id>" } }
}

5) Operational Notes & Best Practices

  • Retries: Exponential backoff for 429/5xx. Respect Retry-After if present.
  • PII: If you require automatic redaction, contact us for a tenant‑level policy.

6) Changelog

  • 2025‑09‑15: Provider‑neutral examples and wording; removed vendor names in examples; retained legacy /api/providers/open_ai/v1 endpoints (historical naming) but clarified they work with any origin via bxo_origin.
  • 2025‑09‑10: Switched to provider‑agnostic proxy via bxo_origin; introduced Authorization header; updated examples.
  • 2025‑09‑07: Major reorg by use case; added Quick Start; added tracing ingest namespace and observation association; standardized cURL blocks; added guidance on idempotency, correlation headers, and size limits.
  • 2025‑08‑18: Initial consolidated draft (proxy, files, batches).

7) Appendix – Reference Status Codes

  • 200 OK: Successful GET/DELETE
  • 201 Created: Successful creation
  • 400 Bad Request: Malformed ID, invalid parameters
  • 401 Unauthorized: Missing/invalid token
  • 403 Forbidden: Valid token but lacks access
  • 404 Not Found: Unknown file_id/batch_id
  • 409 Conflict: Resource not ready (e.g., file not processed)
  • 422 Validation Failed: Field/type/enum violations
  • 429 Too Many Requests: Rate limited
  • 5xx: Server‑side errors