These docs describe the target Fibric platform contract and proposed developer experience. Public Fibric CLI, API endpoints, and SDK packages are not yet available. All present-tense API, CLI, SDK, tenancy, security, retention, retry, and pricing language below is normative target language, not a statement that the surface is callable or commercially available today. Commands, package names, URLs, responses, limits, and timelines are reference examples unless a page explicitly identifies a deployed BearScope path.
Object reference
This page consolidates proposed object shapes for the target Fibric API. They are design references, not objects served by an available public endpoint. Current BearScope schemas and product paths may differ.
Shared conventions, including authentication, pagination, the Idempotency-Key header, and the error envelope, are defined in the API overview. Error codes are catalogued in Errors.
Shared conventions
Every object the API returns follows the same rules:
- Typed ids. Every id is an opaque string with a type prefix. Never parse anything beyond the prefix; length and alphabet may change within a major version.
- The
objectfield. Every object names its own type, so a consumer can dispatch onobjectwithout inspecting the URL it came from. Lists are"object": "list"with the items indata. - Timestamps. All timestamps are RFC 3339 strings in UTC.
- Tenancy. The server derives
tenant_idandreseller_idfrom the API key and stamps them onto everything it writes. Objects that expose these fields expose them read-only; nothing in a request body can widen them. See Tenancy & isolation. - Additive evolution. New fields appear within the major version without notice; unknown fields must be ignored. Removals and renames wait for a major version. See API versioning.
| Object | object value | Id prefix | Endpoint page |
|---|---|---|---|
| Envelope (event) | event | ev_ | Events API |
| Operator | operator | op_ | Operators API |
| Connector | connector | cn_ | Connectors API |
| Capability | none (a value, not a resource) | none | Capabilities |
| Plan | execution_plan | pl_ | Actions & plans API |
| Action | action | act_ | Actions & plans API |
| Receipt | receipt | rc_ | Receipts API |
| Guardrail | guardrail_policy | grd_ | Guardrails API |
| Tenant | tenant | t_ | Tenants API |
| Webhook endpoint | webhook_endpoint | whk_ | Webhooks API |
| API key | api_key | key_ | API keys |
How objects relate
One thread of work touches most of these objects in a fixed order. An event arrives and is stamped with a correlation_id. An operator subscribed to its event_type proposes a plan of actions, each carrying its entity_key and idempotency_key. The executor disposes each action under the matching guardrail rules, and every disposition, applied, blocked, alerted, or deduplicated, appends a receipt. The correlation_id is present on every object in the chain, so any one of them recovers the whole story.
event ev_3a91c7 (correlation_id: co_51d2e8)
└─ plan pl_7c1a (operator op_8f2a1c, status: proposed)
├─ action act_91d0 (order.hold, verdict ALLOW) ─> receipt rc_5b21 (applied)
└─ action act_91d1 (order.notify, verdict ALERT) ─> receipt rc_5b22 (awaiting_approval)
connector cn_7d2f4a fulfills order.hold / order.notify for both actions
guardrail grd_3c90e1 supplied the rules the verdicts cite
webhook_endpoint whk_6b3e0d delivered plan.proposed and action.needs_approval
api_key key_4e91b2 authenticated the requests; request_id lands on each receipt
Two navigation rules follow. To go forward from a cause, filter by correlation_id: GET /v1/receipts?filters and the Search API both accept it. To go backward from an effect, follow the id fields: a receipt names its action_id, plan_id, event_id, and operator_id directly, so an auditor starting from one receipt needs no search at all.
Envelope (event)
The one canonical event for everything. A commerce webhook, an MQTT temperature reading, a cron tick, and an operator's own output all become the same shape; this is what makes the platform vertical-agnostic. The API's event object is the kernel's EventEnvelope plus the server-assigned read fields. See the event envelope for the concept.
| Field | Type | Description |
|---|---|---|
id | string | Unique identifier, prefixed ev_. Assigned by the server at ingestion. |
object | string | Always event. |
reseller_id | string or null | The reseller the tenant belongs to; null means Fibric-direct. Present on every envelope, stamped from the key. |
tenant_id | string | The owning tenant, stamped from the key. Read-only. |
workspace_id | string or null | The workspace within the tenant, or null for tenant-wide events. |
source | string | What produced the event: a connector id such as magento, a gateway such as bacnet-gw-7, cron, or operator:<name> for an operator's own output. |
event_type | string | Dot-delimited noun.verb type, for example order.updated or hvac.zone.fault. Operators subscribe by glob over this field. |
correlation_id | string | Threads one piece of work across events, plans, actions, and receipts. Generated if not supplied at ingestion. |
payload | object | The event body. Shape is source-defined; the convention is an entity reference ({ "kind", "id" }) plus the source fields. |
agent_id | string or null | The operator that produced this event, when the source is an operator. |
session_id | string or null | Groups events belonging to one interactive session, when there is one. |
received_at | string | RFC 3339 timestamp the server accepted the envelope. |
plan_ids | string[] | Plans this event caused, populated as operators respond. Empty for events no operator acted on. |
{
"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"]
}
Operator
A named AI worker with a goal, a fixed capability allowlist, and the sense-reason-propose loop. An operator never acts directly: it proposes plans, and the deterministic executor disposes them. See Operators for the concept.
| Field | Type | Description |
|---|---|---|
id | string | Unique identifier, prefixed op_. |
object | string | Always operator. |
name | string | The operator's name within the tenant. It appears on every plan and receipt the operator produces. |
status | string | active, paused, or error. A paused operator senses nothing and proposes nothing. |
outcome | string | The goal in plain language. Part of the reviewed contract, not a tunable. |
capabilities | string[] | The complete allowlist of capabilities the operator may sense or propose through. A plan naming a tool outside this list fails validation. |
guardrails | object[] | The trust rules bound to this operator: tool, decision (ALLOW / ALERT / BLOCK), and optional max_value. See Guardrail. |
model | string | A model-router alias such as router:default, never a hardcoded vendor model. Resolved per tenant by the router seam. |
schedule | string or null | Cron expression for scheduled operators; null for purely event-driven or on-demand operators. |
created_at | string | RFC 3339 timestamp of creation. |
last_run | object or null | Summary of the most recent run: run_id, counts of sensed, proposed, and applied, and its timestamp. null before the first run. |
{
"id": "op_8f2a1c",
"object": "operator",
"name": "order-risk",
"status": "active",
"outcome": "No order misses its promised ship date without a hold and a reason on the record.",
"capabilities": ["order.read", "order.hold", "order.notify"],
"guardrails": [
{ "tool": "order.hold", "decision": "ALLOW", "max_value": 500 },
{ "tool": "order.notify", "decision": "ALERT" }
],
"model": "router:default",
"schedule": "*/15 * * * *",
"created_at": "2026-06-10T14:21:03Z",
"last_run": {
"run_id": "run_5b21",
"sensed": 42,
"proposed": 3,
"applied": 2,
"at": "2026-07-02T15:02:11Z"
}
}
Connector
An installed instance of a marketplace listing, bound to one connection's credentials. The connector is where capabilities become concrete: it declares which capabilities it fulfills and which of its tools are side-effecting. See Connectors for the concept and the Connector SDK for authoring.
| Field | Type | Description |
|---|---|---|
id | string | Unique identifier for this installed instance, prefixed cn_. |
object | string | Always connector. |
listing | string | The marketplace listing this instance was installed from, for example cn-magento. |
name | string | Your name for this instance, for example magento-us-store. Multiple instances of one listing are distinguished by name. |
kind | string | saas, hardware, or operator. Operators are connectors too; the kind is metadata, not a different code path. |
transport | string | How the platform talks to it. mcp for all current listings. |
capabilities | string[] | The capabilities this instance fulfills. Operators bind to these, not to the connector directly. |
tools | object[] | The tools the connector exposes: name plus side_effect. Side-effecting tools route through the executor and trust policy; reads do not. |
auth | object | The auth declaration: type (oauth2, api_key, basic, aws_iam, mtls, or none) and a credential hint. Secrets are never returned. |
status | string | connected, degraded, error, or pending_auth. Status transitions can be delivered by webhook. |
created_at | string | RFC 3339 timestamp of installation. |
last_synced_at | string or null | Timestamp of the most recent successful ingest or probe; null before the first. |
{
"id": "cn_7d2f4a",
"object": "connector",
"listing": "cn-magento",
"name": "magento-us-store",
"kind": "saas",
"transport": "mcp",
"capabilities": ["order.read", "order.hold", "order.notify"],
"tools": [
{ "name": "order.read", "side_effect": false },
{ "name": "order.hold", "side_effect": true },
{ "name": "order.notify", "side_effect": true }
],
"auth": { "type": "api_key", "hint": "mg_****41" },
"status": "connected",
"created_at": "2026-06-18T10:02:00Z",
"last_synced_at": "2026-07-02T14:59:40Z"
}
Capability
A capability is a value, not a resource: a dot-delimited noun.verb string naming one governed ability, such as order.hold or conversation.read. It has no id, no object field, and no endpoint of its own; it is the level of indirection that lets an operator require order.hold without knowing whether Magento or Shopify fulfills it. Swapping the fulfilling connector is configuration, not a redeploy. See Capabilities.
| Where it appears | As | Meaning |
|---|---|---|
Operator capabilities | string[] | The allowlist: everything the operator may sense or propose through. Enforced at sense time, plan validation, and disposition. |
Connector capabilities | string[] | What this installed instance fulfills. One connector can fulfill many capabilities; one capability is fulfilled by exactly one bound connector per operator. |
GET /v1/connectors?capability= | query filter | Which installed connectors fulfill a capability, used when binding. |
| Guardrail rules | tool match | Trust rules match on the tool name, which by convention is the capability the tool implements. |
{
"name": "order-risk",
"capabilities": ["order.read", "order.hold"],
"bindings": {
"order.read": "cn_7d2f4a",
"order.hold": "cn_7d2f4a"
}
}
Plan
The kernel's ExecutionPlan: what an operator proposes and the only thing the executor will run. The LLM proposes; the deterministic executor disposes. A plan is validated against the kernel type before it exists as an API object, so every plan you can read was structurally sound. See the Actions & plans API for the approval flow.
| Field | Type | Description |
|---|---|---|
id | string | Unique identifier, prefixed pl_. |
object | string | Always execution_plan. |
operator_id | string | The operator that proposed the plan. |
event_id | string or null | The event that triggered the run, or null for scheduled and on-demand runs. |
status | string | proposed, executing, disposed, vetoed, or expired. |
reasoning | string or null | The operator's stated reasoning, stored with the plan and shown in review queues. |
actions | object[] | The proposed actions, each carrying its verdict from the trust evaluation. |
proposed_at | string | RFC 3339 timestamp of the proposal. |
disposed_at | string or null | Timestamp the plan reached a final state; null while proposed or executing. |
expires_at | string or null | When an unapproved plan expires. An expired plan is receipted as such and never runs. |
{
"id": "pl_7c1a",
"object": "execution_plan",
"operator_id": "op_8f2a1c",
"event_id": "ev_3a91c7",
"status": "proposed",
"reasoning": "SO-10884 is paid, unfulfilled, and two days from its promise with no carrier scan. Hold it and tell the owner.",
"actions": [
{
"id": "act_91d0",
"connector": "cn_7d2f4a",
"tool": "order.hold",
"args": { "order": "SO-10884", "reason": "will miss promised ship date" },
"value": 184.5,
"entity_key": "order:SO-10884",
"idempotency_key": "order-risk:SO-10884:hold",
"verdict": { "decision": "ALLOW", "tier": 1, "rule": "tool:order.hold max_value:500" }
}
],
"proposed_at": "2026-07-02T15:02:09Z",
"disposed_at": null,
"expires_at": "2026-07-05T15:02:09Z"
}
Action
One proposed side effect inside a plan, from proposal through disposition. The target object records a trust decision (ALLOW, ALERT, BLOCK) or DEDUP when a stable key is recognized. Single-flight and idempotency are duplicate-suppression controls within the executor boundary, not universal delivery guarantees; see Single-flight & idempotency.
| Field | Type | Description |
|---|---|---|
id | string | Unique identifier, prefixed act_. Stable from proposal through disposition. |
object | string | Always action. |
plan_id | string | The plan this action belonged to. |
connector | string | The connector instance the tool routes through. |
tool | string | The tool the action invokes, for example order.hold. |
args | object | The validated arguments, unchanged from the proposal. |
value | number, optional | The monetary or physical magnitude, when the tool has one; evaluated against max_value guardrail rules. |
entity_key | string | Single-flight key, conventionally kind:id. The executor serializes all side effects sharing the key. |
idempotency_key | string | Dedup key, conventionally operator:entity:action. A key already applied disposes as DEDUP. |
verdict | object | The trust evaluation: decision, tier, and the rule that matched. |
disposition | string | ALLOW, ALERT, BLOCK, or DEDUP. |
ok | boolean | Whether the disposition completed without error. A BLOCK is ok: false with error: "blocked by trust policy". |
error | string or null | Error detail when ok is false. |
receipt_id | string | The immutable receipt written for this action, refusals included. |
undoable | boolean | true when the tool declares a compensating inverse and the action applied successfully. |
undone | boolean | true after a successful undo. |
disposed_at | string | RFC 3339 timestamp of the disposition. |
{
"id": "act_91d0",
"object": "action",
"plan_id": "pl_7c1a",
"connector": "cn_7d2f4a",
"tool": "order.hold",
"args": { "order": "SO-10884", "reason": "will miss promised ship date" },
"value": 184.5,
"entity_key": "order:SO-10884",
"idempotency_key": "order-risk:SO-10884:hold",
"verdict": { "decision": "ALLOW", "tier": 1, "rule": "tool:order.hold max_value:500" },
"disposition": "ALLOW",
"ok": true,
"error": null,
"receipt_id": "rc_5b21",
"undoable": true,
"undone": false,
"disposed_at": "2026-07-02T15:04:41Z"
}
Receipt
The immutable record of one disposition: the proposal exactly as the operator made it, the policy decision, the keys, who approved, and the outcome. Receipts are append-only; there is no write scope for them because only the kernel appends. Refusals and dedups are receipted with the same fidelity as applied actions. See Receipts & audit.
| Field | Type | Description |
|---|---|---|
id | string | Unique identifier, prefixed rc_. |
object | string | Always receipt. |
reseller_id | string or null | Stamped from the tenant, on every row. |
tenant_id | string | The owning tenant. |
operator_id | string | The operator whose plan produced this disposition. |
operator | string | The operator's name at disposition time, denormalized for readable exports. |
event_id | string or null | The triggering event, threading the receipt back to its cause. |
plan_id | string | The plan the action belonged to. |
action_id | string | The action this receipt records. |
connector | string | The connector instance the action routed through. |
tool | string | The tool invoked, or refused. |
entity_key | string | The single-flight key the disposition held. |
idempotency_key | string | The dedup key the disposition checked. |
verdict | object | The trust evaluation: decision, tier, and the matching rule. |
outcome | string | applied, blocked, deduplicated, failed, or awaiting_approval. |
approver | string or null | Who approved an ALERT action; null for unattended dispositions. |
request_id | string | The API request that caused the disposition, for correlation with your own logs. |
at | string | RFC 3339 timestamp of the disposition. |
{
"id": "rc_5b21",
"object": "receipt",
"reseller_id": null,
"tenant_id": "t_8f2ac901",
"operator_id": "op_8f2a1c",
"operator": "order-risk",
"event_id": "ev_3a91c7",
"plan_id": "pl_7c1a",
"action_id": "act_91d0",
"connector": "cn_7d2f4a",
"tool": "order.hold",
"entity_key": "order:SO-10884",
"idempotency_key": "order-risk:SO-10884:hold",
"verdict": { "decision": "ALLOW", "tier": 1, "rule": "tool:order.hold max_value:500" },
"outcome": "applied",
"approver": null,
"request_id": "req_9b3e21f0",
"at": "2026-07-02T15:04:41Z"
}
Guardrail
A named, versioned trust policy: the deterministic half of the loop. Rules match on connector and tool, optionally constrain by value, and yield a decision. Evaluation is default-closed: no matching rule is BLOCK, a matching rule with a failed constraint is BLOCK, and among passing matches ALERT wins over ALLOW. See the Guardrails API and Trust tiers.
| Field | Type | Description |
|---|---|---|
id | string | Unique identifier, prefixed grd_. |
object | string | Always guardrail_policy. |
name | string | The policy's name within the tenant. |
description | string or null | What the policy is for, in plain language. |
status | string | active or disabled. A disabled policy contributes no rules, which under default-closed evaluation means less is allowed, never more. |
version | integer | Monotonic version, incremented on every rules change. Receipts record the version that evaluated them. |
rules | object[] | The rules, evaluated as a set. Each rule: optional connector and tool matchers (absent means any), optional max_value constraint, and a decision of ALLOW, ALERT, or BLOCK. |
created_at | string | RFC 3339 timestamp of creation. |
updated_at | string | Timestamp of the most recent change. |
{
"id": "grd_3c90e1",
"object": "guardrail_policy",
"name": "refund-ceiling",
"description": "Refunds auto-run to $250; larger refunds page a human.",
"status": "active",
"version": 3,
"rules": [
{ "tool": "order.refund", "decision": "ALLOW", "max_value": 250 },
{ "tool": "order.refund", "decision": "ALERT" }
],
"created_at": "2026-05-14T10:00:00Z",
"updated_at": "2026-06-30T16:42:12Z"
}
Tenant
The isolation boundary. Every envelope, plan, action, and receipt carries the tenant's id, and a key belongs to exactly one tenant; another tenant's ids read as 404 not_found, not 403. Workspaces subdivide a tenant for scoping keys and organizing operators. See Tenancy & isolation and the Tenants API.
| Field | Type | Description |
|---|---|---|
id | string | Unique identifier, prefixed t_. |
object | string | Always tenant. |
name | string | Display name. |
slug | string | URL-safe identifier, unique across the platform. |
reseller_id | string or null | The reseller the tenant belongs to; null means Fibric-direct. |
plan | string | The billing plan, for example early_access or team. |
workspaces | object[] | The tenant's workspaces: id (prefixed ws_), name, created_at. Keys may be pinned to one workspace; see tenant and workspace scoping. |
created_at | string | RFC 3339 timestamp of creation. |
{
"id": "t_8f2ac901",
"object": "tenant",
"name": "Acme Fulfillment",
"slug": "acme-fulfillment",
"reseller_id": null,
"plan": "early_access",
"workspaces": [
{ "id": "ws_2d81f0", "name": "us-store", "created_at": "2026-05-01T10:00:00Z" },
{ "id": "ws_9a44c2", "name": "eu-store", "created_at": "2026-06-12T09:30:00Z" }
],
"created_at": "2026-04-01T12:00:00Z"
}
Webhook endpoint
A registered HTTPS destination for signed deliveries: plan proposals, action dispositions, connector status changes, and receipts, pushed as they happen. Deliveries wrap the full API objects defined on this page, so a consumer rarely needs a follow-up fetch. Signature verification, the retry schedule, and the delivery object are covered in the Webhooks API.
| Field | Type | Description |
|---|---|---|
id | string | Unique identifier, prefixed whk_. |
object | string | Always webhook_endpoint. |
url | string | The HTTPS destination. Plain HTTP is rejected at creation. |
types | string[] | Subscribed delivery types, for example plan.proposed or action.needs_approval. |
status | string | active, disabled (by you), or suspended (by Fibric, after sustained delivery failure). |
secret | string | Signing secret, prefixed whsec_. Returned in full at creation and rotation only; reads return a hint. Used to verify Fibric-Signature. |
created_at | string | RFC 3339 timestamp of creation. |
last_delivery_at | string or null | Timestamp of the most recent delivery attempt, successful or not. |
{
"id": "whk_6b3e0d",
"object": "webhook_endpoint",
"url": "https://ops.example.com/fibric/webhook",
"types": ["plan.proposed", "action.needs_approval", "connector.status_changed"],
"status": "active",
"secret": "whsec_5f2e8a1c9b0d7e4f6a3b",
"created_at": "2026-07-02T15:30:00Z",
"last_delivery_at": null
}
API key
The target credential object proves identity, names one tenant, and carries scopes. The proposed creation flow shows the full secret only at creation and retains a display hint. No public Fibric key service is available today; see Authentication.
| Field | Type | Description |
|---|---|---|
id | string | Unique identifier, prefixed key_. This is the id you revoke; it is not the secret. |
object | string | Always api_key. |
name | string | Your label for the workload holding the key, for example ingest-gateway. |
mode | string | live or test. The secret's prefix (sk_live_ / sk_test_) matches. Test keys operate on an isolated test partition. |
role | string or null | The role preset the key was created from (read_only, ingest, operate, admin), or null for hand-assembled scopes. The expanded scopes are stored on the key; later role changes never alter existing keys. |
scopes | string[] | The granted scopes, for example events:write. The grant is the union; there is no implicit escalation. |
workspace_id | string or null | Workspace pin. A pinned key behaves as if the tenant contained only that workspace; null sees the whole tenant. |
hint | string | Display hint for the secret, for example sk_live_…41f7. The full secret is never readable after creation. |
status | string | active or revoked. Revocation is immediate and permanent. |
last_used_at | string or null | Timestamp of the most recent authenticated request; null if never used. |
created_at | string | RFC 3339 timestamp of creation. |
revoked_at | string or null | Timestamp of revocation; null while active. |
{
"id": "key_4e91b2",
"object": "api_key",
"name": "ingest-gateway",
"mode": "live",
"role": "ingest",
"scopes": ["events:write"],
"workspace_id": null,
"hint": "sk_live_…41f7",
"status": "active",
"last_used_at": "2026-07-02T15:11:02Z",
"created_at": "2026-05-20T09:00:00Z",
"revoked_at": null
}