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

# HTTP

> Methods, content types, status codes, and TLS requirements shared by every BlooBank endpoint.

The BlooBank Transactions Engine API is a **REST API over HTTPS**. This page documents the transport-level contract — what every endpoint shares, regardless of the resource.

## Base URL

```
https://txengine.bloobank.com/txengine/v1
```

All paths in this reference are relative to this base. `v1` is the major version of the API contract; breaking changes will be published under a new major version.

## Methods

The API uses HTTP methods with their standard REST semantics.

| Method   | Use                                                                    | Safe? |                          Idempotent?                          |
| -------- | ---------------------------------------------------------------------- | :---: | :-----------------------------------------------------------: |
| `GET`    | Retrieve a resource or list.                                           |   ✅   |                               ✅                               |
| `POST`   | Create a resource.                                                     |   ❌   | ❌ (use [`idempotencyKey`](/get-started/concepts/idempotency)) |
| `PUT`    | Update a resource or trigger a state transition (`approve`, `cancel`). |   ❌   |                               ✅                               |
| `DELETE` | Not used.                                                              |   —   |                               —                               |

<Note>
  **`POST` and idempotency.** Create operations are not idempotent by default. Always supply an `idempotencyKey` when the operation has financial side effects — see [Idempotency](/get-started/concepts/idempotency).
</Note>

## Content types

All request and response bodies are JSON.

| Header                       | Value                             |
| ---------------------------- | --------------------------------- |
| `Content-Type` (request)     | `application/json; charset=utf-8` |
| `Accept` (request, optional) | `application/json`                |
| `Content-Type` (response)    | `application/json; charset=utf-8` |

Bodies are UTF-8 encoded. The server will reject non-JSON content with `INVALID_ARGUMENT` (HTTP 400).

## Authentication

Every request must carry the four [Access Protocol](/get-started/authentication/overview) headers — failure to include them, or signature verification failure, returns one of the canonical authentication reasons documented in the [Error catalog](/get-started/errors/error-catalog).

| Header                | Required | Format                                      |
| --------------------- | :------: | ------------------------------------------- |
| `X-Access-Key`        |     ✅    | Opaque string.                              |
| `X-Access-Timestamp`  |     ✅    | Unix epoch in **milliseconds** (UTC).       |
| `X-Access-Request-Id` |     ✅    | Unique per request (UUID v4 recommended).   |
| `X-Access-Signature`  |     ✅    | Base64-encoded ECDSA `secp256k1` signature. |

## Status codes

The numeric `error.code` is always coherent with the HTTP status line. Branch on `error.status` for business logic — see [Errors](/api-reference/conventions/errors).

|                        HTTP | Meaning                            | When                                                                            |
| --------------------------: | ---------------------------------- | ------------------------------------------------------------------------------- |
|                    `200 OK` | Success.                           | Resource retrieved or updated.                                                  |
|               `201 Created` | Resource created.                  | Returned by `POST` on success.                                                  |
|           `400 Bad Request` | Request contract violation.        | Malformed body, invalid headers, validation failure.                            |
|          `401 Unauthorized` | Authentication failure.            | Missing headers, signature invalid, clock skew, replay detected.                |
|             `403 Forbidden` | Authorization denied.              | Authenticated, but not permitted on this resource.                              |
|             `404 Not Found` | Resource does not exist.           | Or you are not permitted to know it exists.                                     |
|              `409 Conflict` | Conflicts with current state.      | Uniqueness violation on create.                                                 |
|  `422 Unprocessable Entity` | Business precondition failed.      | E.g., `IDEMPOTENCY_KEY_IN_USE_WITH_DIFFERENT_PARAMS`.                           |
| `500 Internal Server Error` | Internal failure.                  | Sanitized response — see [Errors §INTERNAL](/api-reference/conventions/errors). |
|   `503 Service Unavailable` | Downstream dependency unavailable. | E.g., `PROVIDER_UNAVAILABLE`. Retry with backoff.                               |

<Warning>
  **Branch on `error.status`, not `error.code`.** Two `400`s can mean different things (`INVALID_ARGUMENT` vs `FAILED_PRECONDITION`). Two `401`s can mean different things (`SIGNATURE_INVALID` vs `TIMESTAMP_SKEW_EXCEEDED`). The numeric code is informational; `error.status` is the contract.
</Warning>

## TLS

All traffic is HTTPS. The server enforces TLS 1.2 or higher; HTTP connections are refused. Certificate pinning is not required — the server uses publicly trusted certificates rotated transparently.

## Versioning

The major version is part of the URL path (`/v1`). Within a major version:

* **Additive** changes (new endpoints, new response fields, new optional request fields) ship without notice.
* **Breaking** changes (removed fields, renamed fields, changed semantics) trigger a new major version (`/v2`) with a deprecation window for the previous one.

Clients should ignore unknown response fields gracefully — assume the server may add fields at any time.
