Skip to main content
Skip to main content
SeaOtter
See demoPrivacyDownload for macOS

← All developer docs

DEVELOPERS — CHECKPOINTS & THE MESH

The run pauses for your call. Agents check each other's work.

Two contracts on the same key: checkpoints hold a running workflow until someone — or something — decides, and the mesh turns agent moments into supervision with receipts that name a real check.

On this pageCheckpointsAgents checking agents

CHECKPOINTS — THE RUN WAITS FOR YOU

When it matters, the run holds — and asks.

Steering is not a dial you watch; it's a moment the run stops and waits for a call. When an agent SeaOtter manages hits a question, real uncertainty, or a change big enough to matter, it publishes a checkpoint — a typed object your code, your dashboard, and your phone-sized attention span can all act on. Nothing moves until someone (or something you wrote) answers: let it continue, send it back, or stop it.

List what's waiting on you

Any signed-in surface can read the queue. web_decide_enabled tells older clients the decision buttons are live here too.

curl -s 'https://api.seaotter.ai/api/v1/checkpoints?state=pending&limit=50' \
  -H "Authorization: Bearer $OTTER_KEY"
# -> { "checkpoints": [ {
#        "schema": "seaotter.checkpoint.v1",
#        "checkpoint_id": "ckpt-...",
#        # kinds: managed_agent_question |
#        #   seaotter_uncertainty | important_change
#        "kind": "managed_agent_question",
#        "importance": "hold",     # or hard_stop
#        "headline": "Send the refund email to 214 customers?",
#        "agent": { "display_name": "support-drafter" },
#        "forecast": [ { "label", "before", "after" } ],
#        "actions": [ { "action": "continue" },
#          { "action": "send_back" }, { "action": "stop" } ]
#      } ],
#      "count": 1, "web_decide_enabled": true }

Decide — from anywhere you're signed in

One POST settles it: the run continues, goes back to fix first, or stops. Every decision stamps who decided from which surface and lands a signed audit row.

curl -s -X POST \
  https://api.seaotter.ai/api/v1/checkpoints/$CKPT_ID/decide \
  -H "Authorization: Bearer $OTTER_KEY" \
  -H 'Content-Type: application/json' \
  -d '{ "action": "send_back",
        "note": "Tighten the refund wording first." }'
# -> { ..., "state": "decided",
#      "decision": { "action": "send_back",
#        "decided_by": { "surface": "web",
#                         "actor": "you@acme.com" } } }
# First terminal decision wins; a later decide
# on the same checkpoint changes nothing.

One life, four states

pending → decided → resolved → expired

A checkpoint is born pending — the run is holding. A decision (from the app, the web dashboard, or your own code) moves it to decided and the run acts on your call. When the agent finishes acting on it, the Mac app marks it resolved with an outcome line. A pending checkpoint nobody answers expires — it never silently self-approves.

Who publishes, who decides

The Mac app is the surface that publishes checkpoints (it is the one watching the agent work) and marks them resolved afterwards. Deciding is deliberately wider: the app, the web dashboard's "Waiting on you" panel, or any code holding your key can answer — so the person with context can make the call from wherever they are.

Every decision is recorded: who, from where, what changed, in a tamper-evident audit trail — the same record the rest of the platform writes.

AGENTS CHECKING AGENTS — SUPERVISION ON HOOKS

Wire one agent to watch another's work.

Your agents already announce the moments that matter — a piece of work finished, a change applied, a session stuck. The mesh turns those moments into supervision: link a supervisor agent to a supervised one, tell it which moments to care about, and land its findings as receipts that reference a real check — not a vibe. This is how a fleet reviews itself while you sleep.

1 — Link supervisor to supervised

One POST declares the relationship and the moments it cares about. Closed vocabulary: work_produced · work_applied · grade_completed · session_started · session_idle · agent_blocked · agent_error · peer_note. Mesh calls ride your signed-in SeaOtter session ($SEAOTTER_SESSION below) — the Mac app wires this for embedded agents automatically; your sk-otter key is for the checking surface, not the mesh.

curl -s -X POST https://api.seaotter.ai/api/v1/mesh/links \
  -H "Authorization: Bearer $SEAOTTER_SESSION" \
  -H 'Content-Type: application/json' \
  -d '{ "supervisor":  { "agent_id": "reviewer-1",
          "kind": "embedded_app", "display_name": "Reviewer",
          "surface": "claude_code" },
        "supervised": { "agent_id": "drafter-7",
          "kind": "embedded_app", "display_name": "Drafter",
          "surface": "cursor" },
        "hook_events": ["work_produced", "agent_error"],
        "mode": "observe", "visibility": "structural" }'
# 201 -> { "schema": "seaotter.agent_link.v1",
#   "link_id": "link-...", "status": "active",
#   "summary": "Reviewer checks Drafter's work when it
#     finishes a piece of work or hits an error" }

2 — A moment fires

The supervised side (the Mac app's embedded adapters, or your own harness) posts the moment as an event. Work-shaped moments carry a structural artifact ref — never the raw content.

curl -s -X POST https://api.seaotter.ai/api/v1/mesh/events \
  -H "Authorization: Bearer $SEAOTTER_SESSION" \
  -H 'Content-Type: application/json' \
  -d '{ "event_id": "evt-01", "kind": "work_produced",
        "ts": "2026-07-21T14:31:00Z", "seq": 1,
        "source": { "agent_id": "drafter-7",
          "kind": "embedded_app", "surface": "cursor" },
        "artifact_ref": { "label": "src/refund_email.md",
          "sha256": "..." } }'
# 202 -> { "accepted": true, "deduplicated": false, ... }
# supervisor side: poll
#   GET /api/v1/mesh/events?cursor=...&kind=work_produced

3 — Land the verdict receipt

The supervisor runs the artifact through a real check first (POST /api/v1/eval/feedback -> run_id), then posts the receipt naming that run. A receipt with no run behind it is refused.

curl -s -X POST https://api.seaotter.ai/api/v1/mesh/verdicts \
  -H "Authorization: Bearer $SEAOTTER_SESSION" \
  -H 'Content-Type: application/json' \
  -d '{ "verdict_id": "v-01", "link_id": "link-...",
        "event_id": "evt-01",
        "supervisor": { "agent_id": "reviewer-1",
          "kind": "embedded_app", "surface": "claude_code" },
        "supervised": { "agent_id": "drafter-7",
          "kind": "embedded_app", "surface": "cursor" },
        "artifact_ref": { "label": "src/refund_email.md",
          "sha256": "..." },
        "eval_run_id": "$RUN_ID",
        "score": 0.58, "band": "route_to_fix",
        "ts": "2026-07-21T14:32:10Z" }'
# 201 -> { "schema": "seaotter.supervision_verdict.v1",
#   ..., "summary": "Reviewer checked Drafter's work:
#     needs a fix before it ships" }

The supervision loop

link → moment fires → supervisor checks → receipt lands

One link says who watches whom, and on which moments (in the API: hook_events — when the supervised agent finishes a piece of work, applies it, gets stuck, or errors). When one of those moments fires, an event lands on the mesh. The supervisor picks it up, runs the work through a real check, and posts a verdict receipt that names the check it came from. The /team page draws who-checks-whom from these same objects.

Boundaries the API enforces (not asks nicely about)

  • No agent supervises itself — a self-link is refused outright.
  • Watching is structural by default: refs, hashes, timings — the raw work stays out unless a consent receipt says otherwise.
  • mode:"observe" watches; mode:"gate" holds. A gate link needs an artifact_lease_ref (which document it may hold), and a held piece of work only moves when a real check says ship (released), a check says otherwise (returned), or you release it yourself (POST /api/v1/mesh/events/{id}/release) — you always outrank the mesh.
  • Events without an active watcher are refused — no write-only surveillance exhaust.
  • Every verdict receipt lands a tamper-evident audit row, same trail as everything else.
SeaOtterSeaOtter checks your AI agents' work before you trust it.

Product

  • Download for macOS
  • Live demo
  • Pricing
  • Sign in

Developers

  • Docs and the API
  • Agent-native quickstart
  • llms.txt — for agents

Company

  • SeaOtter for enterprise
  • Investors
  • Contact

© 2026 SeaOtter.

PrivacyTerms