Fibric. Docs fibric.io →
v0.9 · preview
Reference

Events API

Events are how systems sense into Fibric. Every occurrence, whether a commerce webhook, a sensor reading, a cron tick, or an operator's own output, is normalized into one canonical EventEnvelope before anything reasons over it. This page documents ingesting an envelope, listing stored events, and retrieving one by id.

Conventions shared by every endpoint on this page, including authentication, pagination, the Idempotency-Key header, and the error envelope, are defined in the API overview. Error codes are catalogued in Errors.

The event object

The stored event exposes the kernel envelope's fields verbatim, plus the API metadata the server adds at ingest. The API id (prefix ev_) is the public form of the kernel envelope's event_id. The envelope shape is defined in packages/kernel/src/envelope.ts and explained in The event envelope.

idstring

Unique identifier for the event, prefixed ev_. Assigned by the server at ingest.

objectstring

Always event.

reseller_idstring or null

The reseller the tenant belongs to. null means Fibric-direct, no reseller. Present on every envelope; stamped from your API key, never from the request body.

tenant_idstring

The tenant that owns this event. Stamped from your API key. See Tenancy & isolation.

workspace_idstring or null

Optional workspace partition within the tenant. null when the tenant does not use workspaces.

sourcestring

Where the event came from: a connector instance (magento), a hardware gateway (bacnet-gw-7), a schedule (cron), or an operator's own output (operator:order-risk).

event_typestring

Dotted noun.verb type, for example order.created or hvac.zone.fault. Operators subscribe to event types.

correlation_idstring

Threads related envelopes together across the sense, reason, and act loop. Supplied by the caller or generated at ingest.

payloadobject

The event body, arbitrary JSON from the source system. Payloads must carry real values from a real source; the platform tags anything else so a placeholder can never read as a governed metric.

agent_idstring or null

The operator that emitted this envelope, when the source is an operator. null for external events.

session_idstring or null

The reasoning session the envelope belongs to, when one exists. null for external events.

received_atstring

RFC 3339 timestamp of when the API accepted the event. Server-assigned.

plan_idsstring[]

Execution plans proposed off this event, if any. Follow each id into the Actions & plans API.

json · the event object
{
  "id": "ev_3a91c7",
  "object": "event",
  "reseller_id": null,
  "tenant_id": "t_8f2ac901",
  "workspace_id": null,
  "source": "magento",
  "event_type": "order.updated",
  "correlation_id": "co_51d2e8",
  "payload": {
    "order": "SO-10884",
    "status": "open",
    "ship_by": "2026-07-06",
    "carrier_scanned": false
  },
  "agent_id": null,
  "session_id": null,
  "received_at": "2026-07-02T14:58:01Z",
  "plan_ids": ["pl_7c1a"]
}
!
Tenancy fields are server-stamped

reseller_id and tenant_id are derived from the API key on every request. You may omit them from the body. If you include them and they do not match the key, the request is rejected with 403 tenant_mismatch. There is no body field that reaches another tenant.

POST

Ingest an event

POST/v1/eventsscope events:write

Accepts one envelope. The server assigns id and received_at, stamps reseller_id and tenant_id from the key, generates correlation_id if you did not supply one, and routes the event to any operator subscribed to its event_type. Ingestion never acts by itself: an event can only cause an operator to propose a plan, and the executor disposes that plan under policy.

Send an Idempotency-Key header on every ingest. Retrying with the same key returns the original stored envelope instead of ingesting a duplicate. This is what makes a webhook retry storm, or a 657-message flood, absorb into one event rather than multiply.

sourcerequiredstring · body

The system the event came from, for example magento, kustomer, bacnet-gw-7, or cron.

event_typerequiredstring · body

Dotted noun.verb event type, for example order.updated. Validated against a lowercase dotted-segment pattern; anything else fails with 400 invalid_parameter.

payloadobject · body

The event body. Defaults to an empty object. Maximum size 256 KB; larger payloads are rejected with 400 invalid_request.

correlation_idstring · body

Supply your own value to thread this event with related envelopes. Generated by the server when omitted.

workspace_idstring · body

Workspace partition within the tenant. Defaults to null.

agent_idstring · body

Set when an operator emits the event through the API on its own behalf. Defaults to null.

session_idstring · body

Reasoning session identifier, when one exists. Defaults to null.

curl
curl -X POST https://api.fibric.io/v1/events \
  -H "Authorization: Bearer $FIBRIC_KEY" \
  -H "Content-Type: application/json" \
  -H "Idempotency-Key: magento:SO-10884:v7" \
  -d '{
    "source": "magento",
    "event_type": "order.updated",
    "payload": {
      "order": "SO-10884",
      "status": "open",
      "ship_by": "2026-07-06",
      "carrier_scanned": false
    }
  }'
202 Accepted Response
json
{
  "id": "ev_3a91c7",
  "object": "event",
  "reseller_id": null,
  "tenant_id": "t_8f2ac901",
  "workspace_id": null,
  "source": "magento",
  "event_type": "order.updated",
  "correlation_id": "co_51d2e8",
  "payload": { "order": "SO-10884", "status": "open", "ship_by": "2026-07-06", "carrier_scanned": false },
  "agent_id": null,
  "session_id": null,
  "received_at": "2026-07-02T14:58:01Z",
  "plan_ids": []
}
i
Deduplicated, not rejected

Replaying an Idempotency-Key the server has already seen, with an identical body, returns 200 and the original stored envelope. Replaying the same key with a different body returns 409 idempotency_conflict; see Errors for the semantics.

Error cases:

StatusCodeWhen
400missing_parametersource or event_type is absent.
400invalid_parameterevent_type does not match the dotted noun.verb pattern, or payload is not an object.
403tenant_mismatchThe body carried a tenant_id or reseller_id that does not match the key.
409idempotency_conflictThe Idempotency-Key was already used with a different body.
429rate_limitedThe event-ingest budget is exhausted. Honor Retry-After; see Rate limits & quotas.
GET

List events

GET/v1/eventsscope events:read

Returns events for the authenticated tenant, newest first, cursor-paginated. Filters combine with AND. The entity filter matches events through the plans they triggered: an event is indexed by the entity_key of every action proposed off it, which lets you reconstruct everything that ever touched one order, one room, or one asset.

sourcestring · query

Only events from this source, for example magento or operator:order-risk.

event_typestring · query

Only events of this type, for example order.updated.

entitystring · query

Only events whose proposed actions carried this entity_key, for example order:SO-10884. Events that triggered no plan do not match.

sincestring · query

Only events received at or after this RFC 3339 timestamp, for example 2026-07-01T00:00:00Z.

limitinteger · query

Page size, 1–100. Defaults to 20.

cursorstring · query

Pagination cursor from a previous response's next_cursor.

curl
curl "https://api.fibric.io/v1/events?source=magento&entity=order:SO-10884&since=2026-07-01T00:00:00Z" \
  -H "Authorization: Bearer $FIBRIC_KEY"
200 OK Response
json
{
  "object": "list",
  "data": [
    {
      "id": "ev_3a91c7",
      "object": "event",
      "source": "magento",
      "event_type": "order.updated",
      "correlation_id": "co_51d2e8",
      "received_at": "2026-07-02T14:58:01Z",
      "plan_ids": ["pl_7c1a"]
    },
    {
      "id": "ev_3a90b2",
      "object": "event",
      "source": "magento",
      "event_type": "order.created",
      "correlation_id": "co_51d2e8",
      "received_at": "2026-07-01T09:12:44Z",
      "plan_ids": []
    }
  ],
  "has_more": true,
  "next_cursor": "cur_eyJpZCI6ImV2XzNhOTBiMiJ9"
}

List responses omit payload and the tenancy fields for brevity; retrieve a single event for the full envelope.

Error cases:

StatusCodeWhen
400invalid_parametersince is not RFC 3339, or limit is outside 1–100.
400invalid_cursorThe cursor is malformed or was issued for a different query.
GET

Retrieve an event

GET/v1/events/{event_id}scope events:read

Returns the full stored envelope, including payload and the tenancy fields, plus the ids of any plans proposed off it. An id that belongs to another tenant reads as 404 not_found; existence is never disclosed across the wall.

event_idrequiredstring · path

The event id, for example ev_3a91c7.

curl
curl https://api.fibric.io/v1/events/ev_3a91c7 \
  -H "Authorization: Bearer $FIBRIC_KEY"
200 OK Response
json
{
  "id": "ev_3a91c7",
  "object": "event",
  "reseller_id": null,
  "tenant_id": "t_8f2ac901",
  "workspace_id": null,
  "source": "magento",
  "event_type": "order.updated",
  "correlation_id": "co_51d2e8",
  "payload": {
    "order": "SO-10884",
    "status": "open",
    "ship_by": "2026-07-06",
    "carrier_scanned": false
  },
  "agent_id": null,
  "session_id": null,
  "received_at": "2026-07-02T14:58:01Z",
  "plan_ids": ["pl_7c1a"]
}

Error cases:

StatusCodeWhen
404not_foundNo event with this id exists for the authenticated tenant.

Retention and immutability

Stored events are immutable. There is no update or delete endpoint: an envelope, once accepted, is part of the audit trail that receipts reference. During early access, events are retained for the life of the tenant; retention windows are finalized with each team during onboarding.