---
title: "Hooks Stop"
method: POST
path: "/hooks/stop"
---

# Hooks Stop

`POST /hooks/stop`

## Request

- Base URL: `https://usemeridian.us` (the document declares no server; this is the origin it was published from)
- URL: `https://usemeridian.us/hooks/stop`
- Auth: none declared

Claude Code / Codex Stop hook.

Accepts {project_id?, session_id?, cwd?, hostname?}. Fires auto_capture +
a delta handoff so a delta is produced even when the executor disconnects
without calling generate_handoff itself.

Best-effort / non-blocking: this never raises out and never returns 4xx/5xx
for a missing session — a missing/unresolvable session yields
``{"ok": true, "handoff": null, "reason": "no session"}`` and any
generate_handoff failure yields ``{"ok": true, "handoff": null, "error": ...}``
(both 200). The agent does not wait for this before exiting.

Resolution: an explicit ``session_id`` is preferred; otherwise the
most-recent active session for the project (resolved from ``project_id`` or,
failing that, the ``cwd``/``hostname`` the same way the SessionStart hook
routes) is handed off.

Hosted callers can authenticate with Authorization: Bearer sk_meridian_...
to route directly to their tenant DB. Local/browser-session behavior is
unchanged when no Bearer token is supplied.

b4f4627f — two guards layered on top of the existing best-effort contract:

* ``stop_hook_active`` (Claude Code sets this true when the CURRENT Stop
  event was itself caused by a PREVIOUS Stop hook's exit-2 block) short-
  circuits immediately, before any DB/background work — the same
  infinite-retrigger guard already baked into every rendered Stop-hook
  script (sprint_guard.{sh,ps1}, and now every custom Stop hook — see
  ``handoff._render_custom_hook_files``), applied at this route's own
  entry point too, in case a caller ever forwards the real hook payload
  here (the shipped hooks.sh/.ps1 STOP_CMD is a fixed curl call that
  never does today, but this route accepts arbitrary POST bodies and
  must not assume that stays true forever).
* a same-session in-flight guard (``_STOP_HOOK_INFLIGHT``) skips a
  SECOND concurrent call for a session already being processed rather
  than racing two concurrent ``generate_handoff(mode="delta")`` calls
  for the same ``session_id``.

## Request body

- object

## Response `200`

Successful Response

- object

## Other responses

- `422`: Validation Error

---

[API](https://skmtc.dev/usemeridian/apis/meridian.md) · [All operations](https://skmtc.dev/usemeridian/apis/meridian/llms.txt) · [OpenAPI document](https://skmtc.dev/usemeridian/apis/meridian/revisions/f37a894bd374?raw)
