---
title: "Resume a matching session (leg F)"
method: POST
path: "/api/matching-sessions/{id}/resume"
tags: ["MatchingSessions"]
---

# Resume a matching session (leg F)

`POST /api/matching-sessions/{id}/resume`

## Request

- Base URL: `https://api.production.yourmedley.com`
- URL: `https://api.production.yourmedley.com/api/matching-sessions/{id}/resume`
- Auth: HTTP bearer

Re-mint a fresh single-use navigation token for an existing matching attempt.

Access is STAFF-only (`internal_admin`, `internal_user`), enforced by the role gate on
this route. There is no row-level ownership check: any staff user may resume any
matching session. This is deliberate, so several staff can collaborate on one
matching-server session. `matching_sessions.opened_by_admin_id` still records who
STARTED the session. The resuming user is recorded in the application log only.

Note: this router mounts at the top level (`/api/matching-sessions`), outside the
`/api/cohorts` tree, so it does NOT inherit `requireCohortAccess`. The role gate on
this route is the only access control here. Add one to every new route on this router.

On success the row transitions to `in_progress` (per the §7 state machine). The
response includes `status` so the SPA can update its sessions list immediately
without a follow-up GET.

Per §11.7, an outbound failure to matching-server does NOT mutate the row's status.
The caller can retry by clicking Resume again.

## Path parameters

- `id` string, uuid, required

## Request body

- object

## Response `200`

Token re-minted. Row transitioned to `in_progress`.

- ResumeMatchingSessionResponse
  - `matching_url` string, uri, required: matching-server URL with a freshly minted single-use navigation token
  - `status` 'in_progress', required: The row's status after a successful resume. Always `in_progress` per the §7 state machine. Returned so the SPA can update its sessions list immediately without a follow-up GET.

## Other responses

- `401`: Unauthorized -- missing or invalid SGOS session.
- `403`: Forbidden -- the caller is not staff. The body is `{ success: false, error: 'Insufficient permissions' }` and carries NO `code` field.
- `404`: Matching session not found. Code: `MATCHING_SESSION_NOT_FOUND`.
- `409`: Row exists but cannot be resumed. Codes: - `MATCHING_SESSION_EXPIRED` -- row's status is `expired` (terminal). - `MATCHING_SESSION_STILL_CREATING` -- row's status is `submitting` (leg C in flight). - `MATCHING_SESSION_FAILED_NO_EXTERNAL_SESSION` -- row's status is `failed` and no external_session_id exists, so there is nothing on matching-server to re-mint.
- `502`: Outbound matching-server call failed. Codes: - `MATCHING_SERVER_AUTH_REJECTED` -- matching-server returned 401 (secret drift; oncall alert emitted). - `MATCHING_SERVER_UNREACHABLE` -- network failure or non-2xx other than 401. - `MATCHING_SERVER_INVALID_RESPONSE` -- response missing `token`.
- `503`: `MATCHING_SERVER_NOT_CONFIGURED` -- matching-server env vars are missing (only possible in non-production deployments).

---

[API](https://skmtc.dev/withmedley/apis/medley-api.md) - [All operations](https://skmtc.dev/withmedley/apis/medley-api/llms.txt) - [OpenAPI document](https://skmtc.dev/withmedley/apis/medley-api/revisions/40aaac5ca6bd?raw)
