API reference
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
curl -s -X DELETE "https://api.closefinch.com/v1/agent-examples/$ID" \
-H "Authorization: Bearer $RA_API_KEY"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
curl -s "https://api.closefinch.com/v1/agent-org-chart" \
-H "Authorization: Bearer $RA_API_KEY"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
curl -s "https://api.closefinch.com/v1/agent-templates" \
-H "Authorization: Bearer $RA_API_KEY"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)
curl -s -X DELETE "https://api.closefinch.com/v1/agent-templates/$KEY" \
-H "Authorization: Bearer $RA_API_KEY"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
curl -s "https://api.closefinch.com/v1/agent-templates/$KEY" \
-H "Authorization: Bearer $RA_API_KEY"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
curl -s "https://api.closefinch.com/v1/agent-templates/$KEY/export" \
-H "Authorization: Bearer $RA_API_KEY"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
curl -s -X POST "https://api.closefinch.com/v1/agent-templates/import" \
-H "Authorization: Bearer $RA_API_KEY" \
-H "content-type: application/json" \
-d '{}'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
curl -s -X POST "https://api.closefinch.com/v1/agents" \
-H "Authorization: Bearer $RA_API_KEY" \
-H "content-type: application/json" \
-d '{}'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)
curl -s -X DELETE "https://api.closefinch.com/v1/agents/$ID" \
-H "Authorization: Bearer $RA_API_KEY"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
curl -s "https://api.closefinch.com/v1/agents/$ID" \
-H "Authorization: Bearer $RA_API_KEY"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)
curl -s -X PATCH "https://api.closefinch.com/v1/agents/$ID" \
-H "Authorization: Bearer $RA_API_KEY" \
-H "content-type: application/json" \
-d '{}'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)
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 '{}'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)
curl -s "https://api.closefinch.com/v1/agents/$ID/diff" \
-H "Authorization: Bearer $RA_API_KEY"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
curl -s "https://api.closefinch.com/v1/agents/$ID/evals" \
-H "Authorization: Bearer $RA_API_KEY"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)
curl -s -X POST "https://api.closefinch.com/v1/agents/$ID/evals" \
-H "Authorization: Bearer $RA_API_KEY" \
-H "content-type: application/json" \
-d '{}'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)
curl -s -X DELETE "https://api.closefinch.com/v1/agents/$ID/evals/$CASE_ID" \
-H "Authorization: Bearer $RA_API_KEY"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
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 '{}'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
curl -s "https://api.closefinch.com/v1/agents/$ID/examples" \
-H "Authorization: Bearer $RA_API_KEY"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
curl -s "https://api.closefinch.com/v1/agents/$ID/experiment" \
-H "Authorization: Bearer $RA_API_KEY"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)
curl -s -X POST "https://api.closefinch.com/v1/agents/$ID/publish" \
-H "Authorization: Bearer $RA_API_KEY" \
-H "content-type: application/json" \
-d '{}'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
curl -s -X POST "https://api.closefinch.com/v1/agents/$ID/rollback" \
-H "Authorization: Bearer $RA_API_KEY" \
-H "content-type: application/json" \
-d '{}'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
curl -s -X POST "https://api.closefinch.com/v1/agents/$ID/share" \
-H "Authorization: Bearer $RA_API_KEY" \
-H "content-type: application/json" \
-d '{}'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
curl -s -X POST "https://api.closefinch.com/v1/agents/$ID/state" \
-H "Authorization: Bearer $RA_API_KEY" \
-H "content-type: application/json" \
-d '{}'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)
curl -s "https://api.closefinch.com/v1/agents/$ID/telemetry" \
-H "Authorization: Bearer $RA_API_KEY"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.
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 '{}'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
curl -s "https://api.closefinch.com/v1/agents/$ID/triggers" \
-H "Authorization: Bearer $RA_API_KEY"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.
curl -s -X POST "https://api.closefinch.com/v1/agents/$ID/triggers" \
-H "Authorization: Bearer $RA_API_KEY" \
-H "content-type: application/json" \
-d '{}'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
curl -s "https://api.closefinch.com/v1/agents/$ID/versions" \
-H "Authorization: Bearer $RA_API_KEY"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.
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 '{}'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)
curl -s "https://api.closefinch.com/v1/approvals" \
-H "Authorization: Bearer $RA_API_KEY"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
curl -s "https://api.closefinch.com/v1/approvals/$ID" \
-H "Authorization: Bearer $RA_API_KEY"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)
curl -s "https://api.closefinch.com/v1/events" \
-H "Authorization: Bearer $RA_API_KEY"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
curl -s "https://api.closefinch.com/v1/home" \
-H "Authorization: Bearer $RA_API_KEY"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
curl -s "https://api.closefinch.com/v1/runs/$ID/scorecard" \
-H "Authorization: Bearer $RA_API_KEY"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)
curl -s "https://api.closefinch.com/v1/secrets" \
-H "Authorization: Bearer $RA_API_KEY"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
curl -s "https://api.closefinch.com/v1/settings/approvals" \
-H "Authorization: Bearer $RA_API_KEY"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)
curl -s "https://api.closefinch.com/v1/skills" \
-H "Authorization: Bearer $RA_API_KEY"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)
curl -s -X POST "https://api.closefinch.com/v1/skills" \
-H "Authorization: Bearer $RA_API_KEY" \
-H "content-type: application/json" \
-d '{}'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)
curl -s -X DELETE "https://api.closefinch.com/v1/skills/$NAME" \
-H "Authorization: Bearer $RA_API_KEY"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
curl -s "https://api.closefinch.com/v1/skills/$NAME" \
-H "Authorization: Bearer $RA_API_KEY"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)
curl -s "https://api.closefinch.com/v1/skills/$NAME/export" \
-H "Authorization: Bearer $RA_API_KEY"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
curl -s "https://api.closefinch.com/v1/telemetry" \
-H "Authorization: Bearer $RA_API_KEY"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)
curl -s "https://api.closefinch.com/v1/template-catalogs" \
-H "Authorization: Bearer $RA_API_KEY"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
curl -s -X DELETE "https://api.closefinch.com/v1/template-catalogs/$ID" \
-H "Authorization: Bearer $RA_API_KEY"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)
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 '{}'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
curl -s "https://api.closefinch.com/v1/template-catalogs/$ID/templates" \
-H "Authorization: Bearer $RA_API_KEY"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
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 '{}'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
curl -s "https://api.closefinch.com/v1/today" \
-H "Authorization: Bearer $RA_API_KEY"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
curl -s "https://api.closefinch.com/v1/tools" \
-H "Authorization: Bearer $RA_API_KEY"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
curl -s "https://api.closefinch.com/v1/tools/$NAME/history" \
-H "Authorization: Bearer $RA_API_KEY"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
curl -s -X DELETE "https://api.closefinch.com/v1/triggers/$ID" \
-H "Authorization: Bearer $RA_API_KEY"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)
curl -s -X PATCH "https://api.closefinch.com/v1/triggers/$ID" \
-H "Authorization: Bearer $RA_API_KEY" \
-H "content-type: application/json" \
-d '{}'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
curl -s "https://api.closefinch.com/v1/triggers/$ID/fires" \
-H "Authorization: Bearer $RA_API_KEY"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)
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 '{}'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
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 '{}'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
curl -s "https://api.closefinch.com/v1/webhooks" \
-H "Authorization: Bearer $RA_API_KEY"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.
curl -s -X POST "https://api.closefinch.com/v1/webhooks" \
-H "Authorization: Bearer $RA_API_KEY" \
-H "content-type: application/json" \
-d '{}'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
curl -s -X DELETE "https://api.closefinch.com/v1/webhooks/$ID" \
-H "Authorization: Bearer $RA_API_KEY"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)
curl -s -X PATCH "https://api.closefinch.com/v1/webhooks/$ID" \
-H "Authorization: Bearer $RA_API_KEY" \
-H "content-type: application/json" \
-d '{}'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
curl -s "https://api.closefinch.com/v1/webhooks/$ID/deliveries" \
-H "Authorization: Bearer $RA_API_KEY"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)
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 '{}'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)
curl -s -X POST "https://api.closefinch.com/v1/webhooks/$ID/test" \
-H "Authorization: Bearer $RA_API_KEY" \
-H "content-type: application/json" \
-d '{}'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. All resources: API reference.