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

# Request and response conventions

> Apply consistent URLs, headers, media types, schema behavior, response envelopes, and binary download handling.

## Base URL and HTTPS

All public requests use HTTPS and are relative to:

```text theme={"theme":{"light":"github-light","dark":"github-dark"}}
https://api.jobhandy.io/v1
```

The `v1` segment is part of the public version contract.

## Standard request headers

| Header                           |            Required | Purpose                                             |
| -------------------------------- | ------------------: | --------------------------------------------------- |
| `X-API-Key`                      | Protected endpoints | Server-to-server authentication                     |
| `X-Tenant-ID`                    |         Conditional | Narrows or resolves tenant context where documented |
| `X-Request-ID`                   |     No, recommended | Correlates one HTTP request attempt                 |
| `Content-Type: application/json` |         JSON writes | Declares the request body media type                |
| `Accept: application/json`       |   Optional for JSON | Requests a JSON representation                      |

Unknown or unsupported headers may be rejected with `UNSUPPORTED_HEADER`.

## JSON request behavior

* Send UTF-8 JSON.
* Request schemas are closed; unknown properties are rejected.
* `PATCH` bodies must contain at least one documented property.
* Omitted patch properties remain unchanged.
* A nullable patch property can be cleared with JSON `null`.
* An empty string is a string value and is not equivalent to `null` or omission.
* Enum values are case-sensitive.
* Documented JSON request bodies have a maximum request size of 5 MiB.

```json theme={"theme":{"light":"github-light","dark":"github-dark"}}
{
  "phoneNumber": null
}
```

This clears a nullable phone number. Omitting `phoneNumber` would leave it unchanged.

## JSON response behavior

Successful resource responses use the schema documented by the operation. Collection responses include items and page metadata defined by their resource-specific page schema.

Clients should tolerate unknown response properties because additive fields can be introduced without changing the `/v1` path.

## Error envelope

Every public API error uses the same top-level envelope:

```json theme={"theme":{"light":"github-light","dark":"github-dark"}}
{
  "error": {
    "code": "INVALID_API_KEY",
    "message": "The supplied API key is missing, invalid, or inactive.",
    "requestId": "018f3d9a-7dfb-7a23-b4b4-9f7e4b19d4b4"
  }
}
```

Use `error.code` for branching, `error.message` for diagnostics, and `error.requestId` for correlation.

## Binary responses

Attachment and payroll download endpoints return binary or text content rather than a JSON resource.

* Treat the document identifier as opaque.
* Use the response `Content-Type` rather than guessing from the endpoint.
* Use the response filename header when supplied by the operation.
* Do not parse an error body as a file; inspect the HTTP status and media type first.
* Protect downloaded files after they leave the API boundary.

## Request-size limits

| Request type                     | Public contract limit |
| -------------------------------- | --------------------: |
| Documented JSON write body       |                 5 MiB |
| Complete incident multipart body |                 5 MiB |
| Incident file count              |          1 to 5 files |

The multipart limit applies to the complete encoded body, not only the sum of original file sizes.
