---
title: "Resolve a handoff and close its conversation"
method: POST
path: "/v1/hitl/handoffs/{handoff_id}/resolve"
tags: ["hitl"]
---

# Resolve a handoff and close its conversation

`POST /v1/hitl/handoffs/{handoff_id}/resolve`

End the session: ``set_status(resolved)`` + conversation ``→ CLOSED``
with ``termination_reason = HANDOFF_RESOLVED``, in one transaction (§6.4).

## Path parameters

- `handoff_id` string, uuid, required

## Response `200`

Successful Response

- HandoffRead — The API-response shape for a single ``handoffs`` row (UI + channel runtime).
  - `id` string, uuid, required
  - `organization_id` string, uuid, required
  - `conversation_id` string, uuid, required
  - `conv_turn_id` string, uuid, nullable, required
  - `reason` string, nullable, required
  - `static_text` string, required
  - `status` 'requested' | 'assigned' | 'accepted' | 'resolved' | 'cancelled', required
  - `assignee` string, nullable, required
  - `source` 'workflow_terminal' | 'router' | 'policy', required
  - `packet` HandoffPacket, required — The complete, enriched handoff packet — the channel-runtime contract. Two halves, by who fills them: * *engine-supplied intent* (rides on the ``handoff`` signal): ``reason``, ``static_text``, ``context_vars``. * *service-enriched at record time* (needs DB access — ``packet.py``): ``summary`` (from ``conversations.summary``) and ``transcript_ptr``.
    - `static_text` string, required
    - `reason` string, nullable
    - `context_vars` object
    - `summary` string, nullable
    - `transcript_ptr` TranscriptPtr — A pointer into the conversation's append-only ``conv_messages`` transcript. ``up_to_seq`` is the highest ``conv_messages.seq`` written for the conversation at handoff time (``None`` when the thread has no messages yet) — so a human can replay everything the brain saw before it stepped aside. Stored on the seam packet as the compact string ``conv:{id}@{seq}`` (or ``conv:{id}`` when ``up_to_seq`` is None); this model is the parsed, API-facing form. :meth:`to_wire` / :meth:`parse` bridge the two.
      - `conversation_id` string, uuid, required
      - `up_to_seq` integer, nullable
    - `transfer_to` string, nullable
    - `transfer_label` string, nullable
  - `created_at` string, date-time, required
  - `resolved_at` string, date-time, nullable, required

## Other responses

- `422` — Validation Error

---

[API](https://skmtc.net/oneloop-hq/apis/feather-api.md) · [All operations](https://skmtc.net/oneloop-hq/apis/feather-api/llms.txt) · [OpenAPI document](https://skmtc-service-staging.skmtc.workers.dev/v1/apis/oneloop-hq/feather-api/versions/888bdd5c076e/schema)
