# API Conventions

Paths in this guide are written as `/v1/...`. The full URL is `https://portal.watcheye.com.au/api` followed by the path, so `GET /v1/account` is `GET https://portal.watcheye.com.au/api/v1/account`.

Country codes are ISO 3166-1 alpha-2 and are shown in uppercase (`AU`). The API accepts them in either case and always returns them in uppercase.

These conventions apply to every endpoint. Knowing them up front makes the per-operation reference easier to read, because each endpoint only documents what is specific to it.

## URLs

- Every endpoint is mounted under `/api/v1/`. The version number is part of the URL - see [API Versioning](/docs/guides/watcheye_api/api-versioning).
- Path segments are kebab-case: `/v1/id-checks`, `/v1/adhoc-checks/{uuid}`, `/v1/entities/{uuid}/archive`.
- Resource identifiers in paths are always UUIDs.

## JSON field names and query parameters

- Field names in request and response bodies are snake_case: `first_name`, `created_at`, `address_line1`, `is_immutable`.
- Query parameter names are snake_case: `per_page`, `created_at_from`, `archived`.
- Enum and discriminator string values are snake_case: `"individual"`, `"api_key"`, `"pep_sanction_check"`.

## Identifiers

- Every resource is identified by a `uuid` (RFC 4122). UUIDs are the only identifiers accepted in URLs and the only ones that should be persisted on your side as a foreign key into WatchEye.
- Some resources also carry a short, human-friendly identifier (`program_number`, `entity_number`, `check_number`, etc.) for display in dashboards. These are not stable lookup keys - always use the `uuid`.

## Dates and timestamps

- Timestamps are ISO 8601 UTC: `2025-01-15T03:00:00Z`.
- Calendar dates use `YYYY-MM-DD` unless otherwise noted (Medicare and ASIC/MSIC `card_expiry` accept `YYYY-MM`).

## Money

Monetary fields (`balance`, `credit_limit`, `available_credit`) are returned as decimal strings with 4 decimal places, for example `"1234.5678"`. Use a decimal arithmetic library, not floating point, when comparing or accumulating these values.

## Response envelopes

Every endpoint returns one of three shapes.

**Show, create, update, async accept, and singleton (`/account`) responses** wrap the resource under a `data` key:

```json
{ "data": { ... }, "api_reference": "9a4b1c8e-2f63-4f9a-9f3a-9b1f5a7c2d4f" }
```

**List responses** wrap the array under `data` and add a `meta` block describing the pagination:

```json
{
  "data": [ ... ],
  "meta": { "current_page": 1, "per_page": 30, "total": 42, "last_page": 2 },
  "api_reference": "9a4b1c8e-2f63-4f9a-9f3a-9b1f5a7c2d4f"
}
```

**Error responses** carry a `message` and, on validation failures, an `errors` map - see [Errors](/docs/guides/watcheye_api/errors).

`api_reference` is present on every response, success or failure, and is the unique UUID of the audit-log row for the call. Capture it in your logs and quote it when raising support tickets - see [Errors](/docs/guides/watcheye_api/errors) for why.

## Content type and request bodies

- Requests with a body (`POST`, `PATCH`) must send `Content-Type: application/json` and a valid JSON object as the body. Form-encoded bodies are not accepted.
- Empty `POST` and `PATCH` bodies should be sent as `{}` rather than no body at all.

## Authentication

Every endpoint requires an API key and secret combination sent as a Bearer token. See [Authentication and Authorization](/docs/guides/watcheye_api/authentication-and-authorization) for the header format. There are no anonymous endpoints.
