---
title: "Issue, verify, close, or heartbeat a signed permit for one governed action."
method: POST
path: "/v1/agent/enforcement"
---

# Issue, verify, close, or heartbeat a signed permit for one governed action.

`POST /v1/agent/enforcement`

## Request

- Base URL: `https://api.getmarrow.ai`
- URL: `https://api.getmarrow.ai/v1/agent/enforcement`
- Auth: HTTP bearer

## Request body

- object
  - `operation` 'issue' | 'verify' | 'close' | 'heartbeat', required
  - `agent_id` string, required
  - `session_id` string, required
  - `harness` string
  - `action` string
  - `action_type` string
  - `target` string
  - `surfaces` string[]: Canonical action surfaces. Verify must send the same set used to issue the permit; ordering is normalized and duplicates are rejected.
  - `proof_requirements` string[]: Exact server-required proof field names; broad proof categories do not satisfy these fields.
  - `decision_id` string
  - `gate_receipt_id` string
  - `owner_approval_receipt_id` string
  - `permit` string
  - `permit_id` string
  - `success` boolean
  - `evidence` object: Exact proof-field map. Every required field needs a non-empty validated value; an empty blockers array is allowed when blockers is required.
  - `expected_hooks` string[]
  - `observed_hooks` string[]

## Response `200`

Successful tenant-scoped response.

- object

## Other responses

- `400`: Invalid request.
- `401`: Missing or invalid API key.
- `403`: Authenticated identity is not allowed to perform this action.
- `429`: Capacity or fairness limit reached; follow Retry-After when present.

---

[API](https://skmtc.dev/getmarrow/apis/marrow-agent-governance-api.md) · [All operations](https://skmtc.dev/getmarrow/apis/marrow-agent-governance-api/llms.txt) · [OpenAPI document](https://skmtc.dev/getmarrow/apis/marrow-agent-governance-api/revisions/3b29084f6cc5?raw)
