Teams & approval groups

Two separate concepts share this page because people mix them up: team members collaborate in your dashboard, while approval groups decide what your agents may do. Different people, different mechanics.

Team members

Members are developers with dashboard access: they see the audit log, manage API keys and webhooks, and send test approvals. Invite them from Settings → Team; they get an email with an accept link and sign in with their own account.

Roles

RoleCan do
OWNEREverything, including billing, workspace rename, and team management.
ADMINEverything except billing and rename: invites, groups, keys, webhooks.
MEMBERView everything, create API keys, send test approvals.

Seats

Seats include the owner, and pending invites hold a seat until they expire (7 days): Hobby 1 · Pro 10 · Business 25 · Enterprise custom.

Approval groups

Groups are named escalation targets: finance, security, platform. Group members are plain email addresses, not accounts. They approve through the same magic links as any approver. Create groups under Dashboard → Groups (Pro plan and up).

Escalate from your agent code by targeting the group key:

agent.ts
await fetch("https://confirm.dev/api/v1/requests", {
  method: "POST",
  headers: { Authorization: `Bearer ${process.env.CONFIRM_API_KEY}`,
             "Content-Type": "application/json" },
  body: JSON.stringify({
    summary: "Refund $1,850 to customer #7133",
    payload: { action: "refund", amount: 1850 },
    notify: refund > 1000 ? "group:finance" : "support-lead@company.com",
  }),
});

Semantics

  • Fan-out. Every group member is emailed their own single-purpose magic link the moment the request is created.
  • First decision wins. The request resolves exactly once. Everyone else's link shows "already resolved" afterward.
  • Named accountability. resolvedByEmail is the specific person who decided, not the group, in the API, webhooks, and audit log.
  • Fail loud. Unknown keys return 404 unknown_group, an empty group returns 400 empty_group, and groups on a plan without them return 403 plan_required. Requests are never silently rerouted.
Put the escalation thresholds in your agent code, not in the group. Groups answer "who decides"; your code answers "when to ask". This keeps policy in version control where it can be reviewed.

Limits

PlanGroupsMembers per group
Hobby
Pro1025
BusinessUnlimited100
EnterpriseCustomCustom