---
title: Rate Limiting
description: Per-key and per-organization rate limits, the Retry-After header, and the audit log written on every authenticated request.
nav: Concepts / Rate Limiting
order: 3
version: v1
source: handwritten
updated: 2026-06-01
---

# Rate Limiting

The Huli Public API enforces rate limits at two levels: per API key and per organization.
Every authenticated request also writes an immutable audit record.

## Limits

| Ceiling                             | Scope                                          | Reset window            |
| ----------------------------------- | ---------------------------------------------- | ----------------------- |
| Per-key request rate                | Configurable per API key (default: 60 req/min) | 1-minute sliding window |
| Per-org request rate                | Shared across all keys in the organization     | 1-minute sliding window |
| Token issuance (`POST /auth/token`) | 20 requests/minute per source IP               | 1-minute fixed window   |

The per-key default and the per-org ceiling are set when the API key is provisioned in
Practice Settings. Contact your organization admin to review or raise the limits for your
key.

## Response headers

Every response includes rate-limit headers:

```http
X-RateLimit-Limit: 60
X-RateLimit-Remaining: 47
X-RateLimit-Reset: 1748808720
```

- `X-RateLimit-Limit` — the current limit for this key (requests per minute).
- `X-RateLimit-Remaining` — requests remaining in the current window.
- `X-RateLimit-Reset` — Unix timestamp (UTC) when the window resets.

## When the limit is exceeded

<StatusBadge code="429" /> with error code `HPB-00105`:

```json
{
  "resourceType": "OperationOutcome",
  "issue": [
    {
      "severity": "error",
      "code": "throttled",
      "diagnostics": "HPB-00105: Rate limit exceeded"
    }
  ]
}
```

The response also includes a `Retry-After` header with the number of seconds to wait:

```http
Retry-After: 14
```

Respect this header. Retry immediately after a `429` without the `Retry-After` delay
results in another `429` and increases the reset time.

## Recommended retry strategy

For transient failures (`429` and `5xx`):

1. Read `Retry-After` on `429` responses. Wait exactly that many seconds.
2. For `5xx` responses: exponential backoff starting at 1s, cap at 60s, jitter ±10%.
3. Do not retry `4xx` responses other than `429` — they indicate a request error that
   retrying will not fix.

Never auto-retry `401`, `403`, or `404`.

## Audit log

Every authenticated request to the API writes an audit record. This is a NOM-024
compliance requirement (Mexico), not an optional feature.

Each record captures:

- The FHIR resource type and resource ID involved (e.g., `Patient` and its UUID).
- The API key identifier and the organization the request was made for.
- The query parameters used (for search operations).
- The number of resources returned.
- The client IP address.
- The request correlation ID — also returned in the `X-Correlation-Id` response header.
- A timestamp (ISO-8601 with UTC offset).

**Retention:** audit records are retained for 7 years. They are immutable once written.

**Read access:** audit records are not accessible via the public API in v1. Access is
available to authorized Huli personnel for compliance audits.

**PHI in audit records:** the recorded search parameters may contain patient identifiers
(e.g., `identifier=https://www.gob.mx/curp|FEME800614MDFRRR09`). Audit records are stored
with the same access controls as the primary data.
