# API: Agent platform

| Method | Path | What it does | Scope |
|---|---|---|---|
| DELETE | `/v1/agent-examples/:id` | Forget an example | `agents:write` |
| GET | `/v1/agent-org-chart` | Agents by the teammate they report to | `agents:read` |
| GET | `/v1/agent-templates` | Browse templates: built-in, shared by your team and imported, by category, role and search | `agents:read` |
| DELETE | `/v1/agent-templates/:key` | Archive a team or imported template (agents made from it keep working) | `agents:write` |
| GET | `/v1/agent-templates/:key` | A template: goal, steps, best for, inputs, outputs, integrations with access, approvals, when it runs, what it replaces, FAQ | `agents:read` |
| GET | `/v1/agent-templates/:key/export` | Export a template as a package (spec and its skills) to reuse in another organization or install | `agents:read` |
| POST | `/v1/agent-templates/import` | Import a template package; its skills are added when missing | `agents:write` |
| POST | `/v1/agents` | Create a draft agent, from a template or a spec | `agents:write` |
| DELETE | `/v1/agents/:id` | Archive an agent (its versions and runs are kept) | `agents:write` |
| GET | `/v1/agents/:id` | An agent: profile, draft spec, integrations and access it needs, current version | `agents:read` |
| PATCH | `/v1/agents/:id` | Edit an agent's profile or draft (published versions don't change) | `agents:write` |
| PUT | `/v1/agents/:id/autonomy` | How much the agent does without a person: approve_all, approve_first, auto_named (with tools), autopilot. Guardrails, outside-content holds and destructive changes apply at every level. (web app only) | `agents:write` |
| PUT | `/v1/agents/:id/budget` | This agent's own daily and monthly model budgets (USD; null removes one). Over budget, its runs pause. (web app only) | `settings:write` |
| POST | `/v1/agents/:id/code-steps` | Have the model write a code step for a repeated task: it's test-run in the sandbox on your sample input and added to the draft (a person publishes it; then it runs without the model) | `agents:write` |
| GET | `/v1/agents/:id/diff` | What changed between two versions (or a version and the draft: to=draft) | `agents:read` |
| GET | `/v1/agents/:id/evals` | The agent's eval cases and recent suite runs | `agents:read` |
| POST | `/v1/agents/:id/evals` | Add (or replace, by name) an eval case: an input and what the run must do (owners: cases are the publish gate) | `settings:write` |
| DELETE | `/v1/agents/:id/evals/:caseId` | Remove an eval case (owners) | `settings:write` |
| POST | `/v1/agents/:id/evals/run` | Run the eval suite as dry runs (nothing is written or sent) on the draft, the current version, or a version | `agents:write` |
| GET | `/v1/agents/:id/examples` | What the agent learned from people's edits and rejections | `agents:read` |
| DELETE | `/v1/agents/:id/experiment` | Stop the experiment (new runs use the current version) (web app only) | `settings:write` |
| GET | `/v1/agents/:id/experiment` | The running (or decided) experiment and each version's metric so far | `agents:read` |
| PUT | `/v1/agents/:id/experiment` | A/B test two versions on live runs: the split, the metric (outcome or qa_score), runs needed, and whether the winner is promoted (web app only) | `settings:write` |
| POST | `/v1/agents/:id/publish` | Publish the draft as a new immutable version, granting the access levels listed (default: everything its tools need) | `agents:write` |
| POST | `/v1/agents/:id/rollback` | Roll back: publish an earlier version again as the newest | `agents:write` |
| POST | `/v1/agents/:id/share` | Share the agent's current version as a template for the team | `agents:write` |
| POST | `/v1/agents/:id/state` | Set the agent live, pause it, or take it back to ready | `agents:write` |
| GET | `/v1/agents/:id/telemetry` | One agent's telemetry per version (compare versions) | `agents:read` |
| POST | `/v1/agents/:id/test-run` | Run the draft once now, step by step. Every write it would make waits for your approval. | `agents:write` |
| GET | `/v1/agents/:id/triggers` | When the agent runs: schedules, events and webhook URLs | `agents:read` |
| POST | `/v1/agents/:id/triggers` | Add a trigger. Webhook triggers return their URL and secret once. | `agents:write` |
| GET | `/v1/agents/:id/versions` | Published versions, newest first | `agents:read` |
| POST | `/v1/agents/draft-from-goal` | Describe a goal; the model drafts an agent from the registered tools (validated). It's saved as a draft for you to review, test and publish. | `agents:write` |
| GET | `/v1/approvals` | The approval inbox: pending (default) or completed items, by agent, kind or assignee (assignee=me) | `agents:read` |
| GET | `/v1/approvals/:id` | One approval item | `agents:read` |
| POST | `/v1/approvals/:id/assign` | Give a pending item to someone else to decide (web app only) | `approvals:write` |
| POST | `/v1/approvals/:id/decide` | Approve (all calls, some, or edited) or reject an item. People in the web app only; send the version you saw. (web app only) | `approvals:write` |
| GET | `/v1/events` | Recent platform events (what triggers and webhooks see) | `agents:read` |
| GET | `/v1/home` | Home: my open tasks, approvals waiting, recent activity on my records, pipeline numbers, live agents | `search:read` |
| GET | `/v1/push/key` | The Web Push public key (VAPID), or null when push isn't set up (web app only) | — |
| DELETE | `/v1/push/subscriptions` | Unsubscribe this device (web app only) | — |
| POST | `/v1/push/subscriptions` | Subscribe this device to push for approvals (the browser's push endpoint only) (web app only) | — |
| GET | `/v1/runs/:id/scorecard` | The run's QA scorecard: checks and the model judge's score against the spec's rubric | `agents:read` |
| POST | `/v1/runs/:id/steps/:stepId/revert` | Undo a write step's changes (values changed since are left alone and listed) (web app only) | `agents:write` |
| POST | `/v1/sandbox/try` | Run code once in the sandbox on an input (no network, no secrets), e.g. to check a code step while editing it (web app) (web app only) | `agents:write` |
| GET | `/v1/secrets` | Secret names for workflow HTTP blocks (values are never returned) | `agents:read` |
| DELETE | `/v1/secrets/:name` | Remove a secret (web app only) | `security:write` |
| PUT | `/v1/secrets/:name` | Set a secret; agents use it as {"$secret": "name"} and only the call sees its value (web app only) | `security:write` |
| GET | `/v1/settings/approvals` | Approval settings | `settings:read` |
| PUT | `/v1/settings/approvals` | How long items wait before they expire (1–90 days, or null for never) (web app only) | `settings:write` |
| GET | `/v1/skills` | The organization's skills (SKILL.md) | `agents:read` |
| POST | `/v1/skills` | Add a skill from SKILL.md text or a zip of its directory (replace: true adds a revision) | `agents:write` |
| DELETE | `/v1/skills/:name` | Archive a skill (agents using it can't be published until it's removed from them) | `agents:write` |
| GET | `/v1/skills/:name` | A skill with its current revision | `agents:read` |
| GET | `/v1/skills/:name/export` | Export as SKILL.md or a zip of the skill directory (base64) | `agents:read` |
| GET | `/v1/telemetry` | Agent telemetry: per agent, runs by status, cost per run and per task, an outcome rate, running now; usage by category | `agents:read` |
| GET | `/v1/template-catalogs` | Community template catalogs this organization subscribes to (signed feeds, publisher key pinned) | `agents:read` |
| POST | `/v1/template-catalogs` | Subscribe to a signed template catalog (owner): its URL and the publisher's Ed25519 public key; it must verify now (web app only) | `integrations:write` |
| DELETE | `/v1/template-catalogs/:id` | Unsubscribe (owner); templates already installed stay | `integrations:write` |
| POST | `/v1/template-catalogs/:id/refresh` | Fetch and verify the catalog now (owner) | `integrations:write` |
| GET | `/v1/template-catalogs/:id/templates` | A catalog's templates, with which are installed here and which have updates | `agents:read` |
| POST | `/v1/template-catalogs/:id/templates/:key/install` | Install (or update) a catalog template as an imported template; agents made from it start as drafts | `agents:write` |
| GET | `/v1/today` | Today: my meetings, tasks due, approvals waiting (tap to decide) and what happened while I was away | `search:read` |
| GET | `/v1/tools` | Every tool agents (and later MCP and Slack) can call: effect, integration, access level, and the organization's gates | `agents:read` |
| PATCH | `/v1/tools/:name` | Turn a tool off, require approval before each use, or restrict it to owners (web app only) | `settings:write` |
| GET | `/v1/tools/:name/history` | Recent changes to a tool's gates | `agents:read` |
| DELETE | `/v1/triggers/:id` | Remove a trigger | `agents:write` |
| PATCH | `/v1/triggers/:id` | Change a trigger (or turn it off) | `agents:write` |
| GET | `/v1/triggers/:id/fires` | Recent firings: started, duplicate, busy or agent not live | `agents:read` |
| POST | `/v1/triggers/:id/rotate-secret` | New secret for a webhook trigger (the old one stops working) | `agents:write` |
| POST | `/v1/webhook-deliveries/:id/resend` | Send a delivery again | `security:write` |
| GET | `/v1/webhooks` | Outbound webhook endpoints | `settings:read` |
| POST | `/v1/webhooks` | Add an endpoint. The signing secret (whsec_…) is returned once. | `security:write` |
| DELETE | `/v1/webhooks/:id` | Remove an endpoint and its delivery log | `security:write` |
| PATCH | `/v1/webhooks/:id` | Change an endpoint, or pause it (enabled: false) | `security:write` |
| GET | `/v1/webhooks/:id/deliveries` | Deliveries of the last 30 days, newest first | `settings:read` |
| POST | `/v1/webhooks/:id/rotate-secret` | New signing secret; the old one also signs for 24 hours (force: true drops it now) | `security:write` |
| POST | `/v1/webhooks/:id/test` | Send a test event (webhook.test) | `security:write` |

## Examples

### DELETE /v1/agent-examples/$ID

Forget an example

```bash
curl -s -X DELETE "https://api.closefinch.com/v1/agent-examples/$ID" \
  -H "Authorization: Bearer $RA_API_KEY"
```

```js
const res = await fetch(`https://api.closefinch.com/v1/agent-examples/${id}`, {
  method: "DELETE",
  headers: { authorization: `Bearer ${process.env.RA_API_KEY}` },
});
const data = await res.json();
```

### GET /v1/agent-org-chart

Agents by the teammate they report to

```bash
curl -s "https://api.closefinch.com/v1/agent-org-chart" \
  -H "Authorization: Bearer $RA_API_KEY"
```

```js
const res = await fetch(`https://api.closefinch.com/v1/agent-org-chart`, {
  method: "GET",
  headers: { authorization: `Bearer ${process.env.RA_API_KEY}` },
});
const data = await res.json();
```

### GET /v1/agent-templates

Browse templates: built-in, shared by your team and imported, by category, role and search

```bash
curl -s "https://api.closefinch.com/v1/agent-templates" \
  -H "Authorization: Bearer $RA_API_KEY"
```

```js
const res = await fetch(`https://api.closefinch.com/v1/agent-templates`, {
  method: "GET",
  headers: { authorization: `Bearer ${process.env.RA_API_KEY}` },
});
const data = await res.json();
```

### DELETE /v1/agent-templates/$KEY

Archive a team or imported template (agents made from it keep working)

```bash
curl -s -X DELETE "https://api.closefinch.com/v1/agent-templates/$KEY" \
  -H "Authorization: Bearer $RA_API_KEY"
```

```js
const res = await fetch(`https://api.closefinch.com/v1/agent-templates/${key}`, {
  method: "DELETE",
  headers: { authorization: `Bearer ${process.env.RA_API_KEY}` },
});
const data = await res.json();
```

### GET /v1/agent-templates/$KEY

A template: goal, steps, best for, inputs, outputs, integrations with access, approvals, when it runs, what it replaces, FAQ

```bash
curl -s "https://api.closefinch.com/v1/agent-templates/$KEY" \
  -H "Authorization: Bearer $RA_API_KEY"
```

```js
const res = await fetch(`https://api.closefinch.com/v1/agent-templates/${key}`, {
  method: "GET",
  headers: { authorization: `Bearer ${process.env.RA_API_KEY}` },
});
const data = await res.json();
```

### GET /v1/agent-templates/$KEY/export

Export a template as a package (spec and its skills) to reuse in another organization or install

```bash
curl -s "https://api.closefinch.com/v1/agent-templates/$KEY/export" \
  -H "Authorization: Bearer $RA_API_KEY"
```

```js
const res = await fetch(`https://api.closefinch.com/v1/agent-templates/${key}/export`, {
  method: "GET",
  headers: { authorization: `Bearer ${process.env.RA_API_KEY}` },
});
const data = await res.json();
```

### POST /v1/agent-templates/import

Import a template package; its skills are added when missing

```bash
curl -s -X POST "https://api.closefinch.com/v1/agent-templates/import" \
  -H "Authorization: Bearer $RA_API_KEY" \
  -H "content-type: application/json" \
  -d '{}'
```

```js
const res = await fetch(`https://api.closefinch.com/v1/agent-templates/import`, {
  method: "POST",
  headers: { authorization: `Bearer ${process.env.RA_API_KEY}`, "content-type": "application/json" },
  body: JSON.stringify({}), // fields: see the OpenAPI schema
});
const data = await res.json();
```

### POST /v1/agents

Create a draft agent, from a template or a spec

```bash
curl -s -X POST "https://api.closefinch.com/v1/agents" \
  -H "Authorization: Bearer $RA_API_KEY" \
  -H "content-type: application/json" \
  -d '{}'
```

```js
const res = await fetch(`https://api.closefinch.com/v1/agents`, {
  method: "POST",
  headers: { authorization: `Bearer ${process.env.RA_API_KEY}`, "content-type": "application/json" },
  body: JSON.stringify({}), // fields: see the OpenAPI schema
});
const data = await res.json();
```

### DELETE /v1/agents/$ID

Archive an agent (its versions and runs are kept)

```bash
curl -s -X DELETE "https://api.closefinch.com/v1/agents/$ID" \
  -H "Authorization: Bearer $RA_API_KEY"
```

```js
const res = await fetch(`https://api.closefinch.com/v1/agents/${id}`, {
  method: "DELETE",
  headers: { authorization: `Bearer ${process.env.RA_API_KEY}` },
});
const data = await res.json();
```

### GET /v1/agents/$ID

An agent: profile, draft spec, integrations and access it needs, current version

```bash
curl -s "https://api.closefinch.com/v1/agents/$ID" \
  -H "Authorization: Bearer $RA_API_KEY"
```

```js
const res = await fetch(`https://api.closefinch.com/v1/agents/${id}`, {
  method: "GET",
  headers: { authorization: `Bearer ${process.env.RA_API_KEY}` },
});
const data = await res.json();
```

### PATCH /v1/agents/$ID

Edit an agent's profile or draft (published versions don't change)

```bash
curl -s -X PATCH "https://api.closefinch.com/v1/agents/$ID" \
  -H "Authorization: Bearer $RA_API_KEY" \
  -H "content-type: application/json" \
  -d '{}'
```

```js
const res = await fetch(`https://api.closefinch.com/v1/agents/${id}`, {
  method: "PATCH",
  headers: { authorization: `Bearer ${process.env.RA_API_KEY}`, "content-type": "application/json" },
  body: JSON.stringify({}), // fields: see the OpenAPI schema
});
const data = await res.json();
```

### POST /v1/agents/$ID/code-steps

Have the model write a code step for a repeated task: it's test-run in the sandbox on your sample input and added to the draft (a person publishes it; then it runs without the model)

```bash
curl -s -X POST "https://api.closefinch.com/v1/agents/$ID/code-steps" \
  -H "Authorization: Bearer $RA_API_KEY" \
  -H "content-type: application/json" \
  -d '{}'
```

```js
const res = await fetch(`https://api.closefinch.com/v1/agents/${id}/code-steps`, {
  method: "POST",
  headers: { authorization: `Bearer ${process.env.RA_API_KEY}`, "content-type": "application/json" },
  body: JSON.stringify({}), // fields: see the OpenAPI schema
});
const data = await res.json();
```

### GET /v1/agents/$ID/diff

What changed between two versions (or a version and the draft: to=draft)

```bash
curl -s "https://api.closefinch.com/v1/agents/$ID/diff" \
  -H "Authorization: Bearer $RA_API_KEY"
```

```js
const res = await fetch(`https://api.closefinch.com/v1/agents/${id}/diff`, {
  method: "GET",
  headers: { authorization: `Bearer ${process.env.RA_API_KEY}` },
});
const data = await res.json();
```

### GET /v1/agents/$ID/evals

The agent's eval cases and recent suite runs

```bash
curl -s "https://api.closefinch.com/v1/agents/$ID/evals" \
  -H "Authorization: Bearer $RA_API_KEY"
```

```js
const res = await fetch(`https://api.closefinch.com/v1/agents/${id}/evals`, {
  method: "GET",
  headers: { authorization: `Bearer ${process.env.RA_API_KEY}` },
});
const data = await res.json();
```

### POST /v1/agents/$ID/evals

Add (or replace, by name) an eval case: an input and what the run must do (owners: cases are the publish gate)

```bash
curl -s -X POST "https://api.closefinch.com/v1/agents/$ID/evals" \
  -H "Authorization: Bearer $RA_API_KEY" \
  -H "content-type: application/json" \
  -d '{}'
```

```js
const res = await fetch(`https://api.closefinch.com/v1/agents/${id}/evals`, {
  method: "POST",
  headers: { authorization: `Bearer ${process.env.RA_API_KEY}`, "content-type": "application/json" },
  body: JSON.stringify({}), // fields: see the OpenAPI schema
});
const data = await res.json();
```

### DELETE /v1/agents/$ID/evals/$CASE_ID

Remove an eval case (owners)

```bash
curl -s -X DELETE "https://api.closefinch.com/v1/agents/$ID/evals/$CASE_ID" \
  -H "Authorization: Bearer $RA_API_KEY"
```

```js
const res = await fetch(`https://api.closefinch.com/v1/agents/${id}/evals/${caseId}`, {
  method: "DELETE",
  headers: { authorization: `Bearer ${process.env.RA_API_KEY}` },
});
const data = await res.json();
```

### POST /v1/agents/$ID/evals/run

Run the eval suite as dry runs (nothing is written or sent) on the draft, the current version, or a version

```bash
curl -s -X POST "https://api.closefinch.com/v1/agents/$ID/evals/run" \
  -H "Authorization: Bearer $RA_API_KEY" \
  -H "content-type: application/json" \
  -d '{}'
```

```js
const res = await fetch(`https://api.closefinch.com/v1/agents/${id}/evals/run`, {
  method: "POST",
  headers: { authorization: `Bearer ${process.env.RA_API_KEY}`, "content-type": "application/json" },
  body: JSON.stringify({}), // fields: see the OpenAPI schema
});
const data = await res.json();
```

### GET /v1/agents/$ID/examples

What the agent learned from people's edits and rejections

```bash
curl -s "https://api.closefinch.com/v1/agents/$ID/examples" \
  -H "Authorization: Bearer $RA_API_KEY"
```

```js
const res = await fetch(`https://api.closefinch.com/v1/agents/${id}/examples`, {
  method: "GET",
  headers: { authorization: `Bearer ${process.env.RA_API_KEY}` },
});
const data = await res.json();
```

### GET /v1/agents/$ID/experiment

The running (or decided) experiment and each version's metric so far

```bash
curl -s "https://api.closefinch.com/v1/agents/$ID/experiment" \
  -H "Authorization: Bearer $RA_API_KEY"
```

```js
const res = await fetch(`https://api.closefinch.com/v1/agents/${id}/experiment`, {
  method: "GET",
  headers: { authorization: `Bearer ${process.env.RA_API_KEY}` },
});
const data = await res.json();
```

### POST /v1/agents/$ID/publish

Publish the draft as a new immutable version, granting the access levels listed (default: everything its tools need)

```bash
curl -s -X POST "https://api.closefinch.com/v1/agents/$ID/publish" \
  -H "Authorization: Bearer $RA_API_KEY" \
  -H "content-type: application/json" \
  -d '{}'
```

```js
const res = await fetch(`https://api.closefinch.com/v1/agents/${id}/publish`, {
  method: "POST",
  headers: { authorization: `Bearer ${process.env.RA_API_KEY}`, "content-type": "application/json" },
  body: JSON.stringify({}), // fields: see the OpenAPI schema
});
const data = await res.json();
```

### POST /v1/agents/$ID/rollback

Roll back: publish an earlier version again as the newest

```bash
curl -s -X POST "https://api.closefinch.com/v1/agents/$ID/rollback" \
  -H "Authorization: Bearer $RA_API_KEY" \
  -H "content-type: application/json" \
  -d '{}'
```

```js
const res = await fetch(`https://api.closefinch.com/v1/agents/${id}/rollback`, {
  method: "POST",
  headers: { authorization: `Bearer ${process.env.RA_API_KEY}`, "content-type": "application/json" },
  body: JSON.stringify({}), // fields: see the OpenAPI schema
});
const data = await res.json();
```

### POST /v1/agents/$ID/share

Share the agent's current version as a template for the team

```bash
curl -s -X POST "https://api.closefinch.com/v1/agents/$ID/share" \
  -H "Authorization: Bearer $RA_API_KEY" \
  -H "content-type: application/json" \
  -d '{}'
```

```js
const res = await fetch(`https://api.closefinch.com/v1/agents/${id}/share`, {
  method: "POST",
  headers: { authorization: `Bearer ${process.env.RA_API_KEY}`, "content-type": "application/json" },
  body: JSON.stringify({}), // fields: see the OpenAPI schema
});
const data = await res.json();
```

### POST /v1/agents/$ID/state

Set the agent live, pause it, or take it back to ready

```bash
curl -s -X POST "https://api.closefinch.com/v1/agents/$ID/state" \
  -H "Authorization: Bearer $RA_API_KEY" \
  -H "content-type: application/json" \
  -d '{}'
```

```js
const res = await fetch(`https://api.closefinch.com/v1/agents/${id}/state`, {
  method: "POST",
  headers: { authorization: `Bearer ${process.env.RA_API_KEY}`, "content-type": "application/json" },
  body: JSON.stringify({}), // fields: see the OpenAPI schema
});
const data = await res.json();
```

### GET /v1/agents/$ID/telemetry

One agent's telemetry per version (compare versions)

```bash
curl -s "https://api.closefinch.com/v1/agents/$ID/telemetry" \
  -H "Authorization: Bearer $RA_API_KEY"
```

```js
const res = await fetch(`https://api.closefinch.com/v1/agents/${id}/telemetry`, {
  method: "GET",
  headers: { authorization: `Bearer ${process.env.RA_API_KEY}` },
});
const data = await res.json();
```

### POST /v1/agents/$ID/test-run

Run the draft once now, step by step. Every write it would make waits for your approval.

```bash
curl -s -X POST "https://api.closefinch.com/v1/agents/$ID/test-run" \
  -H "Authorization: Bearer $RA_API_KEY" \
  -H "content-type: application/json" \
  -d '{}'
```

```js
const res = await fetch(`https://api.closefinch.com/v1/agents/${id}/test-run`, {
  method: "POST",
  headers: { authorization: `Bearer ${process.env.RA_API_KEY}`, "content-type": "application/json" },
  body: JSON.stringify({}), // fields: see the OpenAPI schema
});
const data = await res.json();
```

### GET /v1/agents/$ID/triggers

When the agent runs: schedules, events and webhook URLs

```bash
curl -s "https://api.closefinch.com/v1/agents/$ID/triggers" \
  -H "Authorization: Bearer $RA_API_KEY"
```

```js
const res = await fetch(`https://api.closefinch.com/v1/agents/${id}/triggers`, {
  method: "GET",
  headers: { authorization: `Bearer ${process.env.RA_API_KEY}` },
});
const data = await res.json();
```

### POST /v1/agents/$ID/triggers

Add a trigger. Webhook triggers return their URL and secret once.

```bash
curl -s -X POST "https://api.closefinch.com/v1/agents/$ID/triggers" \
  -H "Authorization: Bearer $RA_API_KEY" \
  -H "content-type: application/json" \
  -d '{}'
```

```js
const res = await fetch(`https://api.closefinch.com/v1/agents/${id}/triggers`, {
  method: "POST",
  headers: { authorization: `Bearer ${process.env.RA_API_KEY}`, "content-type": "application/json" },
  body: JSON.stringify({}), // fields: see the OpenAPI schema
});
const data = await res.json();
```

### GET /v1/agents/$ID/versions

Published versions, newest first

```bash
curl -s "https://api.closefinch.com/v1/agents/$ID/versions" \
  -H "Authorization: Bearer $RA_API_KEY"
```

```js
const res = await fetch(`https://api.closefinch.com/v1/agents/${id}/versions`, {
  method: "GET",
  headers: { authorization: `Bearer ${process.env.RA_API_KEY}` },
});
const data = await res.json();
```

### POST /v1/agents/draft-from-goal

Describe a goal; the model drafts an agent from the registered tools (validated). It's saved as a draft for you to review, test and publish.

```bash
curl -s -X POST "https://api.closefinch.com/v1/agents/draft-from-goal" \
  -H "Authorization: Bearer $RA_API_KEY" \
  -H "content-type: application/json" \
  -d '{}'
```

```js
const res = await fetch(`https://api.closefinch.com/v1/agents/draft-from-goal`, {
  method: "POST",
  headers: { authorization: `Bearer ${process.env.RA_API_KEY}`, "content-type": "application/json" },
  body: JSON.stringify({}), // fields: see the OpenAPI schema
});
const data = await res.json();
```

### GET /v1/approvals

The approval inbox: pending (default) or completed items, by agent, kind or assignee (assignee=me)

```bash
curl -s "https://api.closefinch.com/v1/approvals" \
  -H "Authorization: Bearer $RA_API_KEY"
```

```js
const res = await fetch(`https://api.closefinch.com/v1/approvals`, {
  method: "GET",
  headers: { authorization: `Bearer ${process.env.RA_API_KEY}` },
});
const data = await res.json();
```

### GET /v1/approvals/$ID

One approval item

```bash
curl -s "https://api.closefinch.com/v1/approvals/$ID" \
  -H "Authorization: Bearer $RA_API_KEY"
```

```js
const res = await fetch(`https://api.closefinch.com/v1/approvals/${id}`, {
  method: "GET",
  headers: { authorization: `Bearer ${process.env.RA_API_KEY}` },
});
const data = await res.json();
```

### GET /v1/events

Recent platform events (what triggers and webhooks see)

```bash
curl -s "https://api.closefinch.com/v1/events" \
  -H "Authorization: Bearer $RA_API_KEY"
```

```js
const res = await fetch(`https://api.closefinch.com/v1/events`, {
  method: "GET",
  headers: { authorization: `Bearer ${process.env.RA_API_KEY}` },
});
const data = await res.json();
```

### GET /v1/home

Home: my open tasks, approvals waiting, recent activity on my records, pipeline numbers, live agents

```bash
curl -s "https://api.closefinch.com/v1/home" \
  -H "Authorization: Bearer $RA_API_KEY"
```

```js
const res = await fetch(`https://api.closefinch.com/v1/home`, {
  method: "GET",
  headers: { authorization: `Bearer ${process.env.RA_API_KEY}` },
});
const data = await res.json();
```

### GET /v1/runs/$ID/scorecard

The run's QA scorecard: checks and the model judge's score against the spec's rubric

```bash
curl -s "https://api.closefinch.com/v1/runs/$ID/scorecard" \
  -H "Authorization: Bearer $RA_API_KEY"
```

```js
const res = await fetch(`https://api.closefinch.com/v1/runs/${id}/scorecard`, {
  method: "GET",
  headers: { authorization: `Bearer ${process.env.RA_API_KEY}` },
});
const data = await res.json();
```

### GET /v1/secrets

Secret names for workflow HTTP blocks (values are never returned)

```bash
curl -s "https://api.closefinch.com/v1/secrets" \
  -H "Authorization: Bearer $RA_API_KEY"
```

```js
const res = await fetch(`https://api.closefinch.com/v1/secrets`, {
  method: "GET",
  headers: { authorization: `Bearer ${process.env.RA_API_KEY}` },
});
const data = await res.json();
```

### GET /v1/settings/approvals

Approval settings

```bash
curl -s "https://api.closefinch.com/v1/settings/approvals" \
  -H "Authorization: Bearer $RA_API_KEY"
```

```js
const res = await fetch(`https://api.closefinch.com/v1/settings/approvals`, {
  method: "GET",
  headers: { authorization: `Bearer ${process.env.RA_API_KEY}` },
});
const data = await res.json();
```

### GET /v1/skills

The organization's skills (SKILL.md)

```bash
curl -s "https://api.closefinch.com/v1/skills" \
  -H "Authorization: Bearer $RA_API_KEY"
```

```js
const res = await fetch(`https://api.closefinch.com/v1/skills`, {
  method: "GET",
  headers: { authorization: `Bearer ${process.env.RA_API_KEY}` },
});
const data = await res.json();
```

### POST /v1/skills

Add a skill from SKILL.md text or a zip of its directory (replace: true adds a revision)

```bash
curl -s -X POST "https://api.closefinch.com/v1/skills" \
  -H "Authorization: Bearer $RA_API_KEY" \
  -H "content-type: application/json" \
  -d '{}'
```

```js
const res = await fetch(`https://api.closefinch.com/v1/skills`, {
  method: "POST",
  headers: { authorization: `Bearer ${process.env.RA_API_KEY}`, "content-type": "application/json" },
  body: JSON.stringify({}), // fields: see the OpenAPI schema
});
const data = await res.json();
```

### DELETE /v1/skills/$NAME

Archive a skill (agents using it can't be published until it's removed from them)

```bash
curl -s -X DELETE "https://api.closefinch.com/v1/skills/$NAME" \
  -H "Authorization: Bearer $RA_API_KEY"
```

```js
const res = await fetch(`https://api.closefinch.com/v1/skills/${name}`, {
  method: "DELETE",
  headers: { authorization: `Bearer ${process.env.RA_API_KEY}` },
});
const data = await res.json();
```

### GET /v1/skills/$NAME

A skill with its current revision

```bash
curl -s "https://api.closefinch.com/v1/skills/$NAME" \
  -H "Authorization: Bearer $RA_API_KEY"
```

```js
const res = await fetch(`https://api.closefinch.com/v1/skills/${name}`, {
  method: "GET",
  headers: { authorization: `Bearer ${process.env.RA_API_KEY}` },
});
const data = await res.json();
```

### GET /v1/skills/$NAME/export

Export as SKILL.md or a zip of the skill directory (base64)

```bash
curl -s "https://api.closefinch.com/v1/skills/$NAME/export" \
  -H "Authorization: Bearer $RA_API_KEY"
```

```js
const res = await fetch(`https://api.closefinch.com/v1/skills/${name}/export`, {
  method: "GET",
  headers: { authorization: `Bearer ${process.env.RA_API_KEY}` },
});
const data = await res.json();
```

### GET /v1/telemetry

Agent telemetry: per agent, runs by status, cost per run and per task, an outcome rate, running now; usage by category

```bash
curl -s "https://api.closefinch.com/v1/telemetry" \
  -H "Authorization: Bearer $RA_API_KEY"
```

```js
const res = await fetch(`https://api.closefinch.com/v1/telemetry`, {
  method: "GET",
  headers: { authorization: `Bearer ${process.env.RA_API_KEY}` },
});
const data = await res.json();
```

### GET /v1/template-catalogs

Community template catalogs this organization subscribes to (signed feeds, publisher key pinned)

```bash
curl -s "https://api.closefinch.com/v1/template-catalogs" \
  -H "Authorization: Bearer $RA_API_KEY"
```

```js
const res = await fetch(`https://api.closefinch.com/v1/template-catalogs`, {
  method: "GET",
  headers: { authorization: `Bearer ${process.env.RA_API_KEY}` },
});
const data = await res.json();
```

### DELETE /v1/template-catalogs/$ID

Unsubscribe (owner); templates already installed stay

```bash
curl -s -X DELETE "https://api.closefinch.com/v1/template-catalogs/$ID" \
  -H "Authorization: Bearer $RA_API_KEY"
```

```js
const res = await fetch(`https://api.closefinch.com/v1/template-catalogs/${id}`, {
  method: "DELETE",
  headers: { authorization: `Bearer ${process.env.RA_API_KEY}` },
});
const data = await res.json();
```

### POST /v1/template-catalogs/$ID/refresh

Fetch and verify the catalog now (owner)

```bash
curl -s -X POST "https://api.closefinch.com/v1/template-catalogs/$ID/refresh" \
  -H "Authorization: Bearer $RA_API_KEY" \
  -H "content-type: application/json" \
  -d '{}'
```

```js
const res = await fetch(`https://api.closefinch.com/v1/template-catalogs/${id}/refresh`, {
  method: "POST",
  headers: { authorization: `Bearer ${process.env.RA_API_KEY}`, "content-type": "application/json" },
  body: JSON.stringify({}), // fields: see the OpenAPI schema
});
const data = await res.json();
```

### GET /v1/template-catalogs/$ID/templates

A catalog's templates, with which are installed here and which have updates

```bash
curl -s "https://api.closefinch.com/v1/template-catalogs/$ID/templates" \
  -H "Authorization: Bearer $RA_API_KEY"
```

```js
const res = await fetch(`https://api.closefinch.com/v1/template-catalogs/${id}/templates`, {
  method: "GET",
  headers: { authorization: `Bearer ${process.env.RA_API_KEY}` },
});
const data = await res.json();
```

### POST /v1/template-catalogs/$ID/templates/$KEY/install

Install (or update) a catalog template as an imported template; agents made from it start as drafts

```bash
curl -s -X POST "https://api.closefinch.com/v1/template-catalogs/$ID/templates/$KEY/install" \
  -H "Authorization: Bearer $RA_API_KEY" \
  -H "content-type: application/json" \
  -d '{}'
```

```js
const res = await fetch(`https://api.closefinch.com/v1/template-catalogs/${id}/templates/${key}/install`, {
  method: "POST",
  headers: { authorization: `Bearer ${process.env.RA_API_KEY}`, "content-type": "application/json" },
  body: JSON.stringify({}), // fields: see the OpenAPI schema
});
const data = await res.json();
```

### GET /v1/today

Today: my meetings, tasks due, approvals waiting (tap to decide) and what happened while I was away

```bash
curl -s "https://api.closefinch.com/v1/today" \
  -H "Authorization: Bearer $RA_API_KEY"
```

```js
const res = await fetch(`https://api.closefinch.com/v1/today`, {
  method: "GET",
  headers: { authorization: `Bearer ${process.env.RA_API_KEY}` },
});
const data = await res.json();
```

### GET /v1/tools

Every tool agents (and later MCP and Slack) can call: effect, integration, access level, and the organization's gates

```bash
curl -s "https://api.closefinch.com/v1/tools" \
  -H "Authorization: Bearer $RA_API_KEY"
```

```js
const res = await fetch(`https://api.closefinch.com/v1/tools`, {
  method: "GET",
  headers: { authorization: `Bearer ${process.env.RA_API_KEY}` },
});
const data = await res.json();
```

### GET /v1/tools/$NAME/history

Recent changes to a tool's gates

```bash
curl -s "https://api.closefinch.com/v1/tools/$NAME/history" \
  -H "Authorization: Bearer $RA_API_KEY"
```

```js
const res = await fetch(`https://api.closefinch.com/v1/tools/${name}/history`, {
  method: "GET",
  headers: { authorization: `Bearer ${process.env.RA_API_KEY}` },
});
const data = await res.json();
```

### DELETE /v1/triggers/$ID

Remove a trigger

```bash
curl -s -X DELETE "https://api.closefinch.com/v1/triggers/$ID" \
  -H "Authorization: Bearer $RA_API_KEY"
```

```js
const res = await fetch(`https://api.closefinch.com/v1/triggers/${id}`, {
  method: "DELETE",
  headers: { authorization: `Bearer ${process.env.RA_API_KEY}` },
});
const data = await res.json();
```

### PATCH /v1/triggers/$ID

Change a trigger (or turn it off)

```bash
curl -s -X PATCH "https://api.closefinch.com/v1/triggers/$ID" \
  -H "Authorization: Bearer $RA_API_KEY" \
  -H "content-type: application/json" \
  -d '{}'
```

```js
const res = await fetch(`https://api.closefinch.com/v1/triggers/${id}`, {
  method: "PATCH",
  headers: { authorization: `Bearer ${process.env.RA_API_KEY}`, "content-type": "application/json" },
  body: JSON.stringify({}), // fields: see the OpenAPI schema
});
const data = await res.json();
```

### GET /v1/triggers/$ID/fires

Recent firings: started, duplicate, busy or agent not live

```bash
curl -s "https://api.closefinch.com/v1/triggers/$ID/fires" \
  -H "Authorization: Bearer $RA_API_KEY"
```

```js
const res = await fetch(`https://api.closefinch.com/v1/triggers/${id}/fires`, {
  method: "GET",
  headers: { authorization: `Bearer ${process.env.RA_API_KEY}` },
});
const data = await res.json();
```

### POST /v1/triggers/$ID/rotate-secret

New secret for a webhook trigger (the old one stops working)

```bash
curl -s -X POST "https://api.closefinch.com/v1/triggers/$ID/rotate-secret" \
  -H "Authorization: Bearer $RA_API_KEY" \
  -H "content-type: application/json" \
  -d '{}'
```

```js
const res = await fetch(`https://api.closefinch.com/v1/triggers/${id}/rotate-secret`, {
  method: "POST",
  headers: { authorization: `Bearer ${process.env.RA_API_KEY}`, "content-type": "application/json" },
  body: JSON.stringify({}), // fields: see the OpenAPI schema
});
const data = await res.json();
```

### POST /v1/webhook-deliveries/$ID/resend

Send a delivery again

```bash
curl -s -X POST "https://api.closefinch.com/v1/webhook-deliveries/$ID/resend" \
  -H "Authorization: Bearer $RA_API_KEY" \
  -H "content-type: application/json" \
  -d '{}'
```

```js
const res = await fetch(`https://api.closefinch.com/v1/webhook-deliveries/${id}/resend`, {
  method: "POST",
  headers: { authorization: `Bearer ${process.env.RA_API_KEY}`, "content-type": "application/json" },
  body: JSON.stringify({}), // fields: see the OpenAPI schema
});
const data = await res.json();
```

### GET /v1/webhooks

Outbound webhook endpoints

```bash
curl -s "https://api.closefinch.com/v1/webhooks" \
  -H "Authorization: Bearer $RA_API_KEY"
```

```js
const res = await fetch(`https://api.closefinch.com/v1/webhooks`, {
  method: "GET",
  headers: { authorization: `Bearer ${process.env.RA_API_KEY}` },
});
const data = await res.json();
```

### POST /v1/webhooks

Add an endpoint. The signing secret (whsec_…) is returned once.

```bash
curl -s -X POST "https://api.closefinch.com/v1/webhooks" \
  -H "Authorization: Bearer $RA_API_KEY" \
  -H "content-type: application/json" \
  -d '{}'
```

```js
const res = await fetch(`https://api.closefinch.com/v1/webhooks`, {
  method: "POST",
  headers: { authorization: `Bearer ${process.env.RA_API_KEY}`, "content-type": "application/json" },
  body: JSON.stringify({}), // fields: see the OpenAPI schema
});
const data = await res.json();
```

### DELETE /v1/webhooks/$ID

Remove an endpoint and its delivery log

```bash
curl -s -X DELETE "https://api.closefinch.com/v1/webhooks/$ID" \
  -H "Authorization: Bearer $RA_API_KEY"
```

```js
const res = await fetch(`https://api.closefinch.com/v1/webhooks/${id}`, {
  method: "DELETE",
  headers: { authorization: `Bearer ${process.env.RA_API_KEY}` },
});
const data = await res.json();
```

### PATCH /v1/webhooks/$ID

Change an endpoint, or pause it (enabled: false)

```bash
curl -s -X PATCH "https://api.closefinch.com/v1/webhooks/$ID" \
  -H "Authorization: Bearer $RA_API_KEY" \
  -H "content-type: application/json" \
  -d '{}'
```

```js
const res = await fetch(`https://api.closefinch.com/v1/webhooks/${id}`, {
  method: "PATCH",
  headers: { authorization: `Bearer ${process.env.RA_API_KEY}`, "content-type": "application/json" },
  body: JSON.stringify({}), // fields: see the OpenAPI schema
});
const data = await res.json();
```

### GET /v1/webhooks/$ID/deliveries

Deliveries of the last 30 days, newest first

```bash
curl -s "https://api.closefinch.com/v1/webhooks/$ID/deliveries" \
  -H "Authorization: Bearer $RA_API_KEY"
```

```js
const res = await fetch(`https://api.closefinch.com/v1/webhooks/${id}/deliveries`, {
  method: "GET",
  headers: { authorization: `Bearer ${process.env.RA_API_KEY}` },
});
const data = await res.json();
```

### POST /v1/webhooks/$ID/rotate-secret

New signing secret; the old one also signs for 24 hours (force: true drops it now)

```bash
curl -s -X POST "https://api.closefinch.com/v1/webhooks/$ID/rotate-secret" \
  -H "Authorization: Bearer $RA_API_KEY" \
  -H "content-type: application/json" \
  -d '{}'
```

```js
const res = await fetch(`https://api.closefinch.com/v1/webhooks/${id}/rotate-secret`, {
  method: "POST",
  headers: { authorization: `Bearer ${process.env.RA_API_KEY}`, "content-type": "application/json" },
  body: JSON.stringify({}), // fields: see the OpenAPI schema
});
const data = await res.json();
```

### POST /v1/webhooks/$ID/test

Send a test event (webhook.test)

```bash
curl -s -X POST "https://api.closefinch.com/v1/webhooks/$ID/test" \
  -H "Authorization: Bearer $RA_API_KEY" \
  -H "content-type: application/json" \
  -d '{}'
```

```js
const res = await fetch(`https://api.closefinch.com/v1/webhooks/${id}/test`, {
  method: "POST",
  headers: { authorization: `Bearer ${process.env.RA_API_KEY}`, "content-type": "application/json" },
  body: JSON.stringify({}), // fields: see the OpenAPI schema
});
const data = await res.json();
```

Request and response schemas: [https://www.closefinch.com/openapi.json](https://www.closefinch.com/openapi.json). All resources: [API reference](https://www.closefinch.com/docs/api).
