Skip to main content
Glassray’s metadata convention is a small set of reserved fields with first-class support. They land on every trace as filterable tags, so you can slice flows, deviations, and searches by who a run was for and what it did — and beyond them you can attach any custom attributes and filter by those too:
This is one standard with two ways in: traces pushed by the SDK and traces pulled from Langfuse, LangSmith, or PostHog carry the same tags, so dashboards and filters work identically regardless of how a trace arrived.
Which project a trace lands in is decided by the ingest key, not by any attribute you set — a trace lands in the project of the source (ingest key) that ingested it. The old environment field no longer routes traces and is ignored; use a separate source per project (prod, staging, …). See Projects.

Defaults at construction, overrides per trace

Set the values that are fixed for the process on the constructor; override the ones that vary per run in the trace’s meta. A per-trace value always wins over the constructor default.
In practice: agent is a constructor default, customer is per-trace (it varies with each run), and flow is optional either way.

What it becomes in Glassray

Each field lands as a trace tag (customer:acme-corp, agent:support-agent, …) at ingest — the same filterable index the rest of the dashboard uses. flow is a hint: Glassray’s own flow classification remains the authority for grouping traces.
On the wire these are the glassray.* resource attributes (with a root-span override), which matters only if you bring your own OTel — the SDK sets them for you.

Naming customers

customer is an identifier, and the stable choice is often an opaque one like cus_8fa21. Glassray shows it as a company when it knows the company. You can name identifiers by hand in Settings › Customers, or let each trace name its own by carrying the display name and a contact email beside the identifier:
On the wire, and for traces pulled from Langfuse, LangSmith or PostHog, the customer is one object: glassray.customer.id, glassray.customer.name, glassray.customer.email (glassray.customer is the same identifier, and customer_name / customer_email and the camelCase spellings are accepted aliases). The first trace to carry them names the identifier for the whole organization: the name shows on the traces list, the trace sheet, the filters and the Costs page, and the email’s domain fetches the company logo. Pass glassray.customer.domain instead when you have the domain and not an email.
The email is used only to work out the company domain and is not stored. A personal address (alice@gmail.com) gives no domain, so the customer keeps its monogram rather than the Gmail logo. A name set from a trace never overwrites one typed in Settings, and a trace only fills what is still blank. To change a name, edit it in Settings; to let traces set it again, clear it there. Name, email and domain are not filterable attributes — the identifier is what you filter on.

Custom attributes

The three reserved fields aren’t the whole story: attach any custom attributes and filter your traces by them in the dashboard — by merchantId, branch, region, or whatever your traces already carry. Set per-process defaults on the constructor and add or override per trace in meta.attributes:
Then in the Traces view, Add filter → Attribute lists every custom attribute your traces carry, so merchantId is acme narrows the stream to one merchant.
Values are scalar (string / number / boolean). A per-trace attribute overrides a constructor default of the same key (it rides the root span). Reserved keys — glassray.*, gen_ai.*, and OTel infra prefixes like service.* / session.* — are dropped with a warning so a custom attribute can never shadow a first-class field.
Two ways in, same result. Custom attributes work identically for pulled traces: whatever metadata your Langfuse / LangSmith / PostHog traces already carry is picked up automatically — no SDK required, no re-ingest. High-cardinality id-shaped values (UUIDs, hashes, long ids) are kept on the trace but not offered as filter options, so the picker stays useful.