---
title: "Mark a queued alarm as being worked (soft claim)"
method: POST
path: "/events/{event_id}/claim"
tags: ["events"]
---

# Mark a queued alarm as being worked (soft claim)

`POST /events/{event_id}/claim`

## Request

- Base URL: `https://api.verdun.ai` (the document declares no server; this is the origin it was published from)
- URL: `https://api.verdun.ai/events/{event_id}/claim`
- Auth: HTTP bearer

Called when an operator opens an alarm's review panel. The first operator to open it holds the claim for two minutes or until the alarm is triaged, whichever is shorter; other consoles show an "Operator working" badge on it and grey it out for other operators and monitoring managers (owners see the badge but are not greyed out). Reopening does not extend a claim. Monitoring managers take claims like operators; owners never do. Customer-side callers neither take claims nor receive claimant identity. Always 200 with the live claim for central staff, whoever holds it, or null; opening never blocks anyone (with `CLAIM_REFUSAL_ENABLED` on, what a claim does is refuse ANOTHER operator's close and outbound actions, see `POST /events/{id}/claim/take-over`). With claim cleanup enabled, alarms outside the active queue return null and are not claimed. This event-level acquire endpoint is separate from the renew-only endpoint `POST /events/{id}/claim/renew`; the whole-site claim (`POST /sites/{id}/claim`) is retired by default (`SITE_CLAIM_ENABLED`). Requires `review_label_alarms` and tenant scope (out of scope is 403, unknown is 404). Unlike renew, take-over and the two claim reads, acquire is NOT widened to the outbound-action permissions: it is the review-panel open, and a refused operator without `review_label_alarms` becomes the holder through take-over.

## Path parameters

- `event_id` string, required

## Query parameters

- `entry` string, nullable: Logged only: how this acquire was reached (`manual`, `advance`, `review_mount`, `deep_link`); any other value is logged as `other`. It never changes behaviour. Absent from an older console.

## Response `200`

Successful Response

- ClaimEventResponse
  - `claim` AlarmClaim, required
    - `operator_id` string, required: The operator holding the alarm
    - `operator_name` string, nullable: Their display name; null if the operator no longer exists
    - `claimed_at` string, required: When the claim was taken (ISO 8601, UTC)
    - `expires_at` string, required: When the claim lapses (ISO 8601, UTC)
    - `expires_in_seconds` integer, required: Seconds left on the claim, computed server-side. Time the claim from this against the local clock at receipt, not from `expires_at`, so a skewed workstation clock does not move it.
    - `generation` string, nullable: Ownership generation (a UUID): it changes whenever the claim's HOLDER changes (acquire, take-over) and never on a renewal. Echo it on `POST /events/{id}/claim/acting` and its cancel; a write carrying an old one is rejected. Null while CLAIM_ESCALATION_ENABLED is off, or on a claim stamped before generations existed (the holder's next renew fills it in).
  - `renewed` boolean, nullable: Present only on `POST /events/{id}/claim/renew`: true when the caller's own live claim was renewed (`claim` is then the renewed claim), false when it was NOT (the claim was lost or never held: `claim` is another operator's live claim, or null). A renew never acquires. Absent on an ordinary claim.
  - `reservation` Reservation: An alarm reserved for a focuser or held by a site hold. A reservation is NOT a claim: it has no TTL and lives under the claim.
    - `origin` 'focus' | 'story': `story` for a site hold. A reservation from an older api has no `origin`: it is a Focus.
    - `focus_id` string, required: The focus generation or site hold that reserved this alarm.
    - `operator_id` string, required: The focuser or holder.
    - `operator_name` string, nullable: Their display name; null if the operator no longer exists.
    - `reserved_at` string, required: When the alarm entered the queue and was reserved (ISO 8601, UTC).
    - `elapsed_seconds` integer, required: Server-computed now - reserved_at, for the age display; the unreviewed-age cue applies to reserved alarms exactly as to free ones.
    - `engaged` boolean, nullable: Story only: the current holder has opened this alarm.
    - `open` boolean, nullable: Story only: the holder's page is open (no deadline while it is).
    - `return_at` string, nullable: Story only: when the unattended hold returns its alarms (ISO 8601, UTC); null while `open`. After a clean leave, about 30 s after it unless an earlier idle or new-alert deadline or a live call changes it.
    - `now` string, nullable: Story only: the server clock `return_at` is measured against.
    - `serious_unopened` integer, nullable: Story only: serious alarms the holder has not opened (visibility only).
    - `oldest_serious_queued_at` string, nullable: Story only: when the oldest of those entered the queue.

## Other responses

- `422`: Validation Error

---

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