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

# Identifier Contract

> Every API response carries a durable request_id and message_id you can use to retrieve the inference record and contact support.

Every response from the HASP AI API includes two complementary identifiers:

* **`request_id`** — the full identifier for the inference request, in `req_<ulid>` format.
* **`message_id`** — the ULID portion of `request_id` (without the `req_` prefix), used as the lookup key for `GET /v1/ai/messages/{id}`.

Both are durable: once issued, they are never recycled, never reused, and always retrievable.

## Where to find them

**Non-streaming responses** (`POST /v1/ai/chat` or `POST /v1/messages` with `stream: false`):

```json theme={null}
{
  "meta": {
    "request_id": "req_01ABC123DEF456GHI789JKL012"
  }
}
```

**Streaming responses** (`stream: true`): the `run.started` SSE event carries both:

```
event: run.started
data: {"request_id":"req_01ABC123DEF456GHI789JKL012","message_id":"01ABC123DEF456GHI789JKL012"}
```

**Anthropic-compat surface** (`POST /v1/messages`): the standard Anthropic `id` field is the `msg_<ulid>` form of the message\_id:

```json theme={null}
{
  "id": "msg_01ABC123DEF456GHI789JKL012",
  "type": "message"
}
```

## Format

`request_id` values begin with `req_` followed by a 26-character ULID. `message_id` is the same ULID without the prefix. ULIDs are:

* **Lexicographically sortable** — you can range-query by prefix.
* **Timestamp-embedded** — the first 10 characters encode millisecond creation time.
* **URL-safe** — no encoding required in path parameters.

## Retrieving a request

The retrieval endpoint accepts the ULID in any of its three equivalent forms:

```bash theme={null}
# Bare ULID
curl https://api.usehasp.com/v1/ai/messages/01ABC123DEF456GHI789JKL012 \
  -H "Authorization: Bearer hasp_api_live_<key>"

# msg_ prefix (Anthropic-compat form)
curl https://api.usehasp.com/v1/ai/messages/msg_01ABC123DEF456GHI789JKL012 \
  -H "Authorization: Bearer hasp_api_live_<key>"

# req_ prefix (request_id form)
curl https://api.usehasp.com/v1/ai/messages/req_01ABC123DEF456GHI789JKL012 \
  -H "Authorization: Bearer hasp_api_live_<key>"
```

The response includes the record's metadata and content (when stored):

```json theme={null}
{
  "success": true,
  "data": {
    "id": "msg_01ABC123DEF456GHI789JKL012",
    "request_id": "req_01ABC123DEF456GHI789JKL012",
    "org_id": "<org-ulid>",
    "conversation_id": "<conversation-ulid or null>",
    "model": "claude-sonnet-4-6",
    "role": "assistant",
    "usage": {
      "input_tokens": 120,
      "output_tokens": 480,
      "cache_read_input_tokens": 0,
      "cache_write_input_tokens": 0
    },
    "credits_consumed": 0.006,
    "content": "...",
    "created_at": "2026-04-01T12:00:00+00:00"
  },
  "meta": {
    "request_id": "req_01ABC123DEF456GHI789JKL012"
  }
}
```

`content` is `null` when `store: false` was passed or the organization's storage mode is set to None. Lookups are always scoped to your organization — you cannot retrieve another organization's records.

## Durability guarantee

A shell row is created **before** `run.started` fires — even if the request fails mid-stream, the record is retrievable with whatever state was captured at that point. Records are retained per your organization's data retention policy (default: 7 years for HIPAA-covered entities).

## Using it for support

When filing a support request, include the `request_id`. Support staff can use it to:

* Retrieve the exact request and response payload (subject to BAA and access controls).
* Cross-reference the audit log entry for the same request.
* Identify the model version, inference latency, and any compliance events triggered.

Do not log or store `request_id` values in public-facing error messages — they are internal identifiers, not user-facing content.
