Status: Mixed. The publish-and-call flow is available today; the fabric upgrade path is developer preview.For teams that already run a Praxa custom agent inside their product and want more than one fixed agent’s worth of tools, budget, and approvals — with approvals showing up in your own product instead of Praxa’s dashboard. If you already embed a Praxa custom agent, you’re on the first wedge of the fabric already. This guide covers what you have today, what the fabric adds, and a full worked example — a support-ticket triage agent — showing both.
Today: the custom-agent surface
Status: Available today.aura_agent_*deployment keys andPOST /api/custom-agent-runare shipped, working code, not a roadmap description.
- Publish. Build the agent in the agent builder (instructions, knowledge, bound connectors), publish a version, and Praxa mints a deployment credential for the External API channel — an
aura_agent_*key — tied to onedeploymentId. - Call it. Your backend calls
POST /api/custom-agent-runwith that key and a stableexternalSessionIdyou generate — a ticket id, a customer id, whatever concept you already key sessions on — so repeated calls land in the same conversation. - Approvals. Any step that would send, schedule, change, or purchase through a bound connector doesn’t fire automatically. It produces a pending action instead — the exact provider, action, and arguments, frozen — reviewed inside Praxa’s own agent workspace by someone with review access on that agent.
- Receipts. Conversations, per-agent operational analytics, and cost/charge/contribution-margin — all inside Praxa’s dashboard.
The fabric upgrade
Status: Developer preview./v1/executeand the rest of/v1/*are developer preview: the wire contracts are stable and published, but no public endpoint serves them yet.task,context,tools,policy,delivery,mode,run_id,action_digest,decision, and theIdempotency-Keyheader are the vocabulary the design spec (§3.1) gives;toolsas an{ allow, deny }filter is independently confirmed against the published wire schema. Anything else shown below (webhook registration fields, the keys insidepolicy) is a reasonable illustration, not a frozen contract — seeapi/execute.md.
- Instead of (or alongside) one fixed agent, you call
POST /v1/executewith a task, a tool allowlist, and a policy (risk tier plus budget cap) — under apraxa_sk_tenant key instead of anaura_agent_*deployment credential. Seekeys-and-access/api-keys.mdfor how the two key families differ and coexist —aura_agent_*isn’t being retired. - Approvals move into your product. Register a webhook once (
POST /v1/webhooks), and a pending action reaches your backend directly as a signedapproval.requiredevent instead of sitting in Praxa’s dashboard. You render it in your own UI and post the decision back toPOST /v1/runs/:id/approve. - The trust rule doesn’t change, only where you see it: an approval only ever matches the exact action it was issued for.
Worked example: support-ticket triage
The problem. TicketFlow’s support agent drafts replies to incoming tickets and, for routine ones, sends them. Nobody wants it sending anything unsupervised — every outbound reply needs a human’s okay — and TicketFlow’s ops lead doesn’t want to leave their own helpdesk to give it. What you build.- Today: one custom agent (“Ticket Triage”), instructions for tone and scope, a connector bound for sending replies, published, with a deployment credential.
- Upgrade: the same logic as an execute-API task — a tool allowlist of
read_ticket_history,draft_reply,send_reply; a budget cap;send_replyclassified to require approval — plus one webhook endpoint registered in TicketFlow’s own backend.
externalSessionId is TicketFlow’s own identifier (8–200 characters, letters/numbers/_.:-). The agent drafts a reply. Because the deployment’s connector binding can send messages, that step parks as a pending action instead of firing — reviewed today inside Praxa’s own agent workspace, approved or denied as-is, never edited in place.
Upgrade — TicketFlow registers a webhook once:
/v1/execute per ticket instead of /api/custom-agent-run:
{ "run_id": "run_01j9tcket48213000000001" }. read_ticket_history and draft_reply run on their own. send_reply still parks — same rule as today — but now the approval.required event lands on TicketFlow’s own webhook, HMAC-signed and retried if their endpoint is briefly down, instead of sitting in Praxa’s dashboard. When their ops lead approves it in TicketFlow’s own queue, TicketFlow’s backend posts the decision back:
send_reply, and the decision and digest that authorized the send, rolled into TicketFlow’s tenant-level usage — see api/runs.md and api/usage.md for exactly what’s confirmed on the wire today versus what’s still firming up. A fuller exportable audit trail is on the roadmap, not shipped.
See also
keys-and-access/api-keys.md— creating and scopingpraxa_sk_keyskeys-and-access/scopes-and-tenancy.md— what a key’s scope actually constrainsapi/execute.md— the full/v1/executereference, including the mode:“turn”/mode:“task” contract-status noteapi/approvals.md— theapproval.required→approvecontract in fullapi/webhooks.md— webhook registration and delivery, including what’s still unconfirmed