Org API: everything the dashboard does
Org keys drive every dashboard action through the API: agents, budgets, approvals, receipts, billing, webhooks and team.
Anything a person can do in the dashboard, an agent can do through the API. Agent keys (sk_…) buy results; org keys (ok_…) run the org: make agents and set their budgets, decide approvals, read receipts, top up, manage webhooks and the team.
Org keys
- An owner makes them on the Team page while signed in (or
POST /v1/orgs/{orgId}/keyswith a session). The key is shown once. - Scope
readcan only read; anything else gets403 forbidden("This org key is read-only"). Scopewritecan do anything its maker can do on the dashboard. - A key acts as the owner who made it, works only on
/v1/orgs/{orgId}/…for its own org, and stops working if that owner leaves the org. - Keys can't make or revoke keys, and can't ask for data deletion: both need a person signed in.
- Up to 20 active keys per org. 300 requests a minute per key; see rate limits.
Send it as Authorization: Bearer ok_…. The org's id is in the dashboard's URLs (?org=…) and in GET /v1/me.
Worked examples
Make an agent and read its key
curl https://api.arettic.com/v1/orgs/$ORG_ID/agents \
-H "Authorization: Bearer $ARETTIC_ORG_KEY" \
-H "Content-Type: application/json" \
-d '{ "name": "Lead research", "mode": "live", "monthly_budget_credits": 100000 }'
# → { "agent": { "id": "…", … }, "key": "sk_live_…", "key_note": "…" } (the key is shown once)import { AretticOrg } from "@arettic/sdk";
const org = new AretticOrg({ apiKey: process.env.ARETTIC_ORG_KEY, orgId: "your-org-id" });
const { agent, key } = await org.agents.create({ name: "Lead research", mode: "live" });
await org.agents.update(agent.id, { monthly_budget_credits: 100_000, approval_threshold_credits: 20_000 });import os from arettic import AretticOrg org = AretticOrg(os.environ["ARETTIC_ORG_KEY"], os.environ["ARETTIC_ORG_ID"]) made = org.agents.create(name="Lead research", mode="live") org.agents.update(made["agent"]["id"], monthly_budget_credits=100_000, approval_threshold_credits=20_000)
A month of receipts, and the CSV
const page = await org.receipts.list({ from: "2026-09-01", to: "2026-09-30", limit: 200 });
const csv = await org.receipts.exportCsv({ from: "2026-09-01", to: "2026-09-30" });page = org.receipts.list(from_="2026-09-01", to="2026-09-30", limit=200) csv = org.receipts.export_csv(from_="2026-09-01", to="2026-09-30")
Decide an approval
curl https://api.arettic.com/v1/orgs/$ORG_ID/approvals/$APPROVAL_ID/decision \
-H "Authorization: Bearer $ARETTIC_ORG_KEY" \
-H "Content-Type: application/json" \
-d '{ "decision": "approve", "note": "Q4 list" }'const pending = await org.approvals.list({ status: "pending" });
for (const a of pending) await org.approvals.decide(a.approval_id, { decision: "approve" });for a in org.approvals.list(status="pending")["approvals"]:
org.approvals.decide(a["approval_id"], "approve")Add a webhook
const hook = await org.webhooks.create({ url: "https://example.com/arettic-hook", events: ["job.completed"] });
// hook.webhook.secret is shown once: store it to verify signatureshook = org.webhooks.create("https://example.com/arettic-hook", events=["job.completed"])
secret = hook["webhook"]["secret"] # shown onceVerifying deliveries is on webhooks. The dashboard's overview numbers (balance, spend by day, agent and tool, items not charged, budgets, pending approvals and disputes) are GET /v1/orgs/{orgId}/dashboard.
Errors you'll meet
403 forbidden: a read key tried to change something, a key was used on another org, or a member tried an owner-only action.402 plan_limit: the plan's agents, seats or webhook endpoints are used up.404 not_found: the thing isn't in this org.429 rate_limited: over 300 requests a minute.
Every dashboard action and its endpoint
Generated from the list our tests check: every server action in the dashboard is here, every endpoint is in /openapi.json, and an org key is tested against every row marked yes.
| Action | Dashboard page | Endpoint | Org key |
|---|---|---|---|
| Email me a sign-in link | /app | POST /auth/email/start | no: a person signed in |
| Sign out | /app | POST /auth/logout | no: a person signed in |
| Create an org | /app | POST /v1/orgs | no: a person signed in |
| Accept an invite | /invite | POST /v1/invites/accept | no: a person signed in |
| Balance, spend and refund rate | /app | GET /v1/orgs/{orgId}/dashboard | yes |
| List agents | /app/agents | GET /v1/orgs/{orgId}/agents | yes |
| Add an agent (key shown once) | /app/agents | POST /v1/orgs/{orgId}/agents | yes |
| Change name, budget, approval threshold, IP allowlist or status | /app/agents | PATCH /v1/orgs/{orgId}/agents/{agentId} | yes |
| Rotate an agent key | /app/agents | POST /v1/orgs/{orgId}/agents/{agentId}/rotate-key | yes |
| Revoke an agent key | /app/agents | POST /v1/orgs/{orgId}/agents/{agentId}/revoke-key | yes |
| Approval requests | /app/approvals | GET /v1/orgs/{orgId}/approvals | yes |
| Approve or reject a purchase | /app/approvals | POST /v1/orgs/{orgId}/approvals/{id}/decision | yes |
| Receipt explorer | /app/receipts | GET /v1/orgs/{orgId}/receipts | yes |
| One receipt | /app/receipts/[id] | GET /v1/orgs/{orgId}/receipts/{id} | yes |
| Export receipts as CSV | /app/receipts | GET /v1/orgs/{orgId}/exports/receipts.csv | yes |
| Dispute a charged item | /app/receipts/[id] | POST /v1/orgs/{orgId}/disputes | yes |
| Disputes and their decisions | /app/disputes | GET /v1/orgs/{orgId}/disputes | yes |
| Invoices | /app/invoices | GET /v1/orgs/{orgId}/invoices | yes |
| One invoice (JSON or printable HTML) | /app/invoices | GET /v1/orgs/{orgId}/invoices/{id} | yes |
| Balance and credit lots | /app/billing | GET /v1/orgs/{orgId}/balance | yes |
| Top-up history | /app/billing | GET /v1/orgs/{orgId}/topups | yes |
| Buy credits (returns a checkout link) | /app/billing | POST /v1/orgs/{orgId}/topups | yes |
| Auto-reload settings | /app/billing | GET /v1/orgs/{orgId}/auto-reload | yes |
| Turn auto-reload on or off | /app/billing | PUT /v1/orgs/{orgId}/auto-reload | yes |
| Low-balance alert level | /app/billing | PUT /v1/orgs/{orgId}/notifications | yes |
| Plan, limits and subscriptions | /app/billing | GET /v1/orgs/{orgId}/plan | yes |
| Start the Pro plan (returns a checkout link) | /app/billing | POST /v1/orgs/{orgId}/subscriptions | yes |
| Cancel a plan at period end | /app/billing | DELETE /v1/orgs/{orgId}/subscriptions/{plan} | yes |
| Billing name, address, country and tax ID | /app/billing | PATCH /v1/orgs/{orgId}/billing | yes |
| Webhook endpoints and event types | /app/webhooks | GET /v1/orgs/{orgId}/webhooks | yes |
| Recent deliveries | /app/webhooks | GET /v1/orgs/{orgId}/webhook-deliveries | yes |
| Recent events | /app/webhooks | GET /v1/orgs/{orgId}/events | yes |
| Add an endpoint (secret shown once) | /app/webhooks | POST /v1/orgs/{orgId}/webhooks | yes |
| Send a test event | /app/webhooks | POST /v1/orgs/{orgId}/webhooks/{id}/test | yes |
| Delete an endpoint | /app/webhooks | DELETE /v1/orgs/{orgId}/webhooks/{id} | yes |
| Members and pending invites | /app/team | GET /v1/orgs/{orgId}/members | yes |
| Invite by email | /app/team | POST /v1/orgs/{orgId}/invites | yes |
| Withdraw an invite | /app/team | DELETE /v1/orgs/{orgId}/invites/{inviteId} | yes |
| Make a member an owner, or back | /app/team | PATCH /v1/orgs/{orgId}/members/{userId} | yes |
| Remove a member, or leave | /app/team | DELETE /v1/orgs/{orgId}/members/{userId} | yes |
| Org API keys | /app/team | GET /v1/orgs/{orgId}/keys | no: a person signed in |
| Make an org API key (shown once) | /app/team | POST /v1/orgs/{orgId}/keys | no: a person signed in |
| Revoke an org API key | /app/team | DELETE /v1/orgs/{orgId}/keys/{id} | no: a person signed in |
| Data-deletion requests | /app/team | GET /v1/orgs/{orgId}/deletion-requests | yes |
| Ask us to delete stored inputs and results (within 24 hours) | /app/team | POST /v1/orgs/{orgId}/deletion-requests | no: a person signed in |
| Private test sets and included calls | /app/benchmarks | GET /v1/orgs/{orgId}/test-sets | yes |
| Private benchmark runs | /app/benchmarks | GET /v1/orgs/{orgId}/benchmarks | yes |
| One run: per-case results, segments, failure reasons | /app/benchmarks/[id] | GET /v1/orgs/{orgId}/benchmarks/{id} | yes |
| Make a private test set (JSON Lines) | /app/benchmarks | POST /v1/orgs/{orgId}/test-sets | yes |
| Add cases to a test set | /app/benchmarks | POST /v1/orgs/{orgId}/test-sets/{id}/cases | yes |
| Delete a test set and its results | /app/benchmarks | DELETE /v1/orgs/{orgId}/test-sets/{id} | yes |
| Run tools against a test set | /app/benchmarks | POST /v1/orgs/{orgId}/benchmarks | yes |
| Your tools' scores, inputs and rank (read-only) | /app/provider | GET /v1/orgs/{orgId}/provider | yes |
| Claim a provider | /app/provider | POST /v1/orgs/{orgId}/provider/claims | yes |
| Ask for a re-test (Insights, Pro) | /app/provider | POST /v1/orgs/{orgId}/provider/retests | yes |