team, workflow, userId. The collector stamps them onto the call metadata it emits to the control plane, and each field drives one lens in the dashboard.
You set attribution once as a default and refine it per call. Nothing about attribution changes what leaves your VPC: the full prompt and response stay in your local Postgres, and only the tags below — hashed according to your sensitivity profile — reach Firedog cloud.
The three context fields
The desk or cost centre that owns the spend — for example
macro-desk, credit-research, quant-pnl. Rolls up into the desk lens in Cost allocation, so finance can attribute and charge back a run to the group that spent it. Usually set once on defaultContext per application or service.The named process the call belongs to — for example
market-research, kyc-review, earnings-summary. Populates the workflow register on Home (the reconciled bill, per workflow) and opens the step-by-step workflow detail view where the re-read tax is visible. Best set per call, since one service often runs several workflows.The end user or service account behind the call — for example
u_123. It is always salted-hashed inside your VPC before any metadata leaves it, so the dashboard shows stable per-user cost buckets (user_9f3c…) without ever receiving a raw identity. Pass your own internal identifier; the collector does the hashing.All three fields are optional. A call with none of them still prices, still writes its full record locally, and still reconciles into the total — it just files under Untagged. See Untagged still reconciles below.
Field-to-lens map
| Field | Header | Dashboard lens | How it leaves the VPC |
|---|---|---|---|
team | x-firedog-team | Desk (Cost allocation) | Raw under standard/open; hashed under strict |
workflow | x-firedog-workflow | Workflow register (Home, Workflow detail) | Raw under standard/open; hashed under strict |
userId | x-firedog-user | Salted per-user | Always salted-hashed, every profile |
Setting attribution
There are two ways to attach context, and they produce identical metadata. Use the SDK if your code calls the SDK; set the headers directly if you route through the collector as a drop-in proxy.With the SDK
defaultContext applies to every call from a client. Per-call context is merged on top, so shared tags live on the client and the variable tag rides with the request.
With raw headers (proxy path)
If you point an existing OpenAI-compatible client at the collector’s base URL instead of using the SDK, set the same attribution asx-firedog-* headers. You also mint the correlating x-firedog-call-id yourself — a client-side ULID that ties this request to its full VPC record. (The SDK does both for you.)
The header names are the wire format for both paths — the SDK simply serialises
context into x-firedog-team, x-firedog-workflow and x-firedog-user, and mints x-firedog-call-id.How context becomes metadata
The collector prices the call, writes the full record (messages, any RAG chunks, response) to your local Postgres, and emits onlyCallMetadata to the control plane. The attribution fields on that metadata are exactly your three tags — with userId already hashed, and team/workflow hashed or raw depending on the profile:
Hashing and sensitivity
What gets hashed before it leaves the VPC is governed by your sensitivity profile, a configurable default rather than a hard guarantee:strict
Maximal redaction.
team and workflow are hashed to opaque tokens (for example Project-Titan → wf_7c2a); userId is hashed; identifying categories may be dropped.standard
Balanced. Raw
team and workflow labels, salted userHash, quality signal retained.open
Richest tags, for teams whose labels are not sensitive.
userId is always salted-hashed — there is no setting that emits a raw user identity. Under strict, a desk whose name is itself sensitive (a codenamed project, a client mandate) still reconciles correctly in the dashboard; it just appears under a stable hash instead of a readable label.
Untagged still reconciles
Attribution is additive, never a gate. A call with noteam, no workflow and no userId is still priced, still written in full to your VPC, and still counted in the total — it rolls up under Untagged. On Home, tagged plus untagged spend equals the reconciled bill to the cent, so nothing is dropped for lacking a label and the “Untagged” line tells you exactly how much attribution work is left to do.
A healthy rollout drives the Untagged line toward zero over time by adding
defaultContext to more services.Next steps
Sensitivity profiles
Decide what the collector is allowed to emit for each tag.
Quality & shadow testing
Score answers and prove a cheaper model holds up — without leaking content.
Security & data residency
What stays in your VPC, and what the metadata contains.
