Skip to main content
Niadra is the memory of every agent in the company: the ones that serve customers and the ones that work inside, in the CRM, the ERP, the help desk, billing and orders. For that, the memory takes in three things besides conversations: the system events your systems already emit, the business objects they refer to and the actions agents take in those systems. That is how the voice agent knows at 2:07 pm what the billing agent did at 2:06 pm.

System events

A system event is a state change in a system of record: order created, invoice disputed, ticket reopened, payment declined. It comes in as kind: "system_event", with speaker set to system and a canonical_type such as invoice.credited, plus structured fields in fields. There are three ways in:
A system event is structured data and enters without an AI model: the mapping pulls out the type, the object, the customer ids, the fields and the time. Only mapped types enter the memory, which shields it from the volume of an ERP. The raw payload of an unmapped type is kept for 7 days so you can remap it, and never enters the memory. Free text from inside a system, such as a ticket description, comes in as a message on its own channel and goes through normal extraction. System events are not billed. The unit is still the conversation or task.

Business objects

Orders, tickets, invoices, contracts, deliveries and subscriptions are objects. Each is identified by the triple type, namespace and id, unique within the space, such as invoice:erp:0823. The SDKs accept that shorthand. An object is tied to the customer through their id in that system, the system_id handle, and keeps the timeline of events and actions plus a derived state, always with as_of, the source and a reference to the source record. The official value stays in your system. The memory keeps enough for the agent to remember and act, and points back to the source. Splitting two profiles takes orders and invoices to the right owner on its own, because the object is tied to its handle of origin. Read an object with GET /v1/objects/{object_type}/{namespace}/{external_id} and its events and actions with /timeline, both with the context scope and a receipt. The ids may contain slashes and colons. In the SDKs, object_state() and object_timeline() in Python, objectState() and objectTimeline() in TypeScript:
Your governance team sees every object of one customer, with the actions on them, through GET /v1/profiles/{profile_id}/objects.

Agent actions

An action is the record of what an agent, internal or customer-facing, or a human attendant did in a system: the canonical operation (credit, reschedule), the object, the result, the purpose and, optionally, closes, the open item the action fulfils.
closes points to the open item by item_id or by the object and operation pair, never both. Recording an action needs the key’s act scope, for that operation and object type; track alone is not enough. Actions are immutable: a correction is a new action with corrects_action_id.

Declared, confirmed, divergent

A declared action only closes an open item when its operation is in the trusted_action_ops of the source; a confirmed action always closes it. Actions from a session with an excerpt flagged as prompt injection are quarantined: they close nothing and never show as done.

Retroactive close

An action may arrive before the open item exists. At 2:05 pm Marina disputes the invoice in the app, and the open item is only born when the app session closes and is extracted, at 2:35 pm. The billing agent acts at 2:06 pm. When it creates the open item, Niadra looks for actions already applied to the same object and operation within the window, and the open item is born resolved, closed by the 2:06 pm action.

Context per task

The internal agent reads context centered on the object, with a task view and the no_customer level, because no customer is present:
A task view favours objects of the task’s type, the open items tied to them and what was said about them in conversations. Whatever the source’s purpose does not allow stays out: the billing agent reads invoices and disputes, not technical open items.

The 2:06 pm path

  1. 2:05 pm, app: the dispute comes in and, in under 1 second, is readable and tied to invoice:erp:0823.
  2. 2:06 pm, billing agent: reads the invoice context, gets the dispute through live, posts the credit in the ERP and records the action.
  3. 2:06 pm, ERP: emits invoice.credited; the action becomes confirmed.
  4. Within seconds: the voice context gains “done by another agent: $40 credit, confirmed by the system”.
  5. 2:07 pm, call: the voice agent says the credit is already applied.
No AI model sits between the action and the voice context. Actions and system events reach the recompiled context in under 10 seconds.
Niadra never writes to a system of record. The agent acts, with its own credentials. To send the outcome back to your CRM, consume the action.recorded and open_item.closed webhooks.

Next steps

Internal agents

the full guide to the billing agent.

Webhooks from your systems

mapping and authentication.

Read an object

derived state and open items.