Documentation / Attribution / OASA events and OpenTelemetry

OASA events and OpenTelemetry

Early accessEarly access

OASA is the open record for agent spend. The current specification is OASA 0.1.3. OpenTelemetry is one way to produce those records. The collector setup is in the OpenTelemetry connector guide. Ingest keys are in Manage ingest keys. This page is what Meridian does with the agent and the cost center after the event arrives.

What you set up

  1. Create an ingest key with the ingest scope, under Settings → Ingest keys.
  2. Send usage records to the events endpoint the connector guide names. Each agent needs its own agent id on the record. Meridian creates the agent from that id if it does not exist yet.
  3. Put a cost center on the record when the department should follow the event. Use one cost center for a given agent on a given day.
  4. To map a cost center that does not match a department code or name, open Source identities, under OASA cost centers, and assign it to an agent and a department.

The released OpenTelemetry exporter (v0.2.0) reads the agent id from oasa.agent.id. gen_ai.agent.id, or else gen_ai.main_agent.id, is written to the external identity and is not the agent id. oasa.cost_center, oasa.agent.owner, and oasa.project.id fill the cost center, the owner, and the project. A configured attribution setting fills one of those only when the span left it empty. attribution.legacy_gen_ai_agent_id restores the older behavior of copying gen_ai.agent.id into the agent id. It is off by default. The exporter writes usage records. It does not write the provider invoice. The mapping is the OASA 0.1.3 OpenTelemetry table. Setup is in the connector guide.

Span attributes do not appear on the provider's bill. They attribute the usage record. The charge joins them only when something else ties the two together.

What Meridian receives

One event per request or operation you send. Meridian rolls them up to one spend row per agent, model, UTC day, and pool id. A blank pool id is its own group. The amount is the cost on the events, until a reconciliation scales a row that has no pool id.

A cost center is read from the events in that group. The row keeps a cost center only when every event in the group has the same one. Two cost centers, or a mix of present and missing, leave the cost center empty.

The rollup does not add the cost center to the identity of the row. Two cost centers for the same agent and day stay one row. That is a limit, not a split waiting to happen.

How it's attributed

When the event has an agent id, the agent is declared. A rule does not replace it. A person cannot replace it from the inbox.

The department, when there is exactly one cost center, is chosen in this order:

  1. An active mapping on Source identities for that OASA cost center. The mapping wins even when a department happens to use the same code. The event's agent is kept when the mapping names a different agent.
  2. Otherwise one department whose code or name matches the cost center. Spaces, dashes, underscores, and letter case are ignored. If two departments normalize to the same label, neither is used.
  3. Otherwise no department.

With an agent and a mapping, the agent stays declared and the mapping records where the department came from. With no agent and a mapping, the row is mapped by you, and the agent can come from the mapping. With no agent and a department-code match, the department is inherited and the agent stays empty. With neither, the row is unattributed.

A re-rollup refreshes the amount. It does not fill a department onto a row that was stored before, and it does not change the agent or the attribution of a row that already exists. The first insert is the one that stamps the cost center.

When a provider bill exists for the same vendor, model, and day, Meridian scales rows that have no pool id to that bill and keeps the bill as the tie-out. A row with a pool id stays at the measured cost. Events with no matching bill keep their measured cost. A bill with no events stays on the bill's own grain.

What lands unattributed, and how to fix it

Records with no agent id roll up unattributed. Put the agent id on the event. Days already stored stay as they are until you assign the unattributed rows. Assignment does not replace a day that was declared.

Cost-center reasons:

  • "This cost center is not mapped to an agent or department." Add a department with that code or name, or map the cost center on Source identities. Saving applies the mapping to unlocked unattributed rows.
  • "This usage has more than one cost center, or the cost center matches more than one department." Send one cost center per agent per day, or give the two departments distinct codes. Both values still appear on Source identities so you can map them. The spend row is not split.
  • "This usage has no cost center." This sentence is used when the row is otherwise unattributed. Declared traffic that simply had no cost center does not fill the inbox with it.

A locked month is not rewritten. The correction is an adjustment on a later draft.

Limits

  • One agent, one pool id, and several cost centers on the same day stay one row, with no cost center stamped.
  • A later rollup does not backfill a department onto rows already stored.
  • The provider invoice does not carry these span attributes. Without a matching bill, you have the usage total, not the invoice. With a matching bill, you have the invoice total allocated by the event mix for that vendor, model, and day.
  • Shadow AI discovery is a different intake. It is not this chargeback path.
  • Both catalog entries are Early access. The badges are in the status section below.

Status

  • OASA event ingest is Early access in the integrations catalog. Available to customers now. We confirm the first import with you in a sandbox before production.
  • OpenTelemetry Collector is Early access in the integrations catalog. Available to customers now. We confirm the first import with you in a sandbox before production.