> ## Documentation Index
> Fetch the complete documentation index at: https://docs.punchrescue.com/llms.txt
> Use this file to discover all available pages before exploring further.

# Introduction

> Integrate external systems with Punch Rescue — declare emergencies, read org categories, and receive real-time webhook deliveries.

## Welcome

The **Punch Rescue Public API v1** lets external systems integrate directly with the Rescue platform. Use it to declare emergencies, re-categorize them, mark them resolved, and read an organization's category catalog and audit log.

Every emergency transition fan-outs in real time to the org's base-station devices **and** to any registered webhook subscribers — so your integration, our responders, and downstream partners stay in lockstep.

## Base URL

| Environment | Base URL                                    |
| ----------- | ------------------------------------------- |
| Production  | `https://api.punchrescue.com/api/public/v1` |

The OpenAPI document is published at `https://api.punchrescue.com/api/public/v1/openapi.json`. It's the one path on the API that doesn't require authentication, so you can paste it into Claude or a codegen tool before issuing your first request.

<Note>
  Need a sandbox before going live? Reach out to your Rescue contact — we'll provision a dev key and share the corresponding base URL out-of-band.
</Note>

## Authentication

All endpoints (except `GET /openapi.json`) require an API key issued by Rescue. Send it as a Bearer token on every request.

```bash theme={null}
curl https://api.punchrescue.com/api/public/v1/orgs/{orgId}/emergencies \
  -H "Authorization: Bearer $RESCUE_API_KEY" \
  -H "Content-Type: application/json"
```

API keys are minted by a Rescue admin and shown **exactly once** at creation. Each key carries:

* **A subject** — `partner`, `enterprise`, or `org` — which determines the set of organizations the key can act on (every org under the subject's hierarchy).
* **An optional `allowedOrgIds` whitelist** — when set, further restricts the key to a subset of orgs under its subject.
* **Permissions** — the v1 vocabulary is `read` and `write`. Future versions may introduce granular `<resource>:<action>` permissions additively.
* **An optional `activeUntilDate`** — hard expiration checked on every request.

OpenAPI security scheme:

```json theme={null}
"securitySchemes": {
  "BearerAuth": {
    "type": "http",
    "scheme": "bearer",
    "bearerFormat": "rk_live_<8hex><64hex>"
  }
}
```

<Note>
  Treat your API key like a password. Never commit it to source control or ship it in client-side code. If a key is leaked, contact Punch Rescue support to revoke (`status=inactive`) or rotate it.
</Note>

## Core concepts

<AccordionGroup>
  <Accordion title="Organization" icon="building">
    The tenant scope every emergency, category, and audit-log entry belongs to. Reference an organization by its Punch Rescue `orgId` (UUID). Your API key must cover that org through its subject (`org` / `enterprise` / `partner`) and any `allowedOrgIds` whitelist — `403` is returned otherwise.
  </Accordion>

  <Accordion title="Category" icon="tag">
    A classification for emergencies (e.g. *Medical*, *Fire*, *Security*). Each category has a stable `categoryId`, plus `name`, `color`, and `severity`. Categories are **read-only** on the public API — they're authored inside the Punch Rescue admin console.
  </Accordion>

  <Accordion title="Emergency" icon="bell">
    A real-world incident tracked through three event types:

    * **`emergency.declared`** — created via `POST /orgs/{orgId}/emergencies`.
    * **`emergency.categorized`** — re-categorized via `PATCH /orgs/{orgId}/emergencies/{emergencyId}`.
    * **`emergency.resolved`** — closed via `POST /orgs/{orgId}/emergencies/{emergencyId}/resolutions`.

    Every transition fan-outs to base-station devices and to matching webhook subscribers.
  </Accordion>

  <Accordion title="Webhook delivery" icon="webhook">
    Rescue pushes every emergency transition to registered subscribers as a stable `PublicWebhookEnvelope`. Subscriptions can be scoped at the partner, enterprise, or org level with an optional `allowedOrgIds` whitelist — so a single subscription can cover many orgs. See [**Webhooks**](/api-reference/webhooks) for the full envelope, event catalog, delivery semantics, and dedup/ordering rules.
  </Accordion>
</AccordionGroup>

## A typical integration flow

<Steps>
  <Step title="Discover an org's categories">
    `GET /orgs/{orgId}/emergencies/categories` returns the `categoryId` values available for that org. (Categories are managed inside Rescue — there's no public CRUD.)
  </Step>

  <Step title="Declare an emergency">
    `POST /orgs/{orgId}/emergencies` with a `categoryId` (and an optional `externalId` for your own correlation). Returns `201 Created` with the full emergency record. Rescue resolves the category color and dispatches a real-time alert to every base-station device in the org.
  </Step>

  <Step title="Update or re-categorize">
    `PATCH /orgs/{orgId}/emergencies/{emergencyId}` to change the category or other mutable attributes. Returns `200 OK` and fires an `emergency.categorized` webhook.
  </Step>

  <Step title="Resolve">
    `POST /orgs/{orgId}/emergencies/{emergencyId}/resolutions`. Returns `201 Created` with the resolution record and fires an `emergency.resolved` webhook. Idempotent — resolving an already-resolved emergency returns the existing resolution.
  </Step>

  <Step title="Receive webhook deliveries">
    Have your Rescue admin register a webhook subscription scoped to your partner/enterprise/org. You'll receive every `emergency.declared` / `emergency.categorized` / `emergency.resolved` event for the orgs your subscription covers. See [**Webhooks**](/api-reference/webhooks) for the envelope shape, the full event catalog, and how to secure and test your endpoint.
  </Step>
</Steps>

## Endpoint groups

<CardGroup cols={2}>
  <Card title="Categories" icon="tags" href="/api-reference/endpoint/emergencies-categories-list">
    Read-only listing of an org's category catalog.
  </Card>

  <Card title="Emergencies" icon="siren" href="/api-reference/endpoint/emergencies-create">
    Declare, list, fetch, update, and resolve emergencies.
  </Card>

  <Card title="Webhooks" icon="webhook" href="/docs/public-api-webhooks">
    Receive emergency and device events in real time — envelope, event catalog, and delivery semantics.
  </Card>
</CardGroup>

## Responses & errors

Successful responses use standard HTTP codes — `200 OK`, `201 Created`, `204 No Content`. Emergency writes are synchronous: the response reflects committed state. [Webhook](/api-reference/webhooks) fan-out happens asynchronously after the response is sent, with retries on transient failures.

Validation failures return `422 Unprocessable Entity` with a structured payload pointing at the offending field:

```json theme={null}
{
  "detail": [
    {
      "loc": ["body", "categoryId"],
      "msg": "Field required",
      "type": "missing"
    }
  ]
}
```

Authorization failures:

* `401 Unauthorized` — missing, invalid, expired, or revoked API key.
* `403 Forbidden` — key is valid but its subject doesn't cover the requested `orgId` (or the org isn't in `allowedOrgIds`).

5xx responses indicate retriable server errors. `Idempotency-Key` isn't supported yet — when a write returns 5xx with no body, fetch the emergency via `GET /orgs/{orgId}/emergencies/{emergencyId}` (or look it up by your own `externalId` on the list endpoint) before retrying to avoid duplicates.

<Note>
  Need help or hitting unexpected behavior? Reach out to your Rescue contact with the request ID returned by the API — it's the fastest way for us to trace what happened.
</Note>
