> ## Documentation Index
> Fetch the complete documentation index at: https://docs.praxa.io/llms.txt
> Use this file to discover all available pages before exploring further.

# Praxa Execution Fabric: Quickstart

> This guide has two tracks. Track 1 calls a real endpoint you can use today if you have published a custom agent. Track 2 previews the shape of the fabric's e

This guide has two tracks. Track 1 calls a real endpoint you can use today if you have published a custom agent. Track 2 previews the shape of the fabric's `execute()` API, which is contract-stable but not yet serving traffic.

## Track 1: Call a published agent today

> **Status:** Available today.

If you have published an agent on Praxa's custom-agent platform, you already have an `aura_agent_*` deployment key. Use it to run that agent from your own backend.

### Request

```bash theme={null}
curl -X POST https://api.praxa.io/api/custom-agent-run \
  -H "Authorization: Bearer aura_agent_xxxxxxxxxxxxxxxxxxxx" \
  -H "Content-Type: application/json" \
  -d '{
    "message": "Summarize the last five support tickets for this customer.",
    "externalSessionId": "customer-482910"
  }'
```

```typescript theme={null}
const response = await fetch("https://api.praxa.io/api/custom-agent-run", {
  method: "POST",
  headers: {
    Authorization: `Bearer ${process.env.PRAXA_AGENT_KEY}`,
    "Content-Type": "application/json",
  },
  body: JSON.stringify({
    message: "Summarize the last five support tickets for this customer.",
    externalSessionId: "customer-482910",
  }),
});

if (!response.ok) {
  throw new Error(`Agent run failed: ${response.status}`);
}

const result = await response.json();
```

### Notes

* `externalSessionId` is yours to assign. Pass the same value for the same end user on every call and Praxa keeps that conversation isolated and continuous across calls. Use a distinct value per end user.
* The key authenticates one specific agent deployment. Keep it on your backend. Never ship it to a browser or a mobile client.
* If the agent tries to take an action that sends, schedules, changes, or purchases something through a connector, that action still requires approval under the same server-side rules as the in-app experience. A read-only question-and-answer agent will not hit this path.
* These fields cover text execution. If your agent also uses knowledge ingestion, memory, or automations, those are separate endpoints in the custom-agent API.

## Track 2: Your first `execute()` run

> **Status:** Developer preview — the Fabric v1 API described here is contract-stable but not yet serving traffic. Contact us to join the first partner cohort.

This is what calling the fabric directly will look like once the preview opens. The request and event shapes below come from the published design. There is no SDK yet, so the examples use plain HTTP and SSE.

### Start a run

```bash theme={null}
curl -X POST https://api.praxa.io/v1/execute \
  -H "Authorization: Bearer praxa_sk_xxxxxxxxxxxxxxxxxxxx" \
  -H "Content-Type: application/json" \
  -H "Idempotency-Key: 5f2b1e3a-2b3e-4a6d-9c1a-3a2b1e3a2b3e" \
  -d '{
    "task": "Research three competitors and draft a one-page comparison.",
    "context": { "notes": "Focus on pricing and support SLAs." },
    "tools": { "allow": ["web_search", "document_write"] },
    "policy": {
      "riskCeiling": "human_approval",
      "budgetCap": { "amountMicros": 2000000, "currency": "USD" },
      "toolAllowlist": ["web_search", "document_write"]
    },
    "delivery": { "mode": "turn" }
  }'
```

```typescript theme={null}
const response = await fetch("https://api.praxa.io/v1/execute", {
  method: "POST",
  headers: {
    Authorization: `Bearer ${process.env.PRAXA_SK_KEY}`,
    "Content-Type": "application/json",
    Accept: "text/event-stream",
    "X-AI-Platform-Version": "v1",
    "Idempotency-Key": crypto.randomUUID(),
  },
  body: JSON.stringify({
    task: "Research three competitors and draft a one-page comparison.",
    context: { notes: "Focus on pricing and support SLAs." },
    tools: { allow: ["web_search", "document_write"] },
    policy: {
      riskCeiling: "human_approval",
      budgetCap: { amountMicros: 2_000_000, currency: "USD" },
      toolAllowlist: ["web_search", "document_write"],
    },
    delivery: { mode: "turn" },
  }),
});

if (!response.ok || !response.body) {
  throw new Error(`Execute request failed: ${response.status}`);
}

const reader = response.body.getReader();
const decoder = new TextDecoder();
let buffer = "";

while (true) {
  const { value, done } = await reader.read();
  if (done) break;
  buffer += decoder.decode(value, { stream: true });

  for (const line of buffer.split("\n")) {
    if (!line.startsWith("data:")) continue;
    const payload = line.slice(5).trim();
    if (payload === "[DONE]") continue;
    const event = JSON.parse(payload);

    if (event.type === "approval.required") {
      // Show event.summary to a human, then resolve it:
      // POST /v1/runs/:id/approve  { "action_digest": event.action_digest, "decision": "approved" }
    }
    if (event.type === "response.final" || event.type === "request.failed") {
      // Terminal event. Stop reading.
    }
  }
}
```

### `mode: "turn"` vs. `mode: "task"`

The example above uses `delivery: { mode: "turn" }`: a synchronous call that streams events back on the same connection and ends when the run does. For longer or open-ended work, use `delivery: { mode: "task" }` instead. The call returns a run id right away, and you follow progress with:

* `GET /v1/runs/:id`: current state.
* `GET /v1/runs/:id/events`: the same event stream, resumable with a `Last-Event-ID` header.
* `POST /v1/webhooks`: register an endpoint so Praxa pushes events to you instead of you polling.

### Resolving an approval

If a step needs sign-off, the event feed emits `approval.required` with a summary and an `action_digest`. Post the digest back with your decision:

```bash theme={null}
curl -X POST https://api.praxa.io/v1/runs/run_abc123/approve \
  -H "Authorization: Bearer praxa_sk_xxxxxxxxxxxxxxxxxxxx" \
  -H "Content-Type: application/json" \
  -d '{ "action_digest": "...", "decision": "approved" }'
```

`decision`'s values mirror Praxa's internal approval-status enum (`approved`/`denied`); the public contract will confirm them at launch. The run resumes from exactly the step it paused on. See [Concepts](/fabric/getting-started/concepts) for the fail-closed rules that govern this.

### After the run

Every finished run has a receipt: what ran, which policy version applied, who approved what, and how the result checked against your acceptance criteria. Usage and spend for your tenant are available at `GET /v1/usage`.

## What's next

* Read [Concepts](/fabric/getting-started/concepts) for the full vocabulary.
* Read [Overview](/fabric/getting-started/overview) for the product framing.
* Want into the preview cohort? Contact us.
