Attribute payments to agents
A payment record that cannot say which agent made it, for whom, and on what instruction is little use to a bank. Attribution is the one job the SDK cannot do for you, because only your code knows who the agent is.
Use agent context
Section titled “Use agent context”Wrap the code that runs an agent task in withAgentContext. Every event emitted inside it, including by the rail
adapters, picks up the context without you passing it around.
import { HalvorClient, withAgentContext } from '@halvorai/ingest';
const halvor = new HalvorClient();
await withAgentContext( { agent: { id: 'agt_research_07', name: 'Market research agent', framework: 'openai-agents' }, owner: { id: user.id, type: 'person', country: 'US' }, instruction: { id: task.id, text: task.prompt, channel: 'chat' }, }, () => agent.run(task),);Context follows the call through await, timers and callbacks, and concurrent tasks keep separate contexts.
A nested context replaces fields of the outer one.
In Python, use agent_context(...) as a with block. See the Python SDK.
What to put in each field
Section titled “What to put in each field”| Field | Guidance |
|---|---|
agent.id | A stable id you choose, such as agt_research_07. The same agent must always use the same id. |
owner.id | The person or business the agent acts for, as your system knows them. Not an email address if you can avoid it. |
owner.type | person or business. |
owner.country | Optional ISO country code. |
instruction.id | Your id for the task or request. |
instruction.text | The text the agent received. It is hashed on your machine. Only the hash leaves. |
instruction.summary | Optional. A short redacted description a bank may read, up to 500 characters. |
instruction.tool_call_id | The tool call that triggered the payment, when there is one. |
The hash lets a bank later confirm that an instruction you disclose is the one the agent actually received. HalvorAI never sees the text.
Attribution coverage
Section titled “Attribution coverage”The dashboard reports attribution coverage: events that have an agent, an owner and an instruction, divided by all
events. A sponsor bank often asks for this number. Events with no agent are stored under the agent unattributed and count
against it. They are never dropped.
To raise coverage:
- Make sure payments happen inside
withAgentContext. - For Stripe, tag the object when you create it so webhooks can be attributed later. See the Stripe guide.
- For MCP tools, observe the client so the tool call id is recorded. See the MCP guide.
Chains of agents
Section titled “Chains of agents”If one agent hires another, set instruction.channel to agent on the second agent’s events and link them with
related.previous_event_id. The schema has no nested owners in this version.
What not to send
Section titled “What not to send”Do not send identity documents or KYC data in owner. kyc_ref is a pointer into your own system. Do not put a person’s
payment card details anywhere. See data handling.