# Stowbo · Host

Part of AppEngine API Documentation. Full index: https://appengine.appmint.io/documentation.md
## POST /client/stowbo/host/items/{itemId}/request

**Advance a guest request**

`operationId: StowboClientController_hostUpdateRequest`

Moves a guest's request forward — `acknowledged`, `preparing`, `ready`. **Each step notifies the guest**, so the states are worth using honestly rather than jumping straight to ready.

The actual hand-out is a movement, not this call.

#### Signature

```http
POST /client/stowbo/host/items/{itemId}/request (itemId: string, body) -> The request
```

#### Access

Requires a bearer JWT (`Authorization: Bearer <token>`).

#### Notes

- Notifies the guest at each step.

#### Errors

| Status | Code | Message | When | What to do |
| --- | --- | --- | --- | --- |
| `401` | HOST_AUTH_REQUIRED | Host authentication required | The caller is not signed in as a host. | Sign in with a host account. |
| `404` | ITEM_NOT_FOUND | Booking item not found | No booking item has that id. | List the order's items. |

Plus the standard platform errors: `403`, `429`, `500`.

#### See also

- `POST /client/stowbo/host/items/{itemId}/movement`

### Parameters

| Name | In | Type | Required | Description |
| --- | --- | --- | --- | --- |
| `orgid` | header | string | yes | Organization (tenant) identifier. Every request is scoped to this org; data from other orgs is never visible. Issued with your API credentials. |
| `itemId` | path | string | yes | Booking **item** id — one thing booked, not the whole order. |

### Request body

The new state.

```json
{
  "status": "preparing"
}
```

### Responses

| Status | Meaning |
| --- | --- |
| `201` | The request |
| `401` | Host authentication required — The caller is not signed in as a host. |
| `403` | You do not have permission to perform this action — The caller is authenticated but lacks the role required by the endpoint, or is acting on another org. |
| `404` | Booking item not found — No booking item has that id. |
| `429` | Too Many Requests — More than 100,000 requests from one IP within 5 minutes (configurable per deployment). CORS preflights and requests from inside the platform cluster are not counted. The limiter answers before the error filter, so the body is `{ statusCode, error, message }` with no `path`, `method` or `timeStamp`; the `RateLimit-*` response headers say when the window resets. |
| `500` | An unexpected error occurred. Our team has been notified. — An unhandled server-side failure. |

## POST /client/stowbo/host/take-payment

**Record an in-person card payment**

`operationId: StowboClientController_takePayment`

Records a Tap to Pay / terminal payment a host collected in person — a booking balance, an add-on, a tip, or an ad-hoc walk-up amount.

The app does the collection: create a `card_present` PaymentIntent via `POST /storefront/stripe/terminal/intent`, collect on the phone, confirm, then hand the **succeeded** intent id here to record it against the platform Stripe account and credit the host. This endpoint records; it does not charge.

`reference` is free text for a walk-up with no booking — a plate, a name, an invoice number.

#### Signature

```http
POST /client/stowbo/host/take-payment (body) -> The recorded payment
```

#### Access

Requires a bearer JWT (`Authorization: Bearer <token>`).

#### Errors

| Status | Code | Message | When | What to do |
| --- | --- | --- | --- | --- |
| `401` | HOST_AUTH_REQUIRED | Host authentication required | The caller is not signed in as a host. | Sign in with a host account. |

Plus the standard platform errors: `403`, `429`, `500`.

#### See also

- `POST /client/stowbo/host/payment-request`

### Parameters

| Name | In | Type | Required | Description |
| --- | --- | --- | --- | --- |
| `orgid` | header | string | yes | Organization (tenant) identifier. Every request is scoped to this org; data from other orgs is never visible. Issued with your API credentials. |

### Request body

The collected payment.

```json
{
  "paymentIntentId": "pi_3Abc123",
  "bookingId": "BKG-4821",
  "amount": 2500,
  "category": "booking"
}
```

### Responses

| Status | Meaning |
| --- | --- |
| `201` | The recorded payment |
| `401` | Host authentication required — The caller is not signed in as a host. |
| `403` | You do not have permission to perform this action — The caller is authenticated but lacks the role required by the endpoint, or is acting on another org. |
| `429` | Too Many Requests — More than 100,000 requests from one IP within 5 minutes (configurable per deployment). CORS preflights and requests from inside the platform cluster are not counted. The limiter answers before the error filter, so the body is `{ statusCode, error, message }` with no `path`, `method` or `timeStamp`; the `RateLimit-*` response headers say when the window resets. |
| `500` | An unexpected error occurred. Our team has been notified. — An unhandled server-side failure. |

## POST /client/stowbo/host/payment-request

**Create a self-serve payment request**

`operationId: StowboClientController_createPaymentRequest`

When the customer is not tapping a card at the host, this generates a pay link and a QR code for the same URL. Records a **pending** ledger row and returns `{ url, paymentRequestId }`; the customer pays on the signed-out web `/pay` page, which settles it.

Set `send: true` with `email` or `phone` to deliver the link immediately — that sends a real message to the customer.

#### Signature

```http
POST /client/stowbo/host/payment-request (body) -> `url` and `paymentRequestId`
```

#### Access

Requires a bearer JWT (`Authorization: Bearer <token>`).

#### Notes

- `send: true` messages the customer.

#### Errors

| Status | Code | Message | When | What to do |
| --- | --- | --- | --- | --- |
| `401` | HOST_AUTH_REQUIRED | Host authentication required | The caller is not signed in as a host. | Sign in with a host account. |

Plus the standard platform errors: `403`, `429`, `500`.

#### See also

- `GET /client/stowbo/host/payment-request/{requestId}`

### Parameters

| Name | In | Type | Required | Description |
| --- | --- | --- | --- | --- |
| `orgid` | header | string | yes | Organization (tenant) identifier. Every request is scoped to this org; data from other orgs is never visible. Issued with your API credentials. |

### Request body

What is being asked for, and whether to send it.

```json
{
  "bookingId": "BKG-4821",
  "category": "booking",
  "send": true,
  "phone": "+15551234567"
}
```

### Responses

| Status | Meaning |
| --- | --- |
| `201` | `url` and `paymentRequestId` |
| `401` | Host authentication required — The caller is not signed in as a host. |
| `403` | You do not have permission to perform this action — The caller is authenticated but lacks the role required by the endpoint, or is acting on another org. |
| `429` | Too Many Requests — More than 100,000 requests from one IP within 5 minutes (configurable per deployment). CORS preflights and requests from inside the platform cluster are not counted. The limiter answers before the error filter, so the body is `{ statusCode, error, message }` with no `path`, `method` or `timeStamp`; the `RateLimit-*` response headers say when the window resets. |
| `500` | An unexpected error occurred. Our team has been notified. — An unhandled server-side failure. |

Example response:

```json
{
  "url": "https://stowbo.example.com/pay/BKG-4821",
  "paymentRequestId": "PR-4821"
}
```

## POST /client/stowbo/host/payment-request/{requestId}/complete

**Mark a payment request paid**

`operationId: StowboClientController_completePaymentRequest`

Settles a pending payment request. Called by the web `/pay` flow once the customer has paid — marking one paid by hand records money that may not have arrived.

#### Signature

```http
POST /client/stowbo/host/payment-request/{requestId}/complete (requestId: string, body) -> The settled request
```

#### Access

Requires a bearer JWT (`Authorization: Bearer <token>`).

#### Notes

- Driven by the pay flow, not by hand.

#### Errors

| Status | Code | Message | When | What to do |
| --- | --- | --- | --- | --- |
| `401` | HOST_AUTH_REQUIRED | Host authentication required | The caller is not signed in as a host. | Sign in with a host account. |

Plus the standard platform errors: `403`, `429`, `500`.

#### See also

- `GET /client/stowbo/host/payment-request/{requestId}`

### Parameters

| Name | In | Type | Required | Description |
| --- | --- | --- | --- | --- |
| `orgid` | header | string | yes | Organization (tenant) identifier. Every request is scoped to this org; data from other orgs is never visible. Issued with your API credentials. |
| `requestId` | path | string | yes | Payment request id. |

### Request body

The payment confirmation.

```json
{
  "paymentIntentId": "pi_3Abc123"
}
```

### Responses

| Status | Meaning |
| --- | --- |
| `201` | The settled request |
| `401` | Host authentication required — The caller is not signed in as a host. |
| `403` | You do not have permission to perform this action — The caller is authenticated but lacks the role required by the endpoint, or is acting on another org. |
| `429` | Too Many Requests — More than 100,000 requests from one IP within 5 minutes (configurable per deployment). CORS preflights and requests from inside the platform cluster are not counted. The limiter answers before the error filter, so the body is `{ statusCode, error, message }` with no `path`, `method` or `timeStamp`; the `RateLimit-*` response headers say when the window resets. |
| `500` | An unexpected error occurred. Our team has been notified. — An unhandled server-side failure. |

## GET /client/stowbo/host/payment-request/{requestId}

**Get a payment request's status**

`operationId: StowboClientController_paymentRequestStatus`

The live status of a pending payment request — it flips to `paid` the moment the customer completes it. For a host watching their screen after sending a link or showing a QR.

A socket `payment-completed` push is also emitted; this polling route is the fallback.

#### Signature

```http
GET /client/stowbo/host/payment-request/{requestId} (requestId: string) -> The request status
```

#### Access

Requires a bearer JWT (`Authorization: Bearer <token>`).

#### Errors

| Status | Code | Message | When | What to do |
| --- | --- | --- | --- | --- |
| `401` | HOST_AUTH_REQUIRED | Host authentication required | The caller is not signed in as a host. | Sign in with a host account. |

Plus the standard platform errors: `403`, `429`, `500`.

#### See also

- `POST /client/stowbo/host/payment-request/{requestId}/complete`

### Parameters

| Name | In | Type | Required | Description |
| --- | --- | --- | --- | --- |
| `orgid` | header | string | yes | Organization (tenant) identifier. Every request is scoped to this org; data from other orgs is never visible. Issued with your API credentials. |
| `requestId` | path | string | yes | Payment request id. |

### Responses

| Status | Meaning |
| --- | --- |
| `200` | The request status |
| `401` | Host authentication required — The caller is not signed in as a host. |
| `403` | You do not have permission to perform this action — The caller is authenticated but lacks the role required by the endpoint, or is acting on another org. |
| `429` | Too Many Requests — More than 100,000 requests from one IP within 5 minutes (configurable per deployment). CORS preflights and requests from inside the platform cluster are not counted. The limiter answers before the error filter, so the body is `{ statusCode, error, message }` with no `path`, `method` or `timeStamp`; the `RateLimit-*` response headers say when the window resets. |
| `500` | An unexpected error occurred. Our team has been notified. — An unhandled server-side failure. |

## GET /client/stowbo/host/transactions

**List my transactions**

`operationId: StowboClientController_hostTransactions`

The host's collected and pending payments, newest first — a server-scoped query over the `sf_transaction` ledger for stowbo rows this host created or collected.

Pending rows carry their pay `url`, so a host who walked away from a link or QR can come back, re-show the QR or resend it.

#### Signature

```http
GET /client/stowbo/host/transactions () -> Transactions
```

#### Access

Requires a bearer JWT (`Authorization: Bearer <token>`).

#### Errors

| Status | Code | Message | When | What to do |
| --- | --- | --- | --- | --- |
| `401` | HOST_AUTH_REQUIRED | Host authentication required | The caller is not signed in as a host. | Sign in with a host account. |

Plus the standard platform errors: `403`, `429`, `500`.

#### See also

- `GET /client/stowbo/host/earnings`

### Parameters

| Name | In | Type | Required | Description |
| --- | --- | --- | --- | --- |
| `orgid` | header | string | yes | Organization (tenant) identifier. Every request is scoped to this org; data from other orgs is never visible. Issued with your API credentials. |

### Responses

| Status | Meaning |
| --- | --- |
| `200` | Transactions |
| `401` | Host authentication required — The caller is not signed in as a host. |
| `403` | You do not have permission to perform this action — The caller is authenticated but lacks the role required by the endpoint, or is acting on another org. |
| `429` | Too Many Requests — More than 100,000 requests from one IP within 5 minutes (configurable per deployment). CORS preflights and requests from inside the platform cluster are not counted. The limiter answers before the error filter, so the body is `{ statusCode, error, message }` with no `path`, `method` or `timeStamp`; the `RateLimit-*` response headers say when the window resets. |
| `500` | An unexpected error occurred. Our team has been notified. — An unhandled server-side failure. |

## POST /client/stowbo/host/transactions/{ref}/refund

**Refund a payment I collected**

`operationId: StowboClientController_refundTransaction`

Refunds a paid transaction the signed-in host collected, in full (omit `amount`) or in part. Writes a separate `refund` ledger row and marks the original refunded or partially refunded; its amount is never changed.

#### Signature

```http
POST /client/stowbo/host/transactions/{ref}/refund (ref: string, body) -> The refund
```

#### Access

Requires a bearer JWT (`Authorization: Bearer <token>`).

#### Errors

| Status | Code | Message | When | What to do |
| --- | --- | --- | --- | --- |
| `401` | SIGN_IN_REQUIRED | Sign in required | No customer could be resolved from the token. | Sign in. |
| `403` | NOT_APPROVED_HOST | You need an approved 'stowbo-host' application before you can list space | The caller has no approved host application. | Apply with `POST /client/stowbo/host/apply`. |
| `400` | REF_REQUIRED | A transaction reference is required | Empty ref. | — |
| `404` | TRANSACTION_NOT_FOUND | Transaction <ref> not found | Unknown ref. | — |

Plus the standard platform errors: `429`, `500`.

### Parameters

| Name | In | Type | Required | Description |
| --- | --- | --- | --- | --- |
| `orgid` | header | string | yes | Organization (tenant) identifier. Every request is scoped to this org; data from other orgs is never visible. Issued with your API credentials. |
| `ref` | path | string | yes | The gateway reference of the paid transaction. |

### Request body

```json
{
  "amount": 10,
  "reason": "Late handover"
}
```

### Responses

| Status | Meaning |
| --- | --- |
| `201` | The refund |
| `400` | A transaction reference is required — Empty ref. |
| `401` | Sign in required — No customer could be resolved from the token. |
| `403` | You need an approved 'stowbo-host' application before you can list space — The caller has no approved host application. |
| `404` | Transaction <ref> not found — Unknown ref. |
| `429` | Too Many Requests — More than 100,000 requests from one IP within 5 minutes (configurable per deployment). CORS preflights and requests from inside the platform cluster are not counted. The limiter answers before the error filter, so the body is `{ statusCode, error, message }` with no `path`, `method` or `timeStamp`; the `RateLimit-*` response headers say when the window resets. |
| `500` | An unexpected error occurred. Our team has been notified. — An unhandled server-side failure. |

## POST /client/stowbo/host/transactions/{ref}/receipt

**Resend a receipt**

`operationId: StowboClientController_sendReceipt`

Emails and/or texts the receipt for a payment the host collected. With no email or phone it goes to the linked booking's customer.

#### Signature

```http
POST /client/stowbo/host/transactions/{ref}/receipt (ref: string, body) -> { ok, sentTo }
```

#### Access

Requires a bearer JWT (`Authorization: Bearer <token>`).

#### Errors

| Status | Code | Message | When | What to do |
| --- | --- | --- | --- | --- |
| `401` | SIGN_IN_REQUIRED | Sign in required | No customer could be resolved from the token. | Sign in. |
| `403` | NOT_APPROVED_HOST | You need an approved 'stowbo-host' application before you can list space | The caller has no approved host application. | Apply with `POST /client/stowbo/host/apply`. |
| `400` | REF_REQUIRED | A transaction reference is required | Empty ref. | — |
| `404` | TRANSACTION_NOT_FOUND | Transaction <ref> not found | Unknown ref. | — |

Plus the standard platform errors: `429`, `500`.

### Parameters

| Name | In | Type | Required | Description |
| --- | --- | --- | --- | --- |
| `orgid` | header | string | yes | Organization (tenant) identifier. Every request is scoped to this org; data from other orgs is never visible. Issued with your API credentials. |
| `ref` | path | string | yes | The gateway reference of the paid transaction. |

### Request body

### Responses

| Status | Meaning |
| --- | --- |
| `201` | { ok, sentTo } |
| `400` | A transaction reference is required — Empty ref. |
| `401` | Sign in required — No customer could be resolved from the token. |
| `403` | You need an approved 'stowbo-host' application before you can list space — The caller has no approved host application. |
| `404` | Transaction <ref> not found — Unknown ref. |
| `429` | Too Many Requests — More than 100,000 requests from one IP within 5 minutes (configurable per deployment). CORS preflights and requests from inside the platform cluster are not counted. The limiter answers before the error filter, so the body is `{ statusCode, error, message }` with no `path`, `method` or `timeStamp`; the `RateLimit-*` response headers say when the window resets. |
| `500` | An unexpected error occurred. Our team has been notified. — An unhandled server-side failure. |

## POST /client/stowbo/host/payment-request/{requestId}/cancel

**Void a payment request**

`operationId: StowboClientController_cancelPaymentRequest`

Voids a still-unpaid request so its link and QR stop working. Cancelling one already cancelled returns `alreadyCancelled`. A paid request is refused — refund it instead.

#### Signature

```http
POST /client/stowbo/host/payment-request/{requestId}/cancel (requestId: string) -> { ok, cancelled } or { ok, alreadyCancelled }
```

#### Access

Requires a bearer JWT (`Authorization: Bearer <token>`).

#### Errors

| Status | Code | Message | When | What to do |
| --- | --- | --- | --- | --- |
| `401` | SIGN_IN_REQUIRED | Sign in required | No customer could be resolved from the token. | Sign in. |
| `403` | NOT_APPROVED_HOST | You need an approved 'stowbo-host' application before you can list space | The caller has no approved host application. | Apply with `POST /client/stowbo/host/apply`. |
| `404` | REQUEST_NOT_FOUND | Payment request <id> not found | Unknown id. | — |
| `400` | ALREADY_PAID | That payment is already paid — refund it instead of cancelling. | Paid. | — |

Plus the standard platform errors: `429`, `500`.

### Parameters

| Name | In | Type | Required | Description |
| --- | --- | --- | --- | --- |
| `orgid` | header | string | yes | Organization (tenant) identifier. Every request is scoped to this org; data from other orgs is never visible. Issued with your API credentials. |
| `requestId` | path | string | yes | Payment request id. |

### Responses

| Status | Meaning |
| --- | --- |
| `201` | { ok, cancelled } or { ok, alreadyCancelled } |
| `400` | That payment is already paid — refund it instead of cancelling. — Paid. |
| `401` | Sign in required — No customer could be resolved from the token. |
| `403` | You need an approved 'stowbo-host' application before you can list space — The caller has no approved host application. |
| `404` | Payment request <id> not found — Unknown id. |
| `429` | Too Many Requests — More than 100,000 requests from one IP within 5 minutes (configurable per deployment). CORS preflights and requests from inside the platform cluster are not counted. The limiter answers before the error filter, so the body is `{ statusCode, error, message }` with no `path`, `method` or `timeStamp`; the `RateLimit-*` response headers say when the window resets. |
| `500` | An unexpected error occurred. Our team has been notified. — An unhandled server-side failure. |

## GET /client/stowbo/host/wallet

**Get my wallet**

`operationId: StowboClientController_hostWallet`

The host's earnings wallet, derived from the ledger: earned (net of refunds), pending payment links, refunded, `available` to pay out, the payout minimum (the platform floor or my own higher one), paid out, payouts in progress, and the balance still expected from live bookings.

#### Signature

```http
GET /client/stowbo/host/wallet () -> The wallet
```

#### Access

Requires a bearer JWT (`Authorization: Bearer <token>`).

#### Errors

| Status | Code | Message | When | What to do |
| --- | --- | --- | --- | --- |
| `401` | SIGN_IN_REQUIRED | Sign in required | No customer could be resolved from the token. | Sign in. |
| `403` | NOT_APPROVED_HOST | You need an approved 'stowbo-host' application before you can list space | The caller has no approved host application. | Apply with `POST /client/stowbo/host/apply`. |

Plus the standard platform errors: `429`, `500`.

### Parameters

| Name | In | Type | Required | Description |
| --- | --- | --- | --- | --- |
| `orgid` | header | string | yes | Organization (tenant) identifier. Every request is scoped to this org; data from other orgs is never visible. Issued with your API credentials. |

### Responses

| Status | Meaning |
| --- | --- |
| `200` | The wallet |
| `401` | Sign in required — No customer could be resolved from the token. |
| `403` | You need an approved 'stowbo-host' application before you can list space — The caller has no approved host application. |
| `429` | Too Many Requests — More than 100,000 requests from one IP within 5 minutes (configurable per deployment). CORS preflights and requests from inside the platform cluster are not counted. The limiter answers before the error filter, so the body is `{ statusCode, error, message }` with no `path`, `method` or `timeStamp`; the `RateLimit-*` response headers say when the window resets. |
| `500` | An unexpected error occurred. Our team has been notified. — An unhandled server-side failure. |

## GET /client/stowbo/host/payouts

**List my payouts**

`operationId: StowboClientController_hostPayouts`

The host's payout history: number, amount, status, method and destination.

#### Signature

```http
GET /client/stowbo/host/payouts () -> Payouts
```

#### Access

Requires a bearer JWT (`Authorization: Bearer <token>`).

#### Errors

| Status | Code | Message | When | What to do |
| --- | --- | --- | --- | --- |
| `401` | SIGN_IN_REQUIRED | Sign in required | No customer could be resolved from the token. | Sign in. |
| `403` | NOT_APPROVED_HOST | You need an approved 'stowbo-host' application before you can list space | The caller has no approved host application. | Apply with `POST /client/stowbo/host/apply`. |

Plus the standard platform errors: `429`, `500`.

### Parameters

| Name | In | Type | Required | Description |
| --- | --- | --- | --- | --- |
| `orgid` | header | string | yes | Organization (tenant) identifier. Every request is scoped to this org; data from other orgs is never visible. Issued with your API credentials. |

### Responses

| Status | Meaning |
| --- | --- |
| `200` | Payouts |
| `401` | Sign in required — No customer could be resolved from the token. |
| `403` | You need an approved 'stowbo-host' application before you can list space — The caller has no approved host application. |
| `429` | Too Many Requests — More than 100,000 requests from one IP within 5 minutes (configurable per deployment). CORS preflights and requests from inside the platform cluster are not counted. The limiter answers before the error filter, so the body is `{ statusCode, error, message }` with no `path`, `method` or `timeStamp`; the `RateLimit-*` response headers say when the window resets. |
| `500` | An unexpected error occurred. Our team has been notified. — An unhandled server-side failure. |

## POST /client/stowbo/host/payouts

**Request a payout**

`operationId: StowboClientController_requestHostPayout`

Pays out the available balance, or `amount` of it, to `methodId` (default destination if omitted). The minimum is enforced on the server.

#### Signature

```http
POST /client/stowbo/host/payouts (body) -> { ok, payout, amount, status }
```

#### Access

Requires a bearer JWT (`Authorization: Bearer <token>`).

#### Errors

| Status | Code | Message | When | What to do |
| --- | --- | --- | --- | --- |
| `401` | SIGN_IN_REQUIRED | Sign in required | No customer could be resolved from the token. | Sign in. |
| `403` | NOT_APPROVED_HOST | You need an approved 'stowbo-host' application before you can list space | The caller has no approved host application. | Apply with `POST /client/stowbo/host/apply`. |
| `400` | NOTHING_AVAILABLE | Nothing available to pay out. | Available balance is zero. | — |

Plus the standard platform errors: `429`, `500`.

### Parameters

| Name | In | Type | Required | Description |
| --- | --- | --- | --- | --- |
| `orgid` | header | string | yes | Organization (tenant) identifier. Every request is scoped to this org; data from other orgs is never visible. Issued with your API credentials. |

### Request body

```json
{
  "amount": 150
}
```

### Responses

| Status | Meaning |
| --- | --- |
| `201` | { ok, payout, amount, status } |
| `400` | Nothing available to pay out. — Available balance is zero. |
| `401` | Sign in required — No customer could be resolved from the token. |
| `403` | You need an approved 'stowbo-host' application before you can list space — The caller has no approved host application. |
| `429` | Too Many Requests — More than 100,000 requests from one IP within 5 minutes (configurable per deployment). CORS preflights and requests from inside the platform cluster are not counted. The limiter answers before the error filter, so the body is `{ statusCode, error, message }` with no `path`, `method` or `timeStamp`; the `RateLimit-*` response headers say when the window resets. |
| `500` | An unexpected error occurred. Our team has been notified. — An unhandled server-side failure. |

## GET /client/stowbo/host/payout-methods

**List my payout destinations**

`operationId: StowboClientController_hostPayoutMethods`

Saved bank accounts and PayPal addresses on the host's wallet. Account and routing numbers are never returned — only the last four.

#### Signature

```http
GET /client/stowbo/host/payout-methods () -> Payout methods
```

#### Access

Requires a bearer JWT (`Authorization: Bearer <token>`).

#### Errors

| Status | Code | Message | When | What to do |
| --- | --- | --- | --- | --- |
| `401` | SIGN_IN_REQUIRED | Sign in required | No customer could be resolved from the token. | Sign in. |
| `403` | NOT_APPROVED_HOST | You need an approved 'stowbo-host' application before you can list space | The caller has no approved host application. | Apply with `POST /client/stowbo/host/apply`. |

Plus the standard platform errors: `429`, `500`.

### Parameters

| Name | In | Type | Required | Description |
| --- | --- | --- | --- | --- |
| `orgid` | header | string | yes | Organization (tenant) identifier. Every request is scoped to this org; data from other orgs is never visible. Issued with your API credentials. |

### Responses

| Status | Meaning |
| --- | --- |
| `200` | Payout methods |
| `401` | Sign in required — No customer could be resolved from the token. |
| `403` | You need an approved 'stowbo-host' application before you can list space — The caller has no approved host application. |
| `429` | Too Many Requests — More than 100,000 requests from one IP within 5 minutes (configurable per deployment). CORS preflights and requests from inside the platform cluster are not counted. The limiter answers before the error filter, so the body is `{ statusCode, error, message }` with no `path`, `method` or `timeStamp`; the `RateLimit-*` response headers say when the window resets. |
| `500` | An unexpected error occurred. Our team has been notified. — An unhandled server-side failure. |

## POST /client/stowbo/host/payout-methods

**Add a payout destination**

`operationId: StowboClientController_addHostPayoutMethod`

Adds a bank account or PayPal address. Bank numbers are encrypted on arrival and only the last four are returned.

#### Signature

```http
POST /client/stowbo/host/payout-methods (body) -> The method (masked)
```

#### Access

Requires a bearer JWT (`Authorization: Bearer <token>`).

#### Errors

| Status | Code | Message | When | What to do |
| --- | --- | --- | --- | --- |
| `401` | SIGN_IN_REQUIRED | Sign in required | No customer could be resolved from the token. | Sign in. |
| `403` | NOT_APPROVED_HOST | You need an approved 'stowbo-host' application before you can list space | The caller has no approved host application. | Apply with `POST /client/stowbo/host/apply`. |

Plus the standard platform errors: `429`, `500`.

### Parameters

| Name | In | Type | Required | Description |
| --- | --- | --- | --- | --- |
| `orgid` | header | string | yes | Organization (tenant) identifier. Every request is scoped to this org; data from other orgs is never visible. Issued with your API credentials. |

### Request body

```json
{
  "type": "paypal",
  "paypal": {
    "email": "host@example.com"
  },
  "isDefault": true
}
```

### Responses

| Status | Meaning |
| --- | --- |
| `201` | The method (masked) |
| `401` | Sign in required — No customer could be resolved from the token. |
| `403` | You need an approved 'stowbo-host' application before you can list space — The caller has no approved host application. |
| `429` | Too Many Requests — More than 100,000 requests from one IP within 5 minutes (configurable per deployment). CORS preflights and requests from inside the platform cluster are not counted. The limiter answers before the error filter, so the body is `{ statusCode, error, message }` with no `path`, `method` or `timeStamp`; the `RateLimit-*` response headers say when the window resets. |
| `500` | An unexpected error occurred. Our team has been notified. — An unhandled server-side failure. |

## PUT /client/stowbo/host/payout-methods/{methodId}/default

**Make a payout destination the default**

`operationId: StowboClientController_setHostDefaultPayoutMethod`

#### Signature

```http
PUT /client/stowbo/host/payout-methods/{methodId}/default (methodId: string) -> All payout methods
```

#### Access

Requires a bearer JWT (`Authorization: Bearer <token>`).

#### Errors

| Status | Code | Message | When | What to do |
| --- | --- | --- | --- | --- |
| `401` | SIGN_IN_REQUIRED | Sign in required | No customer could be resolved from the token. | Sign in. |
| `403` | NOT_APPROVED_HOST | You need an approved 'stowbo-host' application before you can list space | The caller has no approved host application. | Apply with `POST /client/stowbo/host/apply`. |

Plus the standard platform errors: `429`, `500`.

### Parameters

| Name | In | Type | Required | Description |
| --- | --- | --- | --- | --- |
| `orgid` | header | string | yes | Organization (tenant) identifier. Every request is scoped to this org; data from other orgs is never visible. Issued with your API credentials. |
| `methodId` | path | string | yes | Payout method id. |

### Responses

| Status | Meaning |
| --- | --- |
| `200` | All payout methods |
| `401` | Sign in required — No customer could be resolved from the token. |
| `403` | You need an approved 'stowbo-host' application before you can list space — The caller has no approved host application. |
| `429` | Too Many Requests — More than 100,000 requests from one IP within 5 minutes (configurable per deployment). CORS preflights and requests from inside the platform cluster are not counted. The limiter answers before the error filter, so the body is `{ statusCode, error, message }` with no `path`, `method` or `timeStamp`; the `RateLimit-*` response headers say when the window resets. |
| `500` | An unexpected error occurred. Our team has been notified. — An unhandled server-side failure. |

## DELETE /client/stowbo/host/payout-methods/{methodId}

**Remove a payout destination**

`operationId: StowboClientController_removeHostPayoutMethod`

#### Signature

```http
DELETE /client/stowbo/host/payout-methods/{methodId} (methodId: string) -> The remaining payout methods
```

#### Access

Requires a bearer JWT (`Authorization: Bearer <token>`).

#### Errors

| Status | Code | Message | When | What to do |
| --- | --- | --- | --- | --- |
| `401` | SIGN_IN_REQUIRED | Sign in required | No customer could be resolved from the token. | Sign in. |
| `403` | NOT_APPROVED_HOST | You need an approved 'stowbo-host' application before you can list space | The caller has no approved host application. | Apply with `POST /client/stowbo/host/apply`. |

Plus the standard platform errors: `429`, `500`.

### Parameters

| Name | In | Type | Required | Description |
| --- | --- | --- | --- | --- |
| `orgid` | header | string | yes | Organization (tenant) identifier. Every request is scoped to this org; data from other orgs is never visible. Issued with your API credentials. |
| `methodId` | path | string | yes | Payout method id. |

### Responses

| Status | Meaning |
| --- | --- |
| `200` | The remaining payout methods |
| `401` | Sign in required — No customer could be resolved from the token. |
| `403` | You need an approved 'stowbo-host' application before you can list space — The caller has no approved host application. |
| `429` | Too Many Requests — More than 100,000 requests from one IP within 5 minutes (configurable per deployment). CORS preflights and requests from inside the platform cluster are not counted. The limiter answers before the error filter, so the body is `{ statusCode, error, message }` with no `path`, `method` or `timeStamp`; the `RateLimit-*` response headers say when the window resets. |
| `500` | An unexpected error occurred. Our team has been notified. — An unhandled server-side failure. |

## GET /client/stowbo/host/listings

**List my listings**

`operationId: StowboClientController_myListings`

The host's own listings.

#### Signature

```http
GET /client/stowbo/host/listings () -> Listings
```

#### Access

Requires a bearer JWT (`Authorization: Bearer <token>`).

#### Errors

| Status | Code | Message | When | What to do |
| --- | --- | --- | --- | --- |
| `401` | HOST_AUTH_REQUIRED | Host authentication required | The caller is not signed in as a host. | Sign in with a host account. |

Plus the standard platform errors: `403`, `429`, `500`.

#### See also

- `GET /client/stowbo/host/listings/{id}`

### Parameters

| Name | In | Type | Required | Description |
| --- | --- | --- | --- | --- |
| `orgid` | header | string | yes | Organization (tenant) identifier. Every request is scoped to this org; data from other orgs is never visible. Issued with your API credentials. |

### Responses

| Status | Meaning |
| --- | --- |
| `200` | Listings |
| `401` | Host authentication required — The caller is not signed in as a host. |
| `403` | You do not have permission to perform this action — The caller is authenticated but lacks the role required by the endpoint, or is acting on another org. |
| `429` | Too Many Requests — More than 100,000 requests from one IP within 5 minutes (configurable per deployment). CORS preflights and requests from inside the platform cluster are not counted. The limiter answers before the error filter, so the body is `{ statusCode, error, message }` with no `path`, `method` or `timeStamp`; the `RateLimit-*` response headers say when the window resets. |
| `500` | An unexpected error occurred. Our team has been notified. — An unhandled server-side failure. |

## POST /client/stowbo/host/listings

**Create a listing**

`operationId: StowboClientController_createListing`

Lists a space. A new listing is not live until its status is set — create it, add units, then publish.

#### Signature

```http
POST /client/stowbo/host/listings (body) -> The listing
```

#### Access

Requires a bearer JWT (`Authorization: Bearer <token>`).

#### Errors

| Status | Code | Message | When | What to do |
| --- | --- | --- | --- | --- |
| `401` | HOST_AUTH_REQUIRED | Host authentication required | The caller is not signed in as a host. | Sign in with a host account. |

Plus the standard platform errors: `403`, `429`, `500`.

#### See also

- `PUT /client/stowbo/host/listings/{id}/status`

### Parameters

| Name | In | Type | Required | Description |
| --- | --- | --- | --- | --- |
| `orgid` | header | string | yes | Organization (tenant) identifier. Every request is scoped to this org; data from other orgs is never visible. Issued with your API credentials. |

### Request body

The listing.

```json
{
  "name": "Mission garage bay",
  "spaceType": "parking",
  "city": "San Francisco"
}
```

### Responses

| Status | Meaning |
| --- | --- |
| `201` | The listing |
| `401` | Host authentication required — The caller is not signed in as a host. |
| `403` | You do not have permission to perform this action — The caller is authenticated but lacks the role required by the endpoint, or is acting on another org. |
| `429` | Too Many Requests — More than 100,000 requests from one IP within 5 minutes (configurable per deployment). CORS preflights and requests from inside the platform cluster are not counted. The limiter answers before the error filter, so the body is `{ statusCode, error, message }` with no `path`, `method` or `timeStamp`; the `RateLimit-*` response headers say when the window resets. |
| `500` | An unexpected error occurred. Our team has been notified. — An unhandled server-side failure. |

## GET /client/stowbo/host/addons

**List my add-ons**

`operationId: StowboClientController_myAddons`

Every add-on the host owns.

#### Signature

```http
GET /client/stowbo/host/addons () -> Add-ons
```

#### Access

Requires a bearer JWT (`Authorization: Bearer <token>`).

#### Errors

| Status | Code | Message | When | What to do |
| --- | --- | --- | --- | --- |
| `401` | HOST_AUTH_REQUIRED | Host authentication required | The caller is not signed in as a host. | Sign in with a host account. |

Plus the standard platform errors: `403`, `429`, `500`.

#### See also

- `POST /client/stowbo/host/addons`

### Parameters

| Name | In | Type | Required | Description |
| --- | --- | --- | --- | --- |
| `orgid` | header | string | yes | Organization (tenant) identifier. Every request is scoped to this org; data from other orgs is never visible. Issued with your API credentials. |

### Responses

| Status | Meaning |
| --- | --- |
| `200` | Add-ons |
| `401` | Host authentication required — The caller is not signed in as a host. |
| `403` | You do not have permission to perform this action — The caller is authenticated but lacks the role required by the endpoint, or is acting on another org. |
| `429` | Too Many Requests — More than 100,000 requests from one IP within 5 minutes (configurable per deployment). CORS preflights and requests from inside the platform cluster are not counted. The limiter answers before the error filter, so the body is `{ statusCode, error, message }` with no `path`, `method` or `timeStamp`; the `RateLimit-*` response headers say when the window resets. |
| `500` | An unexpected error occurred. Our team has been notified. — An unhandled server-side failure. |

## POST /client/stowbo/host/addons

**Create an add-on**

`operationId: StowboClientController_createAddon`

A host-owned extra — insurance, priority retrieval, a padlock.

`price: 0` makes it a **free** add-on. `service: true` means the host physically does something, so buying it raises a fulfilment request rather than just adding a line.

#### Signature

```http
POST /client/stowbo/host/addons (body) -> The add-on
```

#### Access

Requires a bearer JWT (`Authorization: Bearer <token>`).

#### Errors

| Status | Code | Message | When | What to do |
| --- | --- | --- | --- | --- |
| `401` | HOST_AUTH_REQUIRED | Host authentication required | The caller is not signed in as a host. | Sign in with a host account. |
| `400` | NEGATIVE_PRICE | An add-on cannot cost less than nothing | `price` is negative. | Use `0` for free. |

Plus the standard platform errors: `403`, `429`, `500`.

#### See also

- `PUT /client/stowbo/host/listings/{listingId}/addons`

### Parameters

| Name | In | Type | Required | Description |
| --- | --- | --- | --- | --- |
| `orgid` | header | string | yes | Organization (tenant) identifier. Every request is scoped to this org; data from other orgs is never visible. Issued with your API credentials. |

### Request body

The add-on.

```json
{
  "name": "Priority retrieval",
  "price": 500,
  "service": true
}
```

### Responses

| Status | Meaning |
| --- | --- |
| `201` | The add-on |
| `400` | An add-on cannot cost less than nothing — `price` is negative. |
| `401` | Host authentication required — The caller is not signed in as a host. |
| `403` | You do not have permission to perform this action — The caller is authenticated but lacks the role required by the endpoint, or is acting on another org. |
| `429` | Too Many Requests — More than 100,000 requests from one IP within 5 minutes (configurable per deployment). CORS preflights and requests from inside the platform cluster are not counted. The limiter answers before the error filter, so the body is `{ statusCode, error, message }` with no `path`, `method` or `timeStamp`; the `RateLimit-*` response headers say when the window resets. |
| `500` | An unexpected error occurred. Our team has been notified. — An unhandled server-side failure. |

## PUT /client/stowbo/host/addons/{addonId}

**Update an add-on**

`operationId: StowboClientController_updateAddon`

Edits an add-on. Price changes apply to future purchases; add-ons already sold keep what they were sold at.

#### Signature

```http
PUT /client/stowbo/host/addons/{addonId} (addonId: string, body) -> The updated add-on
```

#### Access

Requires a bearer JWT (`Authorization: Bearer <token>`).

#### Errors

| Status | Code | Message | When | What to do |
| --- | --- | --- | --- | --- |
| `401` | HOST_AUTH_REQUIRED | Host authentication required | The caller is not signed in as a host. | Sign in with a host account. |
| `404` | ADDON_NOT_FOUND | Add-on not found | No add-on has that id. | List your add-ons. |
| `403` | NOT_YOUR_ADDON | That add-on is not yours | It belongs to another host. | Check the id. |

Plus the standard platform errors: `429`, `500`.

#### See also

- `DELETE /client/stowbo/host/addons/{addonId}`

### Parameters

| Name | In | Type | Required | Description |
| --- | --- | --- | --- | --- |
| `orgid` | header | string | yes | Organization (tenant) identifier. Every request is scoped to this org; data from other orgs is never visible. Issued with your API credentials. |
| `addonId` | path | string | yes | Add-on id. |

### Request body

Fields to change.

```json
{
  "price": 600
}
```

### Responses

| Status | Meaning |
| --- | --- |
| `200` | The updated add-on |
| `401` | Host authentication required — The caller is not signed in as a host. |
| `403` | That add-on is not yours — It belongs to another host. |
| `404` | Add-on not found — No add-on has that id. |
| `429` | Too Many Requests — More than 100,000 requests from one IP within 5 minutes (configurable per deployment). CORS preflights and requests from inside the platform cluster are not counted. The limiter answers before the error filter, so the body is `{ statusCode, error, message }` with no `path`, `method` or `timeStamp`; the `RateLimit-*` response headers say when the window resets. |
| `500` | An unexpected error occurred. Our team has been notified. — An unhandled server-side failure. |

## DELETE /client/stowbo/host/addons/{addonId}

**Retire an add-on**

`operationId: StowboClientController_deleteAddon`

Soft-deletes an add-on: it stops being offered, but add-ons already sold keep working and the historical record stays intact.

#### Signature

```http
DELETE /client/stowbo/host/addons/{addonId} (addonId: string) -> The result
```

#### Access

Requires a bearer JWT (`Authorization: Bearer <token>`).

#### Notes

- Soft delete — existing purchases are unaffected.

#### Errors

| Status | Code | Message | When | What to do |
| --- | --- | --- | --- | --- |
| `401` | HOST_AUTH_REQUIRED | Host authentication required | The caller is not signed in as a host. | Sign in with a host account. |
| `404` | ADDON_NOT_FOUND | Add-on not found | No add-on has that id. | Check the id. |

Plus the standard platform errors: `403`, `429`, `500`.

#### See also

- `GET /client/stowbo/host/addons`

### Parameters

| Name | In | Type | Required | Description |
| --- | --- | --- | --- | --- |
| `orgid` | header | string | yes | Organization (tenant) identifier. Every request is scoped to this org; data from other orgs is never visible. Issued with your API credentials. |
| `addonId` | path | string | yes | Add-on id. |

### Responses

| Status | Meaning |
| --- | --- |
| `200` | The result |
| `401` | Host authentication required — The caller is not signed in as a host. |
| `403` | You do not have permission to perform this action — The caller is authenticated but lacks the role required by the endpoint, or is acting on another org. |
| `404` | Add-on not found — No add-on has that id. |
| `429` | Too Many Requests — More than 100,000 requests from one IP within 5 minutes (configurable per deployment). CORS preflights and requests from inside the platform cluster are not counted. The limiter answers before the error filter, so the body is `{ statusCode, error, message }` with no `path`, `method` or `timeStamp`; the `RateLimit-*` response headers say when the window resets. |
| `500` | An unexpected error occurred. Our team has been notified. — An unhandled server-side failure. |

## PUT /client/stowbo/host/listings/{listingId}/addons

**Set a listing's add-ons**

`operationId: StowboClientController_setListingAddons`

Sets which of the host's add-ons apply to one listing. The list **replaces** what was there — send the full set, not just the additions.

#### Signature

```http
PUT /client/stowbo/host/listings/{listingId}/addons (listingId: string, body) -> The result
```

#### Access

Requires a bearer JWT (`Authorization: Bearer <token>`).

#### Notes

- Replaces rather than appends.

#### Errors

| Status | Code | Message | When | What to do |
| --- | --- | --- | --- | --- |
| `401` | HOST_AUTH_REQUIRED | Host authentication required | The caller is not signed in as a host. | Sign in with a host account. |
| `404` | LISTING_NOT_FOUND | Listing not found | No listing has that id. | Search listings first. |
| `403` | NOT_YOUR_LISTING | Not your listing | The listing belongs to another host. | Hosts can only act on their own listings. |

Plus the standard platform errors: `429`, `500`.

#### See also

- `GET /client/stowbo/host/addons`

### Parameters

| Name | In | Type | Required | Description |
| --- | --- | --- | --- | --- |
| `orgid` | header | string | yes | Organization (tenant) identifier. Every request is scoped to this org; data from other orgs is never visible. Issued with your API credentials. |
| `listingId` | path | string | yes | Listing id. |

### Request body

The add-ons that apply.

```json
{
  "addonIds": [
    "ADD-3",
    "ADD-7"
  ]
}
```

### Responses

| Status | Meaning |
| --- | --- |
| `200` | The result |
| `401` | Host authentication required — The caller is not signed in as a host. |
| `403` | Not your listing — The listing belongs to another host. |
| `404` | Listing not found — No listing has that id. |
| `429` | Too Many Requests — More than 100,000 requests from one IP within 5 minutes (configurable per deployment). CORS preflights and requests from inside the platform cluster are not counted. The limiter answers before the error filter, so the body is `{ statusCode, error, message }` with no `path`, `method` or `timeStamp`; the `RateLimit-*` response headers say when the window resets. |
| `500` | An unexpected error occurred. Our team has been notified. — An unhandled server-side failure. |

## GET /client/stowbo/host/listings/{listingId}/fees

**List the fees on my listing**

`operationId: StowboClientController_listingFees`

The full `stowbo_fee` records attached to the listing, in the listing's order.

#### Signature

```http
GET /client/stowbo/host/listings/{listingId}/fees (listingId: string) -> Fee records
```

#### Access

Requires a bearer JWT (`Authorization: Bearer <token>`).

#### Errors

| Status | Code | Message | When | What to do |
| --- | --- | --- | --- | --- |
| `401` | SIGN_IN_REQUIRED | Sign in required | No customer could be resolved from the token. | Sign in. |
| `404` | LISTING_NOT_FOUND | Listing not found | No listing has that id. | Search listings first. |
| `403` | NOT_YOUR_LISTING | Not your listing | The listing belongs to another host. | Hosts can only act on their own listings. |

Plus the standard platform errors: `429`, `500`.

### Parameters

| Name | In | Type | Required | Description |
| --- | --- | --- | --- | --- |
| `orgid` | header | string | yes | Organization (tenant) identifier. Every request is scoped to this org; data from other orgs is never visible. Issued with your API credentials. |
| `listingId` | path | string | yes | Listing id. |

### Responses

| Status | Meaning |
| --- | --- |
| `200` | Fee records |
| `401` | Sign in required — No customer could be resolved from the token. |
| `403` | Not your listing — The listing belongs to another host. |
| `404` | Listing not found — No listing has that id. |
| `429` | Too Many Requests — More than 100,000 requests from one IP within 5 minutes (configurable per deployment). CORS preflights and requests from inside the platform cluster are not counted. The limiter answers before the error filter, so the body is `{ statusCode, error, message }` with no `path`, `method` or `timeStamp`; the `RateLimit-*` response headers say when the window resets. |
| `500` | An unexpected error occurred. Our team has been notified. — An unhandled server-side failure. |

## PUT /client/stowbo/host/listings/{listingId}/fees

**Set the fees on my listing**

`operationId: StowboClientController_setListingFees`

Replaces the listing's fee list with these fee **names** (attach and detach in one call).

#### Signature

```http
PUT /client/stowbo/host/listings/{listingId}/fees (listingId: string, body) -> { listing, fees }
```

#### Access

Requires a bearer JWT (`Authorization: Bearer <token>`).

#### Notes

- The names are not checked against existing fees.

#### Errors

| Status | Code | Message | When | What to do |
| --- | --- | --- | --- | --- |
| `401` | SIGN_IN_REQUIRED | Sign in required | No customer could be resolved from the token. | Sign in. |
| `404` | LISTING_NOT_FOUND | Listing not found | No listing has that id. | Search listings first. |
| `403` | NOT_YOUR_LISTING | Not your listing | The listing belongs to another host. | Hosts can only act on their own listings. |

Plus the standard platform errors: `429`, `500`.

### Parameters

| Name | In | Type | Required | Description |
| --- | --- | --- | --- | --- |
| `orgid` | header | string | yes | Organization (tenant) identifier. Every request is scoped to this org; data from other orgs is never visible. Issued with your API credentials. |
| `listingId` | path | string | yes | Listing id. |

### Request body

```json
{
  "fees": [
    "cleaning-fee"
  ]
}
```

### Responses

| Status | Meaning |
| --- | --- |
| `200` | { listing, fees } |
| `401` | Sign in required — No customer could be resolved from the token. |
| `403` | Not your listing — The listing belongs to another host. |
| `404` | Listing not found — No listing has that id. |
| `429` | Too Many Requests — More than 100,000 requests from one IP within 5 minutes (configurable per deployment). CORS preflights and requests from inside the platform cluster are not counted. The limiter answers before the error filter, so the body is `{ statusCode, error, message }` with no `path`, `method` or `timeStamp`; the `RateLimit-*` response headers say when the window resets. |
| `500` | An unexpected error occurred. Our team has been notified. — An unhandled server-side failure. |

## POST /client/stowbo/host/listings/{listingId}/fees

**Create a fee on my listing**

`operationId: StowboClientController_createListingFee`

Saves the fee as entered (the `stowbo_fee` fields) as a host fee I own, and attaches it to the listing. The server sets only `type: host` and a unique `name` (from `name` when it is a lowercase slug, else from the title).

#### Signature

```http
POST /client/stowbo/host/listings/{listingId}/fees (listingId: string, body) -> The fee record
```

#### Access

Requires a bearer JWT (`Authorization: Bearer <token>`).

#### Errors

| Status | Code | Message | When | What to do |
| --- | --- | --- | --- | --- |
| `401` | SIGN_IN_REQUIRED | Sign in required | No customer could be resolved from the token. | Sign in. |
| `403` | NOT_APPROVED_HOST | You need an approved 'stowbo-host' application before you can list space | The caller has no approved host application. | Apply with `POST /client/stowbo/host/apply`. |
| `404` | LISTING_NOT_FOUND | Listing not found | No listing has that id. | Search listings first. |
| `400` | NAME_REQUIRED | A name is required | No `title` or `label`. | — |

Plus the standard platform errors: `429`, `500`.

### Parameters

| Name | In | Type | Required | Description |
| --- | --- | --- | --- | --- |
| `orgid` | header | string | yes | Organization (tenant) identifier. Every request is scoped to this org; data from other orgs is never visible. Issued with your API credentials. |
| `listingId` | path | string | yes | Listing id. |

### Request body

```json
{
  "title": "Cleaning fee",
  "amount": 10,
  "basis": "fixed"
}
```

### Responses

| Status | Meaning |
| --- | --- |
| `201` | The fee record |
| `400` | A name is required — No `title` or `label`. |
| `401` | Sign in required — No customer could be resolved from the token. |
| `403` | You need an approved 'stowbo-host' application before you can list space — The caller has no approved host application. |
| `404` | Listing not found — No listing has that id. |
| `429` | Too Many Requests — More than 100,000 requests from one IP within 5 minutes (configurable per deployment). CORS preflights and requests from inside the platform cluster are not counted. The limiter answers before the error filter, so the body is `{ statusCode, error, message }` with no `path`, `method` or `timeStamp`; the `RateLimit-*` response headers say when the window resets. |
| `500` | An unexpected error occurred. Our team has been notified. — An unhandled server-side failure. |

## DELETE /client/stowbo/host/listings/{listingId}/fees/{feeId}

**Detach a fee from my listing**

`operationId: StowboClientController_removeListingFee`

Removes the fee from the listing. Bookings that already carry it keep their line; the fee record itself stays.

#### Signature

```http
DELETE /client/stowbo/host/listings/{listingId}/fees/{feeId} (listingId: string, feeId: string) -> { success, listing, fees }
```

#### Access

Requires a bearer JWT (`Authorization: Bearer <token>`).

#### Errors

| Status | Code | Message | When | What to do |
| --- | --- | --- | --- | --- |
| `401` | SIGN_IN_REQUIRED | Sign in required | No customer could be resolved from the token. | Sign in. |
| `404` | LISTING_NOT_FOUND | Listing not found | No listing has that id. | Search listings first. |
| `403` | NOT_YOUR_LISTING | Not your listing | The listing belongs to another host. | Hosts can only act on their own listings. |

Plus the standard platform errors: `429`, `500`.

### Parameters

| Name | In | Type | Required | Description |
| --- | --- | --- | --- | --- |
| `orgid` | header | string | yes | Organization (tenant) identifier. Every request is scoped to this org; data from other orgs is never visible. Issued with your API credentials. |
| `listingId` | path | string | yes | Listing id. |
| `feeId` | path | string | yes | `stowbo_fee` sk or name. |

### Responses

| Status | Meaning |
| --- | --- |
| `200` | { success, listing, fees } |
| `401` | Sign in required — No customer could be resolved from the token. |
| `403` | Not your listing — The listing belongs to another host. |
| `404` | Listing not found — No listing has that id. |
| `429` | Too Many Requests — More than 100,000 requests from one IP within 5 minutes (configurable per deployment). CORS preflights and requests from inside the platform cluster are not counted. The limiter answers before the error filter, so the body is `{ statusCode, error, message }` with no `path`, `method` or `timeStamp`; the `RateLimit-*` response headers say when the window resets. |
| `500` | An unexpected error occurred. Our team has been notified. — An unhandled server-side failure. |

## PUT /client/stowbo/host/fees/{feeId}

**Edit one of my fees**

`operationId: StowboClientController_updateFee`

Changes the fee's fields. `name` and `type` cannot be changed.

#### Signature

```http
PUT /client/stowbo/host/fees/{feeId} (feeId: string, body) -> The fee record
```

#### Access

Requires a bearer JWT (`Authorization: Bearer <token>`).

#### Errors

| Status | Code | Message | When | What to do |
| --- | --- | --- | --- | --- |
| `401` | SIGN_IN_REQUIRED | Sign in required | No customer could be resolved from the token. | Sign in. |
| `404` | FEE_NOT_FOUND | Fee not found | No fee has that id. | — |
| `403` | NOT_YOUR_FEE | That fee is not yours | Another host owns the fee. | — |

Plus the standard platform errors: `429`, `500`.

### Parameters

| Name | In | Type | Required | Description |
| --- | --- | --- | --- | --- |
| `orgid` | header | string | yes | Organization (tenant) identifier. Every request is scoped to this org; data from other orgs is never visible. Issued with your API credentials. |
| `feeId` | path | string | yes | `stowbo_fee` sk or name. |

### Request body

```json
{
  "amount": 12
}
```

### Responses

| Status | Meaning |
| --- | --- |
| `200` | The fee record |
| `401` | Sign in required — No customer could be resolved from the token. |
| `403` | That fee is not yours — Another host owns the fee. |
| `404` | Fee not found — No fee has that id. |
| `429` | Too Many Requests — More than 100,000 requests from one IP within 5 minutes (configurable per deployment). CORS preflights and requests from inside the platform cluster are not counted. The limiter answers before the error filter, so the body is `{ statusCode, error, message }` with no `path`, `method` or `timeStamp`; the `RateLimit-*` response headers say when the window resets. |
| `500` | An unexpected error occurred. Our team has been notified. — An unhandled server-side failure. |

## GET /client/stowbo/host/discounts

**List my coupons**

`operationId: StowboClientController_myDiscounts`

The `sf_discount` records this host owns.

#### Signature

```http
GET /client/stowbo/host/discounts () -> Coupons
```

#### Access

Requires a bearer JWT (`Authorization: Bearer <token>`).

#### Errors

| Status | Code | Message | When | What to do |
| --- | --- | --- | --- | --- |
| `401` | SIGN_IN_REQUIRED | Sign in required | No customer could be resolved from the token. | Sign in. |

Plus the standard platform errors: `403`, `429`, `500`.

### Parameters

| Name | In | Type | Required | Description |
| --- | --- | --- | --- | --- |
| `orgid` | header | string | yes | Organization (tenant) identifier. Every request is scoped to this org; data from other orgs is never visible. Issued with your API credentials. |

### Responses

| Status | Meaning |
| --- | --- |
| `200` | Coupons |
| `401` | Sign in required — No customer could be resolved from the token. |
| `403` | You do not have permission to perform this action — The caller is authenticated but lacks the role required by the endpoint, or is acting on another org. |
| `429` | Too Many Requests — More than 100,000 requests from one IP within 5 minutes (configurable per deployment). CORS preflights and requests from inside the platform cluster are not counted. The limiter answers before the error filter, so the body is `{ statusCode, error, message }` with no `path`, `method` or `timeStamp`; the `RateLimit-*` response headers say when the window resets. |
| `500` | An unexpected error occurred. Our team has been notified. — An unhandled server-side failure. |

## POST /client/stowbo/host/discounts

**Create a coupon**

`operationId: StowboClientController_createHostDiscount`

Creates a coupon I own. The server scopes it to Stowbo and to my listings (`applyTo: stowbo`, `merchant` = me, `products` = the listings I pick, or all of mine now and later when empty) — a host coupon can never discount another host.

#### Signature

```http
POST /client/stowbo/host/discounts (body) -> The coupon
```

#### Access

Requires a bearer JWT (`Authorization: Bearer <token>`).

#### Errors

| Status | Code | Message | When | What to do |
| --- | --- | --- | --- | --- |
| `401` | SIGN_IN_REQUIRED | Sign in required | No customer could be resolved from the token. | Sign in. |
| `403` | NOT_APPROVED_HOST | You need an approved 'stowbo-host' application before you can list space | The caller has no approved host application. | Apply with `POST /client/stowbo/host/apply`. |
| `400` | CODE_REQUIRED | A code is required | No code. | — |

Plus the standard platform errors: `429`, `500`.

### Parameters

| Name | In | Type | Required | Description |
| --- | --- | --- | --- | --- |
| `orgid` | header | string | yes | Organization (tenant) identifier. Every request is scoped to this org; data from other orgs is never visible. Issued with your API credentials. |

### Request body

```json
{
  "code": "FALL15",
  "type": "percent",
  "value": 15,
  "listings": [
    "downtown-lockers"
  ]
}
```

### Responses

| Status | Meaning |
| --- | --- |
| `201` | The coupon |
| `400` | A code is required — No code. |
| `401` | Sign in required — No customer could be resolved from the token. |
| `403` | You need an approved 'stowbo-host' application before you can list space — The caller has no approved host application. |
| `429` | Too Many Requests — More than 100,000 requests from one IP within 5 minutes (configurable per deployment). CORS preflights and requests from inside the platform cluster are not counted. The limiter answers before the error filter, so the body is `{ statusCode, error, message }` with no `path`, `method` or `timeStamp`; the `RateLimit-*` response headers say when the window resets. |
| `500` | An unexpected error occurred. Our team has been notified. — An unhandled server-side failure. |

## GET /client/stowbo/host/discounts/{id}/stats

**Get a coupon's usage**

`operationId: StowboClientController_hostDiscountStats`

Every booking that used the code (read from the bills), what it gave away, revenue on the bookings still live, and use against its limits.

#### Signature

```http
GET /client/stowbo/host/discounts/{id}/stats (id: string) -> Usage and the bookings
```

#### Access

Requires a bearer JWT (`Authorization: Bearer <token>`).

#### Errors

| Status | Code | Message | When | What to do |
| --- | --- | --- | --- | --- |
| `401` | SIGN_IN_REQUIRED | Sign in required | No customer could be resolved from the token. | Sign in. |
| `404` | COUPON_NOT_FOUND | Coupon not found | No coupon has that id or code. | — |
| `403` | NOT_YOUR_COUPON | That coupon is not yours | Another host owns the coupon. | — |

Plus the standard platform errors: `429`, `500`.

### Parameters

| Name | In | Type | Required | Description |
| --- | --- | --- | --- | --- |
| `orgid` | header | string | yes | Organization (tenant) identifier. Every request is scoped to this org; data from other orgs is never visible. Issued with your API credentials. |
| `id` | path | string | yes | Coupon (`sf_discount`) sk or code. |

### Responses

| Status | Meaning |
| --- | --- |
| `200` | Usage and the bookings |
| `401` | Sign in required — No customer could be resolved from the token. |
| `403` | That coupon is not yours — Another host owns the coupon. |
| `404` | Coupon not found — No coupon has that id or code. |
| `429` | Too Many Requests — More than 100,000 requests from one IP within 5 minutes (configurable per deployment). CORS preflights and requests from inside the platform cluster are not counted. The limiter answers before the error filter, so the body is `{ statusCode, error, message }` with no `path`, `method` or `timeStamp`; the `RateLimit-*` response headers say when the window resets. |
| `500` | An unexpected error occurred. Our team has been notified. — An unhandled server-side failure. |

## PUT /client/stowbo/host/discounts/{id}

**Edit a coupon**

`operationId: StowboClientController_updateHostDiscount`

Changes a coupon I own. The code cannot be changed; `listings` rescopes it (my listings only).

#### Signature

```http
PUT /client/stowbo/host/discounts/{id} (id: string, body) -> The coupon
```

#### Access

Requires a bearer JWT (`Authorization: Bearer <token>`).

#### Errors

| Status | Code | Message | When | What to do |
| --- | --- | --- | --- | --- |
| `401` | SIGN_IN_REQUIRED | Sign in required | No customer could be resolved from the token. | Sign in. |
| `404` | COUPON_NOT_FOUND | Coupon not found | No coupon has that id or code. | — |
| `403` | NOT_YOUR_COUPON | That coupon is not yours | Another host owns the coupon. | — |

Plus the standard platform errors: `429`, `500`.

### Parameters

| Name | In | Type | Required | Description |
| --- | --- | --- | --- | --- |
| `orgid` | header | string | yes | Organization (tenant) identifier. Every request is scoped to this org; data from other orgs is never visible. Issued with your API credentials. |
| `id` | path | string | yes | Coupon (`sf_discount`) sk or code. |

### Request body

```json
{
  "value": 20
}
```

### Responses

| Status | Meaning |
| --- | --- |
| `200` | The coupon |
| `401` | Sign in required — No customer could be resolved from the token. |
| `403` | That coupon is not yours — Another host owns the coupon. |
| `404` | Coupon not found — No coupon has that id or code. |
| `429` | Too Many Requests — More than 100,000 requests from one IP within 5 minutes (configurable per deployment). CORS preflights and requests from inside the platform cluster are not counted. The limiter answers before the error filter, so the body is `{ statusCode, error, message }` with no `path`, `method` or `timeStamp`; the `RateLimit-*` response headers say when the window resets. |
| `500` | An unexpected error occurred. Our team has been notified. — An unhandled server-side failure. |

## DELETE /client/stowbo/host/discounts/{id}

**Retire a coupon**

`operationId: StowboClientController_deleteHostDiscount`

Deactivates the coupon: the code stops working and bookings that used it keep their discount line.

#### Signature

```http
DELETE /client/stowbo/host/discounts/{id} (id: string) -> { success, id }
```

#### Access

Requires a bearer JWT (`Authorization: Bearer <token>`).

#### Errors

| Status | Code | Message | When | What to do |
| --- | --- | --- | --- | --- |
| `401` | SIGN_IN_REQUIRED | Sign in required | No customer could be resolved from the token. | Sign in. |
| `404` | COUPON_NOT_FOUND | Coupon not found | No coupon has that id or code. | — |
| `403` | NOT_YOUR_COUPON | That coupon is not yours | Another host owns the coupon. | — |

Plus the standard platform errors: `429`, `500`.

### Parameters

| Name | In | Type | Required | Description |
| --- | --- | --- | --- | --- |
| `orgid` | header | string | yes | Organization (tenant) identifier. Every request is scoped to this org; data from other orgs is never visible. Issued with your API credentials. |
| `id` | path | string | yes | Coupon (`sf_discount`) sk or code. |

### Responses

| Status | Meaning |
| --- | --- |
| `200` | { success, id } |
| `401` | Sign in required — No customer could be resolved from the token. |
| `403` | That coupon is not yours — Another host owns the coupon. |
| `404` | Coupon not found — No coupon has that id or code. |
| `429` | Too Many Requests — More than 100,000 requests from one IP within 5 minutes (configurable per deployment). CORS preflights and requests from inside the platform cluster are not counted. The limiter answers before the error filter, so the body is `{ statusCode, error, message }` with no `path`, `method` or `timeStamp`; the `RateLimit-*` response headers say when the window resets. |
| `500` | An unexpected error occurred. Our team has been notified. — An unhandled server-side failure. |

## GET /client/stowbo/host/listings/{id}

**Get one of my listings**

`operationId: StowboClientController_myListing`

A listing with its units and add-ons — **including drafts**, unlike the public view.

#### Signature

```http
GET /client/stowbo/host/listings/{id} (id: string) -> The listing
```

#### Access

Requires a bearer JWT (`Authorization: Bearer <token>`).

#### Errors

| Status | Code | Message | When | What to do |
| --- | --- | --- | --- | --- |
| `401` | HOST_AUTH_REQUIRED | Host authentication required | The caller is not signed in as a host. | Sign in with a host account. |
| `404` | LISTING_NOT_FOUND | Listing not found | No listing has that id. | Search listings first. |
| `403` | NOT_YOUR_LISTING | Not your listing | The listing belongs to another host. | Hosts can only act on their own listings. |

Plus the standard platform errors: `429`, `500`.

#### See also

- `PUT /client/stowbo/host/listings/{id}`

### Parameters

| Name | In | Type | Required | Description |
| --- | --- | --- | --- | --- |
| `orgid` | header | string | yes | Organization (tenant) identifier. Every request is scoped to this org; data from other orgs is never visible. Issued with your API credentials. |
| `id` | path | string | yes | Listing id. |

### Responses

| Status | Meaning |
| --- | --- |
| `200` | The listing |
| `401` | Host authentication required — The caller is not signed in as a host. |
| `403` | Not your listing — The listing belongs to another host. |
| `404` | Listing not found — No listing has that id. |
| `429` | Too Many Requests — More than 100,000 requests from one IP within 5 minutes (configurable per deployment). CORS preflights and requests from inside the platform cluster are not counted. The limiter answers before the error filter, so the body is `{ statusCode, error, message }` with no `path`, `method` or `timeStamp`; the `RateLimit-*` response headers say when the window resets. |
| `500` | An unexpected error occurred. Our team has been notified. — An unhandled server-side failure. |

## PUT /client/stowbo/host/listings/{id}

**Edit a listing**

`operationId: StowboClientController_updateListing`

Changes a listing's details. Rate changes apply to future bookings; bookings already made keep the price they were sold at.

#### Signature

```http
PUT /client/stowbo/host/listings/{id} (id: string, body) -> The updated listing
```

#### Access

Requires a bearer JWT (`Authorization: Bearer <token>`).

#### Errors

| Status | Code | Message | When | What to do |
| --- | --- | --- | --- | --- |
| `401` | HOST_AUTH_REQUIRED | Host authentication required | The caller is not signed in as a host. | Sign in with a host account. |
| `404` | LISTING_NOT_FOUND | Listing not found | No listing has that id. | Search listings first. |
| `403` | NOT_YOUR_LISTING | Not your listing | The listing belongs to another host. | Hosts can only act on their own listings. |
| `400` | NOTHING_TO_UPDATE | Nothing to update | The body has no changes. | Send at least one field. |

Plus the standard platform errors: `429`, `500`.

#### See also

- `PUT /client/stowbo/host/listings/{id}/status`

### Parameters

| Name | In | Type | Required | Description |
| --- | --- | --- | --- | --- |
| `orgid` | header | string | yes | Organization (tenant) identifier. Every request is scoped to this org; data from other orgs is never visible. Issued with your API credentials. |
| `id` | path | string | yes | Listing id. |

### Request body

Fields to change.

```json
{
  "name": "Mission garage bay (covered)"
}
```

### Responses

| Status | Meaning |
| --- | --- |
| `200` | The updated listing |
| `400` | Nothing to update — The body has no changes. |
| `401` | Host authentication required — The caller is not signed in as a host. |
| `403` | Not your listing — The listing belongs to another host. |
| `404` | Listing not found — No listing has that id. |
| `429` | Too Many Requests — More than 100,000 requests from one IP within 5 minutes (configurable per deployment). CORS preflights and requests from inside the platform cluster are not counted. The limiter answers before the error filter, so the body is `{ statusCode, error, message }` with no `path`, `method` or `timeStamp`; the `RateLimit-*` response headers say when the window resets. |
| `500` | An unexpected error occurred. Our team has been notified. — An unhandled server-side failure. |

## DELETE /client/stowbo/host/listings/{id}

**Delete a listing**

`operationId: StowboClientController_deleteListing`

Removes a listing. Unlist it instead when there are bookings against it — deleting a listing people have booked leaves those bookings pointing at nothing.

#### Signature

```http
DELETE /client/stowbo/host/listings/{id} (id: string) -> The result
```

#### Access

Requires a bearer JWT (`Authorization: Bearer <token>`).

#### Notes

- Prefer unlisting when bookings exist.

#### Errors

| Status | Code | Message | When | What to do |
| --- | --- | --- | --- | --- |
| `401` | HOST_AUTH_REQUIRED | Host authentication required | The caller is not signed in as a host. | Sign in with a host account. |
| `404` | LISTING_NOT_FOUND | Listing not found | No listing has that id. | Search listings first. |
| `403` | NOT_YOUR_LISTING | Not your listing | The listing belongs to another host. | Hosts can only act on their own listings. |

Plus the standard platform errors: `429`, `500`.

#### See also

- `PUT /client/stowbo/host/listings/{id}/status`

### Parameters

| Name | In | Type | Required | Description |
| --- | --- | --- | --- | --- |
| `orgid` | header | string | yes | Organization (tenant) identifier. Every request is scoped to this org; data from other orgs is never visible. Issued with your API credentials. |
| `id` | path | string | yes | Listing id. |

### Responses

| Status | Meaning |
| --- | --- |
| `200` | The result |
| `401` | Host authentication required — The caller is not signed in as a host. |
| `403` | Not your listing — The listing belongs to another host. |
| `404` | Listing not found — No listing has that id. |
| `429` | Too Many Requests — More than 100,000 requests from one IP within 5 minutes (configurable per deployment). CORS preflights and requests from inside the platform cluster are not counted. The limiter answers before the error filter, so the body is `{ statusCode, error, message }` with no `path`, `method` or `timeStamp`; the `RateLimit-*` response headers say when the window resets. |
| `500` | An unexpected error occurred. Our team has been notified. — An unhandled server-side failure. |

## GET /client/stowbo/host/listings/{id}/bookings

**Get a listing's bookings**

`operationId: StowboClientController_listingBookings`

Bookings that touch one of the host's listings — the listing dashboard.

#### Signature

```http
GET /client/stowbo/host/listings/{id}/bookings (id: string) -> Bookings
```

#### Access

Requires a bearer JWT (`Authorization: Bearer <token>`).

#### Errors

| Status | Code | Message | When | What to do |
| --- | --- | --- | --- | --- |
| `401` | HOST_AUTH_REQUIRED | Host authentication required | The caller is not signed in as a host. | Sign in with a host account. |
| `404` | LISTING_NOT_FOUND | Listing not found | No listing has that id. | Search listings first. |
| `403` | NOT_YOUR_LISTING | Not your listing | The listing belongs to another host. | Hosts can only act on their own listings. |

Plus the standard platform errors: `429`, `500`.

#### See also

- `GET /client/stowbo/host/today`

### Parameters

| Name | In | Type | Required | Description |
| --- | --- | --- | --- | --- |
| `orgid` | header | string | yes | Organization (tenant) identifier. Every request is scoped to this org; data from other orgs is never visible. Issued with your API credentials. |
| `id` | path | string | yes | Listing id. |

### Responses

| Status | Meaning |
| --- | --- |
| `200` | Bookings |
| `401` | Host authentication required — The caller is not signed in as a host. |
| `403` | Not your listing — The listing belongs to another host. |
| `404` | Listing not found — No listing has that id. |
| `429` | Too Many Requests — More than 100,000 requests from one IP within 5 minutes (configurable per deployment). CORS preflights and requests from inside the platform cluster are not counted. The limiter answers before the error filter, so the body is `{ statusCode, error, message }` with no `path`, `method` or `timeStamp`; the `RateLimit-*` response headers say when the window resets. |
| `500` | An unexpected error occurred. Our team has been notified. — An unhandled server-side failure. |

## GET /client/stowbo/host/bookings

**List every booking at my places**

`operationId: StowboClientController_hostAllBookings`

One list of every booking touching any of my listings, newest first: reference, customer, status, pay state, total, balance, discount, the first space and its window.

#### Signature

```http
GET /client/stowbo/host/bookings (status?: string) -> Booking rows
```

#### Access

Requires a bearer JWT (`Authorization: Bearer <token>`).

#### Errors

| Status | Code | Message | When | What to do |
| --- | --- | --- | --- | --- |
| `401` | SIGN_IN_REQUIRED | Sign in required | No customer could be resolved from the token. | Sign in. |

Plus the standard platform errors: `403`, `429`, `500`.

### Parameters

| Name | In | Type | Required | Description |
| --- | --- | --- | --- | --- |
| `orgid` | header | string | yes | Organization (tenant) identifier. Every request is scoped to this org; data from other orgs is never visible. Issued with your API credentials. |
| `status` | query | string | — | new \| active \| completed \| cancelled \| settled |

### Responses

| Status | Meaning |
| --- | --- |
| `200` | Booking rows |
| `401` | Sign in required — No customer could be resolved from the token. |
| `403` | You do not have permission to perform this action — The caller is authenticated but lacks the role required by the endpoint, or is acting on another org. |
| `429` | Too Many Requests — More than 100,000 requests from one IP within 5 minutes (configurable per deployment). CORS preflights and requests from inside the platform cluster are not counted. The limiter answers before the error filter, so the body is `{ statusCode, error, message }` with no `path`, `method` or `timeStamp`; the `RateLimit-*` response headers say when the window resets. |
| `500` | An unexpected error occurred. Our team has been notified. — An unhandled server-side failure. |

## POST /client/stowbo/host/bookings

**Create a booking for a customer**

`operationId: StowboClientController_hostBook`

Books on a customer's behalf. **Defaults to an OPEN stay**, since the end is often unknown when the booking is opened — pass `endDate` only when the window is genuinely known.

A single detail is enough to identify the customer (a phone number or a plate) and no signup is required. Creates the order plus one booking item per unit. Set `movementIn` to record the first inbound movement in the same call.

#### Signature

```http
POST /client/stowbo/host/bookings (body) -> The booking and its items
```

#### Access

Requires a bearer JWT (`Authorization: Bearer <token>`).

#### Errors

| Status | Code | Message | When | What to do |
| --- | --- | --- | --- | --- |
| `401` | HOST_AUTH_REQUIRED | Host authentication required | The caller is not signed in as a host. | Sign in with a host account. |
| `409` | NO_CAPACITY | The space cannot take it right now | There is no capacity for the request. | Check `GET /client/stowbo/host/today`. |

Plus the standard platform errors: `403`, `429`, `500`.

#### See also

- `GET /client/stowbo/host/bookings/{bookingId}/items`

### Parameters

| Name | In | Type | Required | Description |
| --- | --- | --- | --- | --- |
| `orgid` | header | string | yes | Organization (tenant) identifier. Every request is scoped to this org; data from other orgs is never visible. Issued with your API credentials. |

### Request body

The booking.

```json
{
  "listing": "LST-4821",
  "units": [
    "A1"
  ],
  "customer": {
    "phone": "+15551234567"
  },
  "movementIn": true
}
```

### Responses

| Status | Meaning |
| --- | --- |
| `201` | The booking and its items |
| `401` | Host authentication required — The caller is not signed in as a host. |
| `403` | You do not have permission to perform this action — The caller is authenticated but lacks the role required by the endpoint, or is acting on another org. |
| `409` | The space cannot take it right now — There is no capacity for the request. |
| `429` | Too Many Requests — More than 100,000 requests from one IP within 5 minutes (configurable per deployment). CORS preflights and requests from inside the platform cluster are not counted. The limiter answers before the error filter, so the body is `{ statusCode, error, message }` with no `path`, `method` or `timeStamp`; the `RateLimit-*` response headers say when the window resets. |
| `500` | An unexpected error occurred. Our team has been notified. — An unhandled server-side failure. |

## GET /client/stowbo/host/listings/{id}/calendar

**Get a listing's occupancy calendar**

`operationId: StowboClientController_hostCalendar`

A server-computed occupancy grid for one of the host's listings.

#### Signature

```http
GET /client/stowbo/host/listings/{id}/calendar (id: string, from?: string, days?: integer) -> The calendar
```

#### Access

Requires a bearer JWT (`Authorization: Bearer <token>`).

#### Errors

| Status | Code | Message | When | What to do |
| --- | --- | --- | --- | --- |
| `401` | HOST_AUTH_REQUIRED | Host authentication required | The caller is not signed in as a host. | Sign in with a host account. |
| `404` | LISTING_NOT_FOUND | Listing not found | No listing has that id. | Search listings first. |
| `403` | NOT_YOUR_LISTING | Not your listing | The listing belongs to another host. | Hosts can only act on their own listings. |

Plus the standard platform errors: `429`, `500`.

#### See also

- `GET /client/stowbo/host/listings/{id}/occupancy-now`

### Parameters

| Name | In | Type | Required | Description |
| --- | --- | --- | --- | --- |
| `orgid` | header | string | yes | Organization (tenant) identifier. Every request is scoped to this org; data from other orgs is never visible. Issued with your API credentials. |
| `id` | path | string | yes | Listing id. |
| `from` | query | string | — |  |
| `days` | query | integer | — |  |

### Responses

| Status | Meaning |
| --- | --- |
| `200` | The calendar |
| `401` | Host authentication required — The caller is not signed in as a host. |
| `403` | Not your listing — The listing belongs to another host. |
| `404` | Listing not found — No listing has that id. |
| `429` | Too Many Requests — More than 100,000 requests from one IP within 5 minutes (configurable per deployment). CORS preflights and requests from inside the platform cluster are not counted. The limiter answers before the error filter, so the body is `{ statusCode, error, message }` with no `path`, `method` or `timeStamp`; the `RateLimit-*` response headers say when the window resets. |
| `500` | An unexpected error occurred. Our team has been notified. — An unhandled server-side failure. |

## GET /client/stowbo/host/listings/{id}/blackouts

**Get a listing's blackouts**

`operationId: StowboClientController_hostBlackouts`

Days the host has closed on a listing.

#### Signature

```http
GET /client/stowbo/host/listings/{id}/blackouts (id: string) -> Blackouts
```

#### Access

Requires a bearer JWT (`Authorization: Bearer <token>`).

#### Errors

| Status | Code | Message | When | What to do |
| --- | --- | --- | --- | --- |
| `401` | HOST_AUTH_REQUIRED | Host authentication required | The caller is not signed in as a host. | Sign in with a host account. |
| `404` | LISTING_NOT_FOUND | Listing not found | No listing has that id. | Search listings first. |
| `403` | NOT_YOUR_LISTING | Not your listing | The listing belongs to another host. | Hosts can only act on their own listings. |

Plus the standard platform errors: `429`, `500`.

#### See also

- `POST /client/stowbo/host/listings/{id}/blackouts`

### Parameters

| Name | In | Type | Required | Description |
| --- | --- | --- | --- | --- |
| `orgid` | header | string | yes | Organization (tenant) identifier. Every request is scoped to this org; data from other orgs is never visible. Issued with your API credentials. |
| `id` | path | string | yes | Listing id. |

### Responses

| Status | Meaning |
| --- | --- |
| `200` | Blackouts |
| `401` | Host authentication required — The caller is not signed in as a host. |
| `403` | Not your listing — The listing belongs to another host. |
| `404` | Listing not found — No listing has that id. |
| `429` | Too Many Requests — More than 100,000 requests from one IP within 5 minutes (configurable per deployment). CORS preflights and requests from inside the platform cluster are not counted. The limiter answers before the error filter, so the body is `{ statusCode, error, message }` with no `path`, `method` or `timeStamp`; the `RateLimit-*` response headers say when the window resets. |
| `500` | An unexpected error occurred. Our team has been notified. — An unhandled server-side failure. |

## POST /client/stowbo/host/listings/{id}/blackouts

**Close days on a listing**

`operationId: StowboClientController_addBlackout`

Makes a stretch of days unavailable. Blackouts stop **new** bookings in that range; anything already booked into it stands, so check the calendar before closing days.

#### Signature

```http
POST /client/stowbo/host/listings/{id}/blackouts (id: string, body) -> The blackout
```

#### Access

Requires a bearer JWT (`Authorization: Bearer <token>`).

#### Notes

- Does not cancel existing bookings in the range.

#### Errors

| Status | Code | Message | When | What to do |
| --- | --- | --- | --- | --- |
| `401` | HOST_AUTH_REQUIRED | Host authentication required | The caller is not signed in as a host. | Sign in with a host account. |
| `404` | LISTING_NOT_FOUND | Listing not found | No listing has that id. | Search listings first. |
| `403` | NOT_YOUR_LISTING | Not your listing | The listing belongs to another host. | Hosts can only act on their own listings. |

Plus the standard platform errors: `429`, `500`.

#### See also

- `DELETE /client/stowbo/host/listings/{id}/blackouts/{blackoutId}`

### Parameters

| Name | In | Type | Required | Description |
| --- | --- | --- | --- | --- |
| `orgid` | header | string | yes | Organization (tenant) identifier. Every request is scoped to this org; data from other orgs is never visible. Issued with your API credentials. |
| `id` | path | string | yes | Listing id. |

### Request body

The range to close.

```json
{
  "from": "2026-12-24",
  "to": "2026-12-26",
  "reason": "Closed for the holiday"
}
```

### Responses

| Status | Meaning |
| --- | --- |
| `201` | The blackout |
| `401` | Host authentication required — The caller is not signed in as a host. |
| `403` | Not your listing — The listing belongs to another host. |
| `404` | Listing not found — No listing has that id. |
| `429` | Too Many Requests — More than 100,000 requests from one IP within 5 minutes (configurable per deployment). CORS preflights and requests from inside the platform cluster are not counted. The limiter answers before the error filter, so the body is `{ statusCode, error, message }` with no `path`, `method` or `timeStamp`; the `RateLimit-*` response headers say when the window resets. |
| `500` | An unexpected error occurred. Our team has been notified. — An unhandled server-side failure. |

## DELETE /client/stowbo/host/listings/{id}/blackouts/{blackoutId}

**Re-open blacked-out days**

`operationId: StowboClientController_removeBlackout`

Removes a blackout, putting those days back on the market.

#### Signature

```http
DELETE /client/stowbo/host/listings/{id}/blackouts/{blackoutId} (id: string, blackoutId: string) -> The result
```

#### Access

Requires a bearer JWT (`Authorization: Bearer <token>`).

#### Errors

| Status | Code | Message | When | What to do |
| --- | --- | --- | --- | --- |
| `401` | HOST_AUTH_REQUIRED | Host authentication required | The caller is not signed in as a host. | Sign in with a host account. |
| `404` | LISTING_NOT_FOUND | Listing not found | No listing has that id. | Search listings first. |
| `403` | NOT_YOUR_LISTING | Not your listing | The listing belongs to another host. | Hosts can only act on their own listings. |

Plus the standard platform errors: `429`, `500`.

#### See also

- `GET /client/stowbo/host/listings/{id}/blackouts`

### Parameters

| Name | In | Type | Required | Description |
| --- | --- | --- | --- | --- |
| `orgid` | header | string | yes | Organization (tenant) identifier. Every request is scoped to this org; data from other orgs is never visible. Issued with your API credentials. |
| `id` | path | string | yes | Listing id. |
| `blackoutId` | path | string | yes | Blackout id. |

### Responses

| Status | Meaning |
| --- | --- |
| `200` | The result |
| `401` | Host authentication required — The caller is not signed in as a host. |
| `403` | Not your listing — The listing belongs to another host. |
| `404` | Listing not found — No listing has that id. |
| `429` | Too Many Requests — More than 100,000 requests from one IP within 5 minutes (configurable per deployment). CORS preflights and requests from inside the platform cluster are not counted. The limiter answers before the error filter, so the body is `{ statusCode, error, message }` with no `path`, `method` or `timeStamp`; the `RateLimit-*` response headers say when the window resets. |
| `500` | An unexpected error occurred. Our team has been notified. — An unhandled server-side failure. |

## PUT /client/stowbo/host/listings/{id}/status

**Publish, pause or unlist a listing**

`operationId: StowboClientController_setListingStatus`

Changes what a listing is doing on the market. Pausing stops new bookings; **bookings already taken are unaffected** and still have to be honoured.

#### Signature

```http
PUT /client/stowbo/host/listings/{id}/status (id: string, body) -> The updated listing
```

#### Access

Requires a bearer JWT (`Authorization: Bearer <token>`).

#### Notes

- Existing bookings still stand.

#### Errors

| Status | Code | Message | When | What to do |
| --- | --- | --- | --- | --- |
| `401` | HOST_AUTH_REQUIRED | Host authentication required | The caller is not signed in as a host. | Sign in with a host account. |
| `404` | LISTING_NOT_FOUND | Listing not found | No listing has that id. | Search listings first. |
| `403` | NOT_YOUR_LISTING | Not your listing | The listing belongs to another host. | Hosts can only act on their own listings. |

Plus the standard platform errors: `429`, `500`.

#### See also

- `DELETE /client/stowbo/host/listings/{id}`

### Parameters

| Name | In | Type | Required | Description |
| --- | --- | --- | --- | --- |
| `orgid` | header | string | yes | Organization (tenant) identifier. Every request is scoped to this org; data from other orgs is never visible. Issued with your API credentials. |
| `id` | path | string | yes | Listing id. |

### Request body

The status.

```json
{
  "status": "published"
}
```

### Responses

| Status | Meaning |
| --- | --- |
| `200` | The updated listing |
| `401` | Host authentication required — The caller is not signed in as a host. |
| `403` | Not your listing — The listing belongs to another host. |
| `404` | Listing not found — No listing has that id. |
| `429` | Too Many Requests — More than 100,000 requests from one IP within 5 minutes (configurable per deployment). CORS preflights and requests from inside the platform cluster are not counted. The limiter answers before the error filter, so the body is `{ statusCode, error, message }` with no `path`, `method` or `timeStamp`; the `RateLimit-*` response headers say when the window resets. |
| `500` | An unexpected error occurred. Our team has been notified. — An unhandled server-side failure. |

## PUT /client/stowbo/host/units/{id}

**Edit a unit**

`operationId: StowboClientController_updateUnit`

Changes a unit on one of the host's listings.

#### Signature

```http
PUT /client/stowbo/host/units/{id} (id: string, body) -> The updated unit
```

#### Access

Requires a bearer JWT (`Authorization: Bearer <token>`).

#### Errors

| Status | Code | Message | When | What to do |
| --- | --- | --- | --- | --- |
| `401` | HOST_AUTH_REQUIRED | Host authentication required | The caller is not signed in as a host. | Sign in with a host account. |
| `403` | NOT_YOUR_UNIT | Not your unit | The unit belongs to another host. | Check the id. |

Plus the standard platform errors: `429`, `500`.

#### See also

- `GET /client/stowbo/host/units`

### Parameters

| Name | In | Type | Required | Description |
| --- | --- | --- | --- | --- |
| `orgid` | header | string | yes | Organization (tenant) identifier. Every request is scoped to this org; data from other orgs is never visible. Issued with your API credentials. |
| `id` | path | string | yes | Unit id. |

### Request body

Fields to change.

```json
{
  "name": "A1 (corner)"
}
```

### Responses

| Status | Meaning |
| --- | --- |
| `200` | The updated unit |
| `401` | Host authentication required — The caller is not signed in as a host. |
| `403` | Not your unit — The unit belongs to another host. |
| `429` | Too Many Requests — More than 100,000 requests from one IP within 5 minutes (configurable per deployment). CORS preflights and requests from inside the platform cluster are not counted. The limiter answers before the error filter, so the body is `{ statusCode, error, message }` with no `path`, `method` or `timeStamp`; the `RateLimit-*` response headers say when the window resets. |
| `500` | An unexpected error occurred. Our team has been notified. — An unhandled server-side failure. |

## GET /client/stowbo/host/units

**List my units**

`operationId: StowboClientController_myUnits`

The host's physical units, optionally for one listing.

#### Signature

```http
GET /client/stowbo/host/units (listing?: string) -> Units
```

#### Access

Requires a bearer JWT (`Authorization: Bearer <token>`).

#### Errors

| Status | Code | Message | When | What to do |
| --- | --- | --- | --- | --- |
| `401` | HOST_AUTH_REQUIRED | Host authentication required | The caller is not signed in as a host. | Sign in with a host account. |

Plus the standard platform errors: `403`, `429`, `500`.

#### See also

- `POST /client/stowbo/host/units`

### Parameters

| Name | In | Type | Required | Description |
| --- | --- | --- | --- | --- |
| `orgid` | header | string | yes | Organization (tenant) identifier. Every request is scoped to this org; data from other orgs is never visible. Issued with your API credentials. |
| `listing` | query | string | — |  |

### Responses

| Status | Meaning |
| --- | --- |
| `200` | Units |
| `401` | Host authentication required — The caller is not signed in as a host. |
| `403` | You do not have permission to perform this action — The caller is authenticated but lacks the role required by the endpoint, or is acting on another org. |
| `429` | Too Many Requests — More than 100,000 requests from one IP within 5 minutes (configurable per deployment). CORS preflights and requests from inside the platform cluster are not counted. The limiter answers before the error filter, so the body is `{ statusCode, error, message }` with no `path`, `method` or `timeStamp`; the `RateLimit-*` response headers say when the window resets. |
| `500` | An unexpected error occurred. Our team has been notified. — An unhandled server-side failure. |

## POST /client/stowbo/host/units

**Add units to a listing**

`operationId: StowboClientController_createUnit`

Adds physical units. Give either `names` (an explicit list) **or** `prefix` with `from` and `to` to generate a numbered range — not both.

A range is capped at 500 units per call, which is what stops a typo in `to` creating tens of thousands of units.

#### Signature

```http
POST /client/stowbo/host/units (body) -> The created units
```

#### Access

Requires a bearer JWT (`Authorization: Bearer <token>`).

#### Errors

| Status | Code | Message | When | What to do |
| --- | --- | --- | --- | --- |
| `401` | HOST_AUTH_REQUIRED | Host authentication required | The caller is not signed in as a host. | Sign in with a host account. |
| `404` | LISTING_NOT_FOUND | Listing not found | No listing has that id. | Search listings first. |
| `403` | NOT_YOUR_LISTING | Not your listing | The listing belongs to another host. | Hosts can only act on their own listings. |
| `400` | UNIT_SPEC_INVALID | Give either `names`, or `prefix` with `from` and `to` | The body mixes or omits the two forms. | Pick one form. |

Plus the standard platform errors: `429`, `500`.

#### See also

- `PUT /client/stowbo/host/units/{id}`

### Parameters

| Name | In | Type | Required | Description |
| --- | --- | --- | --- | --- |
| `orgid` | header | string | yes | Organization (tenant) identifier. Every request is scoped to this org; data from other orgs is never visible. Issued with your API credentials. |

### Request body

The units to create.

```json
{
  "listing": "LST-4821",
  "names": [
    "A1",
    "A2",
    "A3"
  ]
}
```

### Responses

| Status | Meaning |
| --- | --- |
| `201` | The created units |
| `400` | Give either `names`, or `prefix` with `from` and `to` — The body mixes or omits the two forms. |
| `401` | Host authentication required — The caller is not signed in as a host. |
| `403` | Not your listing — The listing belongs to another host. |
| `404` | Listing not found — No listing has that id. |
| `429` | Too Many Requests — More than 100,000 requests from one IP within 5 minutes (configurable per deployment). CORS preflights and requests from inside the platform cluster are not counted. The limiter answers before the error filter, so the body is `{ statusCode, error, message }` with no `path`, `method` or `timeStamp`; the `RateLimit-*` response headers say when the window resets. |
| `500` | An unexpected error occurred. Our team has been notified. — An unhandled server-side failure. |

## GET /client/stowbo/host/resolve

**Find a booking by any identifier**

`operationId: StowboClientController_resolve`

One search across plate, phone, booking reference, unit, box number and tag. **The caller does not say which kind it is** — a scanner holds a barcode, a phone line holds whatever was read out.

Partial matches are supported because identifiers arrive mistranscribed. Each result lists the transitions legal on it right now, so a caller need not re-derive the state machine to know what to offer.

#### Signature

```http
GET /client/stowbo/host/resolve (q?: string) -> Matches, each with its legal transitions
```

#### Access

Requires a bearer JWT (`Authorization: Bearer <token>`).

#### Errors

| Status | Code | Message | When | What to do |
| --- | --- | --- | --- | --- |
| `401` | HOST_AUTH_REQUIRED | Host authentication required | The caller is not signed in as a host. | Sign in with a host account. |
| `400` | QUERY_TOO_SHORT | Search for at least 2 characters | `q` is shorter than 2 characters. | Type more. |

Plus the standard platform errors: `403`, `429`, `500`.

#### See also

- `GET /client/stowbo/host/today`

### Parameters

| Name | In | Type | Required | Description |
| --- | --- | --- | --- | --- |
| `orgid` | header | string | yes | Organization (tenant) identifier. Every request is scoped to this org; data from other orgs is never visible. Issued with your API credentials. |
| `q` | query | string | yes | At least 2 characters. |

### Responses

| Status | Meaning |
| --- | --- |
| `200` | Matches, each with its legal transitions |
| `400` | Search for at least 2 characters — `q` is shorter than 2 characters. |
| `401` | Host authentication required — The caller is not signed in as a host. |
| `403` | You do not have permission to perform this action — The caller is authenticated but lacks the role required by the endpoint, or is acting on another org. |
| `429` | Too Many Requests — More than 100,000 requests from one IP within 5 minutes (configurable per deployment). CORS preflights and requests from inside the platform cluster are not counted. The limiter answers before the error filter, so the body is `{ statusCode, error, message }` with no `path`, `method` or `timeStamp`; the `RateLimit-*` response headers say when the window resets. |
| `500` | An unexpected error occurred. Our team has been notified. — An unhandled server-side failure. |

## GET /client/stowbo/host/today

**Get today at my place**

`operationId: StowboClientController_today`

Arrivals due, what is present, departures due, overdue, and capacity remaining **right now** — in one call rather than five.

Per booking **item**, so twelve units can sit in twelve different lanes. Capacity is evaluated for this moment, because that is the question an unplanned arrival poses.

#### Signature

```http
GET /client/stowbo/host/today (listing?: string, date?: string) -> The day's lanes and current capacity
```

#### Access

Requires a bearer JWT (`Authorization: Bearer <token>`).

#### Errors

| Status | Code | Message | When | What to do |
| --- | --- | --- | --- | --- |
| `401` | HOST_AUTH_REQUIRED | Host authentication required | The caller is not signed in as a host. | Sign in with a host account. |

Plus the standard platform errors: `403`, `429`, `500`.

#### See also

- `GET /client/stowbo/host/resolve`

### Parameters

| Name | In | Type | Required | Description |
| --- | --- | --- | --- | --- |
| `orgid` | header | string | yes | Organization (tenant) identifier. Every request is scoped to this org; data from other orgs is never visible. Issued with your API credentials. |
| `listing` | query | string | — |  |
| `date` | query | string | — | ISO date. Defaults to today. |

### Responses

| Status | Meaning |
| --- | --- |
| `200` | The day's lanes and current capacity |
| `401` | Host authentication required — The caller is not signed in as a host. |
| `403` | You do not have permission to perform this action — The caller is authenticated but lacks the role required by the endpoint, or is acting on another org. |
| `429` | Too Many Requests — More than 100,000 requests from one IP within 5 minutes (configurable per deployment). CORS preflights and requests from inside the platform cluster are not counted. The limiter answers before the error filter, so the body is `{ statusCode, error, message }` with no `path`, `method` or `timeStamp`; the `RateLimit-*` response headers say when the window resets. |
| `500` | An unexpected error occurred. Our team has been notified. — An unhandled server-side failure. |

## GET /client/stowbo/host/bookings/{bookingId}/items

**Get an order's items**

`operationId: StowboClientController_bookingItems`

One record per thing booked, each with its own window, session, movements and status. Two can end on Tuesday, three on Friday, one can be disputed, and the rest run on — which is why the item, not the order, is the unit of work.

#### Signature

```http
GET /client/stowbo/host/bookings/{bookingId}/items (bookingId: string) -> Booking items
```

#### Access

Requires a bearer JWT (`Authorization: Bearer <token>`).

#### Errors

| Status | Code | Message | When | What to do |
| --- | --- | --- | --- | --- |
| `401` | HOST_AUTH_REQUIRED | Host authentication required | The caller is not signed in as a host. | Sign in with a host account. |
| `404` | BOOKING_NOT_FOUND | Booking not found | No booking has that id. | List your bookings. |
| `403` | NOT_YOUR_LISTINGS_BOOKING | That booking is not for one of your listings | The booking is at another host's place. | Check the booking id. |

Plus the standard platform errors: `429`, `500`.

#### See also

- `POST /client/stowbo/host/items/{itemId}/checkin`

### Parameters

| Name | In | Type | Required | Description |
| --- | --- | --- | --- | --- |
| `orgid` | header | string | yes | Organization (tenant) identifier. Every request is scoped to this org; data from other orgs is never visible. Issued with your API credentials. |
| `bookingId` | path | string | yes | Booking (order) id. |

### Responses

| Status | Meaning |
| --- | --- |
| `200` | Booking items |
| `401` | Host authentication required — The caller is not signed in as a host. |
| `403` | That booking is not for one of your listings — The booking is at another host's place. |
| `404` | Booking not found — No booking has that id. |
| `429` | Too Many Requests — More than 100,000 requests from one IP within 5 minutes (configurable per deployment). CORS preflights and requests from inside the platform cluster are not counted. The limiter answers before the error filter, so the body is `{ statusCode, error, message }` with no `path`, `method` or `timeStamp`; the `RateLimit-*` response headers say when the window resets. |
| `500` | An unexpected error occurred. Our team has been notified. — An unhandled server-side failure. |

## POST /client/stowbo/host/items/{itemId}/checkin

**Check in an item**

`operationId: StowboClientController_checkIn`

Opens the session on **one booking item**. Distinct from creating the booking, which may have been weeks earlier, and from anything physically moving in — a session can be open with nothing in it yet.

Idempotent: checking in twice is harmless.

#### Signature

```http
POST /client/stowbo/host/items/{itemId}/checkin (itemId: string, body) -> The item
```

#### Access

Requires a bearer JWT (`Authorization: Bearer <token>`).

#### Notes

- Idempotent.

#### Errors

| Status | Code | Message | When | What to do |
| --- | --- | --- | --- | --- |
| `401` | HOST_AUTH_REQUIRED | Host authentication required | The caller is not signed in as a host. | Sign in with a host account. |
| `404` | ITEM_NOT_FOUND | Booking item not found | No booking item has that id. | List the order's items. |
| `409` | SESSION_CLOSED | That session is closed | The item was already checked out. | A closed session cannot be reopened. |

Plus the standard platform errors: `403`, `429`, `500`.

#### See also

- `POST /client/stowbo/host/items/{itemId}/movement`

### Parameters

| Name | In | Type | Required | Description |
| --- | --- | --- | --- | --- |
| `orgid` | header | string | yes | Organization (tenant) identifier. Every request is scoped to this org; data from other orgs is never visible. Issued with your API credentials. |
| `itemId` | path | string | yes | Booking **item** id — one thing booked, not the whole order. |

### Request body

Optional check-in detail.

```json
{
  "note": "Guest arrived early"
}
```

### Responses

| Status | Meaning |
| --- | --- |
| `201` | The item |
| `401` | Host authentication required — The caller is not signed in as a host. |
| `403` | You do not have permission to perform this action — The caller is authenticated but lacks the role required by the endpoint, or is acting on another org. |
| `404` | Booking item not found — No booking item has that id. |
| `409` | That session is closed — The item was already checked out. |
| `429` | Too Many Requests — More than 100,000 requests from one IP within 5 minutes (configurable per deployment). CORS preflights and requests from inside the platform cluster are not counted. The limiter answers before the error filter, so the body is `{ statusCode, error, message }` with no `path`, `method` or `timeStamp`; the `RateLimit-*` response headers say when the window resets. |
| `500` | An unexpected error occurred. Our team has been notified. — An unhandled server-side failure. |

## POST /client/stowbo/host/items/{itemId}/movement

**Record a movement**

`operationId: StowboClientController_movement`

Records that something went in or out, inside one check-in. **Unlimited and append-only**: fourteen movements over a week is still one booking and one charge — movements are never billable and never touch capacity.

Everything past `direction` is optional: photos, note, condition, signature, id, `declaredValue`, `releasedTo`, identifier, unit. The optional fields are what a custody dispute is settled on, so they are worth filling in at hand-over rather than reconstructing later.

#### Signature

```http
POST /client/stowbo/host/items/{itemId}/movement (itemId: string, body) -> The movement
```

#### Access

Requires a bearer JWT (`Authorization: Bearer <token>`).

#### Notes

- Never billable; never releases the space.

#### Errors

| Status | Code | Message | When | What to do |
| --- | --- | --- | --- | --- |
| `401` | HOST_AUTH_REQUIRED | Host authentication required | The caller is not signed in as a host. | Sign in with a host account. |
| `404` | ITEM_NOT_FOUND | Booking item not found | No booking item has that id. | List the order's items. |
| `400` | DIRECTION_INVALID | direction must be 'in' or 'out' | `direction` is missing or invalid. | Send `in` or `out`. |
| `409` | ALREADY_THERE | That is already here / That is already out | The movement repeats the last direction. | Check the current state. |

Plus the standard platform errors: `403`, `429`, `500`.

#### See also

- `GET /client/stowbo/host/items/{itemId}/checkout`

### Parameters

| Name | In | Type | Required | Description |
| --- | --- | --- | --- | --- |
| `orgid` | header | string | yes | Organization (tenant) identifier. Every request is scoped to this org; data from other orgs is never visible. Issued with your API credentials. |
| `itemId` | path | string | yes | Booking **item** id — one thing booked, not the whole order. |

### Request body

The movement.

```json
{
  "direction": "out",
  "releasedTo": "Grace Hopper",
  "condition": "good",
  "note": "Signed for at the desk"
}
```

### Responses

| Status | Meaning |
| --- | --- |
| `201` | The movement |
| `400` | direction must be 'in' or 'out' — `direction` is missing or invalid. |
| `401` | Host authentication required — The caller is not signed in as a host. |
| `403` | You do not have permission to perform this action — The caller is authenticated but lacks the role required by the endpoint, or is acting on another org. |
| `404` | Booking item not found — No booking item has that id. |
| `409` | That is already here / That is already out — The movement repeats the last direction. |
| `429` | Too Many Requests — More than 100,000 requests from one IP within 5 minutes (configurable per deployment). CORS preflights and requests from inside the platform cluster are not counted. The limiter answers before the error filter, so the body is `{ statusCode, error, message }` with no `path`, `method` or `timeStamp`; the `RateLimit-*` response headers say when the window resets. |
| `500` | An unexpected error occurred. Our team has been notified. — An unhandled server-side failure. |

## POST /client/stowbo/host/items/{itemId}/assign

**Assign or move an item**

`operationId: StowboClientController_assign`

Puts a thing somewhere, or moves it. **Re-assignable on purpose**: where a thing sits can change any number of times during a session, and an assignment made at intake is not necessarily where it still is.

#### Signature

```http
POST /client/stowbo/host/items/{itemId}/assign (itemId: string, body) -> The result
```

#### Access

Requires a bearer JWT (`Authorization: Bearer <token>`).

#### Errors

| Status | Code | Message | When | What to do |
| --- | --- | --- | --- | --- |
| `401` | HOST_AUTH_REQUIRED | Host authentication required | The caller is not signed in as a host. | Sign in with a host account. |
| `404` | ITEM_NOT_FOUND | Booking item not found | No booking item has that id. | List the order's items. |

Plus the standard platform errors: `403`, `429`, `500`.

#### See also

- `GET /client/stowbo/host/listings/{id}/occupancy-now`

### Parameters

| Name | In | Type | Required | Description |
| --- | --- | --- | --- | --- |
| `orgid` | header | string | yes | Organization (tenant) identifier. Every request is scoped to this org; data from other orgs is never visible. Issued with your API credentials. |
| `itemId` | path | string | yes | Booking **item** id — one thing booked, not the whole order. |

### Request body

Where it goes.

```json
{
  "unit": "A1"
}
```

### Responses

| Status | Meaning |
| --- | --- |
| `201` | The result |
| `401` | Host authentication required — The caller is not signed in as a host. |
| `403` | You do not have permission to perform this action — The caller is authenticated but lacks the role required by the endpoint, or is acting on another org. |
| `404` | Booking item not found — No booking item has that id. |
| `429` | Too Many Requests — More than 100,000 requests from one IP within 5 minutes (configurable per deployment). CORS preflights and requests from inside the platform cluster are not counted. The limiter answers before the error filter, so the body is `{ statusCode, error, message }` with no `path`, `method` or `timeStamp`; the `RateLimit-*` response headers say when the window resets. |
| `500` | An unexpected error occurred. Our team has been notified. — An unhandled server-side failure. |

## GET /client/stowbo/host/items/{itemId}/checkout

**Preview a check-out**

`operationId: StowboClientController_itemCheckoutStatement`

What closing this item will add to the bill. **The same computation check-out runs**, so the preview cannot disagree with what is charged. Writes nothing.

An open stay is priced start-to-exit; a fixed one accrues overstay past its window. `accruing` is true while a meter is still running, meaning the number will keep moving. `canCheckOut` is false while the thing is still present.

#### Signature

```http
GET /client/stowbo/host/items/{itemId}/checkout (itemId: string) -> The projected charge, with `accruing` and `canCheckOut`
```

#### Access

Requires a bearer JWT (`Authorization: Bearer <token>`).

#### Notes

- Read-only.

#### Errors

| Status | Code | Message | When | What to do |
| --- | --- | --- | --- | --- |
| `401` | HOST_AUTH_REQUIRED | Host authentication required | The caller is not signed in as a host. | Sign in with a host account. |
| `404` | ITEM_NOT_FOUND | Booking item not found | No booking item has that id. | List the order's items. |

Plus the standard platform errors: `403`, `429`, `500`.

#### See also

- `POST /client/stowbo/host/items/{itemId}/checkout`

### Parameters

| Name | In | Type | Required | Description |
| --- | --- | --- | --- | --- |
| `orgid` | header | string | yes | Organization (tenant) identifier. Every request is scoped to this org; data from other orgs is never visible. Issued with your API credentials. |
| `itemId` | path | string | yes | Booking **item** id — one thing booked, not the whole order. |

### Responses

| Status | Meaning |
| --- | --- |
| `200` | The projected charge, with `accruing` and `canCheckOut` |
| `401` | Host authentication required — The caller is not signed in as a host. |
| `403` | You do not have permission to perform this action — The caller is authenticated but lacks the role required by the endpoint, or is acting on another org. |
| `404` | Booking item not found — No booking item has that id. |
| `429` | Too Many Requests — More than 100,000 requests from one IP within 5 minutes (configurable per deployment). CORS preflights and requests from inside the platform cluster are not counted. The limiter answers before the error filter, so the body is `{ statusCode, error, message }` with no `path`, `method` or `timeStamp`; the `RateLimit-*` response headers say when the window resets. |
| `500` | An unexpected error occurred. Our team has been notified. — An unhandled server-side failure. |

Example response:

```json
{
  "total": 4200,
  "accruing": true,
  "canCheckOut": false
}
```

## POST /client/stowbo/host/items/{itemId}/checkout

**Check out an item**

`operationId: StowboClientController_checkOut`

**A move-out is not a check-out.** One check-in holds any number of movements and the space stays held throughout; this is the only place a booking item stops occupying capacity.

What it actually cost is added to the **order** as line items. Closing two of twelve leaves the other ten running, and the order completes only when every item has.

Refused while the thing is still present — move it out first.

#### Signature

```http
POST /client/stowbo/host/items/{itemId}/checkout (itemId: string, body) -> The closed item and what it cost
```

#### Access

Requires a bearer JWT (`Authorization: Bearer <token>`).

#### Notes

- Releases capacity and bills the stay.

#### Errors

| Status | Code | Message | When | What to do |
| --- | --- | --- | --- | --- |
| `401` | HOST_AUTH_REQUIRED | Host authentication required | The caller is not signed in as a host. | Sign in with a host account. |
| `404` | ITEM_NOT_FOUND | Booking item not found | No booking item has that id. | List the order's items. |
| `409` | STILL_PRESENT | Still present — move it out first | The last movement was inbound. | Record an outbound movement. |

Plus the standard platform errors: `403`, `429`, `500`.

#### See also

- `GET /client/stowbo/host/items/{itemId}/checkout`

### Parameters

| Name | In | Type | Required | Description |
| --- | --- | --- | --- | --- |
| `orgid` | header | string | yes | Organization (tenant) identifier. Every request is scoped to this org; data from other orgs is never visible. Issued with your API credentials. |
| `itemId` | path | string | yes | Booking **item** id — one thing booked, not the whole order. |

### Request body

Optional check-out detail.

```json
{
  "note": "All clear"
}
```

### Responses

| Status | Meaning |
| --- | --- |
| `201` | The closed item and what it cost |
| `401` | Host authentication required — The caller is not signed in as a host. |
| `403` | You do not have permission to perform this action — The caller is authenticated but lacks the role required by the endpoint, or is acting on another org. |
| `404` | Booking item not found — No booking item has that id. |
| `409` | Still present — move it out first — The last movement was inbound. |
| `429` | Too Many Requests — More than 100,000 requests from one IP within 5 minutes (configurable per deployment). CORS preflights and requests from inside the platform cluster are not counted. The limiter answers before the error filter, so the body is `{ statusCode, error, message }` with no `path`, `method` or `timeStamp`; the `RateLimit-*` response headers say when the window resets. |
| `500` | An unexpected error occurred. Our team has been notified. — An unhandled server-side failure. |

## GET /client/stowbo/host/handover

**Resolve a scanned pickup code**

`operationId: StowboClientController_hostHandover`

Looks up a code scanned at the desk. A booking's own code resolves to the owner's items (minus any handed to someone else); a hand-off code resolves to its items and what must be checked (`verify[]`, `photoRequired`). `allowed` says whether anything can be handed over. Nothing is released here.

#### Signature

```http
GET /client/stowbo/host/handover (code?: string) -> { allowed, kind: owner\|delegate, booking, delegation, collector, verify, verifyLabel, photoRequired, validUntil, note, items, … }
```

#### Access

Requires a bearer JWT (`Authorization: Bearer <token>`).

#### Errors

| Status | Code | Message | When | What to do |
| --- | --- | --- | --- | --- |
| `401` | SIGN_IN_REQUIRED | Sign in required | No customer could be resolved from the token. | Sign in. |
| `400` | CODE_REQUIRED | code is required | No code. | — |
| `404` | NO_PICKUP | No pickup matches that code | Unknown code. | — |
| `403` | OTHER_HOST | That code belongs to another host | The items are at someone else's listing. | — |

Plus the standard platform errors: `429`, `500`.

#### See also

- `POST /client/stowbo/host/handover`

### Parameters

| Name | In | Type | Required | Description |
| --- | --- | --- | --- | --- |
| `orgid` | header | string | yes | Organization (tenant) identifier. Every request is scoped to this org; data from other orgs is never visible. Issued with your API credentials. |
| `code` | query | string | yes |  |
| `itemId` | path | any | yes |  |

### Responses

| Status | Meaning |
| --- | --- |
| `200` | { allowed, kind: owner\|delegate, booking, delegation, collector, verify, verifyLabel, photoRequired, validUntil, note, items, … } |
| `400` | code is required — No code. |
| `401` | Sign in required — No customer could be resolved from the token. |
| `403` | That code belongs to another host — The items are at someone else's listing. |
| `404` | No pickup matches that code — Unknown code. |
| `409` | Still present — move it out first |
| `429` | Too Many Requests — More than 100,000 requests from one IP within 5 minutes (configurable per deployment). CORS preflights and requests from inside the platform cluster are not counted. The limiter answers before the error filter, so the body is `{ statusCode, error, message }` with no `path`, `method` or `timeStamp`; the `RateLimit-*` response headers say when the window resets. |
| `500` | An unexpected error occurred. Our team has been notified. — An unhandled server-side failure. |

## POST /client/stowbo/host/handover

**Hand items over**

`operationId: StowboClientController_hostCompleteHandover`

Completes a pickup: moves each item out and checks it out, stamping who collected it and what was verified. `verified` must cover what the pass demands; a hand-off also needs a photo.

#### Signature

```http
POST /client/stowbo/host/handover (body) -> { handedOver: [{ item, orderComplete }], collectedBy, verified, delegation }
```

#### Access

Requires a bearer JWT (`Authorization: Bearer <token>`).

#### Errors

| Status | Code | Message | When | What to do |
| --- | --- | --- | --- | --- |
| `401` | SIGN_IN_REQUIRED | Sign in required | No customer could be resolved from the token. | Sign in. |
| `409` | NOT_ALLOWED | Nothing to hand over | The code resolves to nothing collectable (expired, revoked, already collected). The body `code` carries the reason. | — |
| `400` | VERIFY_REQUIRED | Confirm <checks> before handing over | `verified` is missing a required check. The body carries `missing`. | — |

Plus the standard platform errors: `403`, `429`, `500`.

### Parameters

| Name | In | Type | Required | Description |
| --- | --- | --- | --- | --- |
| `orgid` | header | string | yes | Organization (tenant) identifier. Every request is scoped to this org; data from other orgs is never visible. Issued with your API credentials. |

### Request body

```json
{
  "code": "K7Q2M9",
  "verified": [
    "qr",
    "id"
  ],
  "photos": [
    {
      "url": "https://files.example.com/handover.jpg"
    }
  ]
}
```

### Responses

| Status | Meaning |
| --- | --- |
| `201` | { handedOver: [{ item, orderComplete }], collectedBy, verified, delegation } |
| `400` | Confirm <checks> before handing over — `verified` is missing a required check. The body carries `missing`. |
| `401` | Sign in required — No customer could be resolved from the token. |
| `403` | You do not have permission to perform this action — The caller is authenticated but lacks the role required by the endpoint, or is acting on another org. |
| `409` | Nothing to hand over — The code resolves to nothing collectable (expired, revoked, already collected). The body `code` carries the reason. |
| `429` | Too Many Requests — More than 100,000 requests from one IP within 5 minutes (configurable per deployment). CORS preflights and requests from inside the platform cluster are not counted. The limiter answers before the error filter, so the body is `{ statusCode, error, message }` with no `path`, `method` or `timeStamp`; the `RateLimit-*` response headers say when the window resets. |
| `500` | An unexpected error occurred. Our team has been notified. — An unhandled server-side failure. |

## POST /client/stowbo/host/items/{itemId}/refuse

**Refuse a pickup**

`operationId: StowboClientController_hostRefusePickup`

Records that a pickup was refused at the desk. Nothing moves; the owner is told.

#### Signature

```http
POST /client/stowbo/host/items/{itemId}/refuse (itemId: string, body) -> The refusal entry
```

#### Access

Requires a bearer JWT (`Authorization: Bearer <token>`).

#### Errors

| Status | Code | Message | When | What to do |
| --- | --- | --- | --- | --- |
| `401` | SIGN_IN_REQUIRED | Sign in required | No customer could be resolved from the token. | Sign in. |
| `404` | ITEM_NOT_FOUND | Booking item not found | No booking item has that id. | List the order's items. |
| `403` | NOT_YOUR_ITEM | Not your booking item | The item belongs to another customer. | Check the item id. |

Plus the standard platform errors: `429`, `500`.

### Parameters

| Name | In | Type | Required | Description |
| --- | --- | --- | --- | --- |
| `orgid` | header | string | yes | Organization (tenant) identifier. Every request is scoped to this org; data from other orgs is never visible. Issued with your API credentials. |
| `itemId` | path | string | yes | Booking **item** id — one thing booked, not the whole order. |

### Request body

```json
{
  "reason": "id_mismatch",
  "who": "Man claiming to be Sam"
}
```

### Responses

| Status | Meaning |
| --- | --- |
| `201` | The refusal entry |
| `401` | Sign in required — No customer could be resolved from the token. |
| `403` | Not your booking item — The item belongs to another customer. |
| `404` | Booking item not found — No booking item has that id. |
| `429` | Too Many Requests — More than 100,000 requests from one IP within 5 minutes (configurable per deployment). CORS preflights and requests from inside the platform cluster are not counted. The limiter answers before the error filter, so the body is `{ statusCode, error, message }` with no `path`, `method` or `timeStamp`; the `RateLimit-*` response headers say when the window resets. |
| `500` | An unexpected error occurred. Our team has been notified. — An unhandled server-side failure. |

## GET /client/stowbo/host/bookings/{bookingId}/delegations

**List the hand-offs on a booking I host**

`operationId: StowboClientController_hostBookingDelegations`

Every hand-off on the booking, newest first.

#### Signature

```http
GET /client/stowbo/host/bookings/{bookingId}/delegations (bookingId: string) -> Hand-offs
```

#### Access

Requires a bearer JWT (`Authorization: Bearer <token>`).

#### Errors

| Status | Code | Message | When | What to do |
| --- | --- | --- | --- | --- |
| `401` | SIGN_IN_REQUIRED | Sign in required | No customer could be resolved from the token. | Sign in. |
| `404` | BOOKING_NOT_FOUND | Booking not found | No booking has that id. | List your bookings. |
| `403` | NOT_YOUR_LISTINGS_BOOKING | That booking is not for one of your listings | The booking is at another host's place. | Check the booking id. |

Plus the standard platform errors: `429`, `500`.

### Parameters

| Name | In | Type | Required | Description |
| --- | --- | --- | --- | --- |
| `orgid` | header | string | yes | Organization (tenant) identifier. Every request is scoped to this org; data from other orgs is never visible. Issued with your API credentials. |
| `bookingId` | path | string | yes | Booking (order) id. |

### Responses

| Status | Meaning |
| --- | --- |
| `200` | Hand-offs |
| `401` | Sign in required — No customer could be resolved from the token. |
| `403` | That booking is not for one of your listings — The booking is at another host's place. |
| `404` | Booking not found — No booking has that id. |
| `429` | Too Many Requests — More than 100,000 requests from one IP within 5 minutes (configurable per deployment). CORS preflights and requests from inside the platform cluster are not counted. The limiter answers before the error filter, so the body is `{ statusCode, error, message }` with no `path`, `method` or `timeStamp`; the `RateLimit-*` response headers say when the window resets. |
| `500` | An unexpected error occurred. Our team has been notified. — An unhandled server-side failure. |

## GET /client/stowbo/host/handovers

**List hand-offs at my places**

`operationId: StowboClientController_hostHandovers`

Hand-offs on my listings — who collected what, when, what was verified — plus refusals.

#### Signature

```http
GET /client/stowbo/host/handovers (from?: string, to?: string, listing?: string, status?: string, booking?: string, customer?: string) -> { handoffs, refusals, totals }
```

#### Access

Requires a bearer JWT (`Authorization: Bearer <token>`).

#### Errors

| Status | Code | Message | When | What to do |
| --- | --- | --- | --- | --- |
| `401` | SIGN_IN_REQUIRED | Sign in required | No customer could be resolved from the token. | Sign in. |

Plus the standard platform errors: `403`, `429`, `500`.

### Parameters

| Name | In | Type | Required | Description |
| --- | --- | --- | --- | --- |
| `orgid` | header | string | yes | Organization (tenant) identifier. Every request is scoped to this org; data from other orgs is never visible. Issued with your API credentials. |
| `from` | query | string | — |  |
| `to` | query | string | — |  |
| `listing` | query | string | — |  |
| `status` | query | string | — |  |
| `booking` | query | string | — |  |
| `customer` | query | string | — |  |

### Responses

| Status | Meaning |
| --- | --- |
| `200` | { handoffs, refusals, totals } |
| `401` | Sign in required — No customer could be resolved from the token. |
| `403` | You do not have permission to perform this action — The caller is authenticated but lacks the role required by the endpoint, or is acting on another org. |
| `429` | Too Many Requests — More than 100,000 requests from one IP within 5 minutes (configurable per deployment). CORS preflights and requests from inside the platform cluster are not counted. The limiter answers before the error filter, so the body is `{ statusCode, error, message }` with no `path`, `method` or `timeStamp`; the `RateLimit-*` response headers say when the window resets. |
| `500` | An unexpected error occurred. Our team has been notified. — An unhandled server-side failure. |

## GET /client/stowbo/host/listings/{id}/occupancy-now

**Get current occupancy**

`operationId: StowboClientController_occupancyNow`

What is in which unit right now. **Occupancy, not custody**: whether what is in a given unit is what is supposed to be there. Nothing here releases anything.

#### Signature

```http
GET /client/stowbo/host/listings/{id}/occupancy-now (id: string) -> Current occupancy by unit
```

#### Access

Requires a bearer JWT (`Authorization: Bearer <token>`).

#### Errors

| Status | Code | Message | When | What to do |
| --- | --- | --- | --- | --- |
| `401` | HOST_AUTH_REQUIRED | Host authentication required | The caller is not signed in as a host. | Sign in with a host account. |
| `404` | LISTING_NOT_FOUND | Listing not found | No listing has that id. | Search listings first. |
| `403` | NOT_YOUR_LISTING | Not your listing | The listing belongs to another host. | Hosts can only act on their own listings. |

Plus the standard platform errors: `429`, `500`.

#### See also

- `GET /client/stowbo/host/today`

### Parameters

| Name | In | Type | Required | Description |
| --- | --- | --- | --- | --- |
| `orgid` | header | string | yes | Organization (tenant) identifier. Every request is scoped to this org; data from other orgs is never visible. Issued with your API credentials. |
| `id` | path | string | yes | Listing id. |

### Responses

| Status | Meaning |
| --- | --- |
| `200` | Current occupancy by unit |
| `401` | Host authentication required — The caller is not signed in as a host. |
| `403` | Not your listing — The listing belongs to another host. |
| `404` | Listing not found — No listing has that id. |
| `429` | Too Many Requests — More than 100,000 requests from one IP within 5 minutes (configurable per deployment). CORS preflights and requests from inside the platform cluster are not counted. The limiter answers before the error filter, so the body is `{ statusCode, error, message }` with no `path`, `method` or `timeStamp`; the `RateLimit-*` response headers say when the window resets. |
| `500` | An unexpected error occurred. Our team has been notified. — An unhandled server-side failure. |

## POST /client/stowbo/host/bookings/{bookingId}/charge

**Add a charge to the bill**

`operationId: StowboClientController_hostCharge`

Adds a charge or credit line to an order — a damage fee, a late charge, a goodwill credit. It becomes part of what the guest owes.

#### Signature

```http
POST /client/stowbo/host/bookings/{bookingId}/charge (bookingId: string, body) -> The updated bill
```

#### Access

Requires a bearer JWT (`Authorization: Bearer <token>`).

#### Notes

- Changes what the guest owes.

#### Errors

| Status | Code | Message | When | What to do |
| --- | --- | --- | --- | --- |
| `401` | HOST_AUTH_REQUIRED | Host authentication required | The caller is not signed in as a host. | Sign in with a host account. |
| `404` | BOOKING_NOT_FOUND | Booking not found | No booking has that id. | List your bookings. |
| `403` | NOT_YOUR_LISTINGS_BOOKING | That booking is not for one of your listings | The booking is at another host's place. | Check the booking id. |

Plus the standard platform errors: `429`, `500`.

#### See also

- `POST /client/stowbo/host/bookings/{bookingId}/refund`

### Parameters

| Name | In | Type | Required | Description |
| --- | --- | --- | --- | --- |
| `orgid` | header | string | yes | Organization (tenant) identifier. Every request is scoped to this org; data from other orgs is never visible. Issued with your API credentials. |
| `bookingId` | path | string | yes | Booking (order) id. |

### Request body

The charge.

```json
{
  "amount": 2500,
  "description": "Damage to the door seal"
}
```

### Responses

| Status | Meaning |
| --- | --- |
| `201` | The updated bill |
| `401` | Host authentication required — The caller is not signed in as a host. |
| `403` | That booking is not for one of your listings — The booking is at another host's place. |
| `404` | Booking not found — No booking has that id. |
| `429` | Too Many Requests — More than 100,000 requests from one IP within 5 minutes (configurable per deployment). CORS preflights and requests from inside the platform cluster are not counted. The limiter answers before the error filter, so the body is `{ statusCode, error, message }` with no `path`, `method` or `timeStamp`; the `RateLimit-*` response headers say when the window resets. |
| `500` | An unexpected error occurred. Our team has been notified. — An unhandled server-side failure. |

## POST /client/stowbo/host/bookings/{bookingId}/refund

**Credit the bill**

`operationId: StowboClientController_hostRefund`

Adds a credit to an order, reducing what is owed or returning money already taken.

#### Signature

```http
POST /client/stowbo/host/bookings/{bookingId}/refund (bookingId: string, body) -> The updated bill
```

#### Access

Requires a bearer JWT (`Authorization: Bearer <token>`).

#### Notes

- Returns money to the guest.

#### Errors

| Status | Code | Message | When | What to do |
| --- | --- | --- | --- | --- |
| `401` | HOST_AUTH_REQUIRED | Host authentication required | The caller is not signed in as a host. | Sign in with a host account. |
| `404` | BOOKING_NOT_FOUND | Booking not found | No booking has that id. | List your bookings. |
| `403` | NOT_YOUR_LISTINGS_BOOKING | That booking is not for one of your listings | The booking is at another host's place. | Check the booking id. |

Plus the standard platform errors: `429`, `500`.

#### See also

- `POST /client/stowbo/host/bookings/{bookingId}/lines/{index}/reverse`

### Parameters

| Name | In | Type | Required | Description |
| --- | --- | --- | --- | --- |
| `orgid` | header | string | yes | Organization (tenant) identifier. Every request is scoped to this org; data from other orgs is never visible. Issued with your API credentials. |
| `bookingId` | path | string | yes | Booking (order) id. |

### Request body

The credit.

```json
{
  "amount": 1000,
  "description": "Goodwill — late retrieval"
}
```

### Responses

| Status | Meaning |
| --- | --- |
| `201` | The updated bill |
| `401` | Host authentication required — The caller is not signed in as a host. |
| `403` | That booking is not for one of your listings — The booking is at another host's place. |
| `404` | Booking not found — No booking has that id. |
| `429` | Too Many Requests — More than 100,000 requests from one IP within 5 minutes (configurable per deployment). CORS preflights and requests from inside the platform cluster are not counted. The limiter answers before the error filter, so the body is `{ statusCode, error, message }` with no `path`, `method` or `timeStamp`; the `RateLimit-*` response headers say when the window resets. |
| `500` | An unexpected error occurred. Our team has been notified. — An unhandled server-side failure. |

## POST /client/stowbo/host/bookings/{bookingId}/lines/{index}/reverse

**Undo a bill line**

`operationId: StowboClientController_hostReverse`

Reverses a line. **The original stays** and its opposite is added, so a disputed bill still explains itself rather than quietly no longer showing the mistake.

#### Signature

```http
POST /client/stowbo/host/bookings/{bookingId}/lines/{index}/reverse (bookingId: string, index: string, body) -> The updated bill
```

#### Access

Requires a bearer JWT (`Authorization: Bearer <token>`).

#### Notes

- Adds an offsetting line; nothing is erased.

#### Errors

| Status | Code | Message | When | What to do |
| --- | --- | --- | --- | --- |
| `401` | HOST_AUTH_REQUIRED | Host authentication required | The caller is not signed in as a host. | Sign in with a host account. |
| `404` | BOOKING_NOT_FOUND | Booking not found | No booking has that id. | List your bookings. |
| `403` | NOT_YOUR_LISTINGS_BOOKING | That booking is not for one of your listings | The booking is at another host's place. | Check the booking id. |
| `409` | ALREADY_REVERSED | Already reversed | The line was already undone. | Nothing to do. |

Plus the standard platform errors: `429`, `500`.

#### See also

- `POST /client/stowbo/host/bookings/{bookingId}/settle`

### Parameters

| Name | In | Type | Required | Description |
| --- | --- | --- | --- | --- |
| `orgid` | header | string | yes | Organization (tenant) identifier. Every request is scoped to this org; data from other orgs is never visible. Issued with your API credentials. |
| `bookingId` | path | string | yes | Booking (order) id. |
| `index` | path | string | yes | Line index on the order. |

### Request body

Optional reason.

```json
{
  "reason": "Charged in error"
}
```

### Responses

| Status | Meaning |
| --- | --- |
| `201` | The updated bill |
| `401` | Host authentication required — The caller is not signed in as a host. |
| `403` | That booking is not for one of your listings — The booking is at another host's place. |
| `404` | Booking not found — No booking has that id. |
| `409` | Already reversed — The line was already undone. |
| `429` | Too Many Requests — More than 100,000 requests from one IP within 5 minutes (configurable per deployment). CORS preflights and requests from inside the platform cluster are not counted. The limiter answers before the error filter, so the body is `{ statusCode, error, message }` with no `path`, `method` or `timeStamp`; the `RateLimit-*` response headers say when the window resets. |
| `500` | An unexpected error occurred. Our team has been notified. — An unhandled server-side failure. |

## POST /client/stowbo/host/bookings/{bookingId}/settle

**Settle an order and pay out**

`operationId: StowboClientController_settle`

Closes the order financially and releases the host's payout. Do this once the bill is final — reversals after settlement are messier than getting the lines right first.

#### Signature

```http
POST /client/stowbo/host/bookings/{bookingId}/settle (bookingId: string) -> The settlement
```

#### Access

Requires a bearer JWT (`Authorization: Bearer <token>`).

#### Notes

- Releases money to the host.

#### Errors

| Status | Code | Message | When | What to do |
| --- | --- | --- | --- | --- |
| `401` | HOST_AUTH_REQUIRED | Host authentication required | The caller is not signed in as a host. | Sign in with a host account. |
| `404` | BOOKING_NOT_FOUND | Booking not found | No booking has that id. | List your bookings. |
| `403` | NOT_YOUR_LISTINGS_BOOKING | That booking is not for one of your listings | The booking is at another host's place. | Check the booking id. |

Plus the standard platform errors: `429`, `500`.

#### See also

- `POST /client/stowbo/host/bookings/{bookingId}/hold`

### Parameters

| Name | In | Type | Required | Description |
| --- | --- | --- | --- | --- |
| `orgid` | header | string | yes | Organization (tenant) identifier. Every request is scoped to this org; data from other orgs is never visible. Issued with your API credentials. |
| `bookingId` | path | string | yes | Booking (order) id. |

### Responses

| Status | Meaning |
| --- | --- |
| `201` | The settlement |
| `401` | Host authentication required — The caller is not signed in as a host. |
| `403` | That booking is not for one of your listings — The booking is at another host's place. |
| `404` | Booking not found — No booking has that id. |
| `429` | Too Many Requests — More than 100,000 requests from one IP within 5 minutes (configurable per deployment). CORS preflights and requests from inside the platform cluster are not counted. The limiter answers before the error filter, so the body is `{ statusCode, error, message }` with no `path`, `method` or `timeStamp`; the `RateLimit-*` response headers say when the window resets. |
| `500` | An unexpected error occurred. Our team has been notified. — An unhandled server-side failure. |

## POST /client/stowbo/host/bookings/{bookingId}/hold

**Hold a payout**

`operationId: StowboClientController_hostHold`

Holds the payout while something is unresolved — a damage claim, a dispute. The money stays put until released.

#### Signature

```http
POST /client/stowbo/host/bookings/{bookingId}/hold (bookingId: string, body) -> The result
```

#### Access

Requires a bearer JWT (`Authorization: Bearer <token>`).

#### Errors

| Status | Code | Message | When | What to do |
| --- | --- | --- | --- | --- |
| `401` | HOST_AUTH_REQUIRED | Host authentication required | The caller is not signed in as a host. | Sign in with a host account. |
| `404` | BOOKING_NOT_FOUND | Booking not found | No booking has that id. | List your bookings. |
| `403` | NOT_YOUR_LISTINGS_BOOKING | That booking is not for one of your listings | The booking is at another host's place. | Check the booking id. |

Plus the standard platform errors: `429`, `500`.

#### See also

- `POST /client/stowbo/host/bookings/{bookingId}/release`

### Parameters

| Name | In | Type | Required | Description |
| --- | --- | --- | --- | --- |
| `orgid` | header | string | yes | Organization (tenant) identifier. Every request is scoped to this org; data from other orgs is never visible. Issued with your API credentials. |
| `bookingId` | path | string | yes | Booking (order) id. |

### Request body

Why it is held.

```json
{
  "reason": "Damage claim under review"
}
```

### Responses

| Status | Meaning |
| --- | --- |
| `201` | The result |
| `401` | Host authentication required — The caller is not signed in as a host. |
| `403` | That booking is not for one of your listings — The booking is at another host's place. |
| `404` | Booking not found — No booking has that id. |
| `429` | Too Many Requests — More than 100,000 requests from one IP within 5 minutes (configurable per deployment). CORS preflights and requests from inside the platform cluster are not counted. The limiter answers before the error filter, so the body is `{ statusCode, error, message }` with no `path`, `method` or `timeStamp`; the `RateLimit-*` response headers say when the window resets. |
| `500` | An unexpected error occurred. Our team has been notified. — An unhandled server-side failure. |

## POST /client/stowbo/host/bookings/{bookingId}/release

**Release a held payout**

`operationId: StowboClientController_hostRelease`

Lifts a hold so the payout can proceed.

#### Signature

```http
POST /client/stowbo/host/bookings/{bookingId}/release (bookingId: string) -> The result
```

#### Access

Requires a bearer JWT (`Authorization: Bearer <token>`).

#### Errors

| Status | Code | Message | When | What to do |
| --- | --- | --- | --- | --- |
| `401` | HOST_AUTH_REQUIRED | Host authentication required | The caller is not signed in as a host. | Sign in with a host account. |
| `404` | BOOKING_NOT_FOUND | Booking not found | No booking has that id. | List your bookings. |
| `403` | NOT_YOUR_LISTINGS_BOOKING | That booking is not for one of your listings | The booking is at another host's place. | Check the booking id. |

Plus the standard platform errors: `429`, `500`.

#### See also

- `POST /client/stowbo/host/bookings/{bookingId}/hold`

### Parameters

| Name | In | Type | Required | Description |
| --- | --- | --- | --- | --- |
| `orgid` | header | string | yes | Organization (tenant) identifier. Every request is scoped to this org; data from other orgs is never visible. Issued with your API credentials. |
| `bookingId` | path | string | yes | Booking (order) id. |

### Responses

| Status | Meaning |
| --- | --- |
| `201` | The result |
| `401` | Host authentication required — The caller is not signed in as a host. |
| `403` | That booking is not for one of your listings — The booking is at another host's place. |
| `404` | Booking not found — No booking has that id. |
| `429` | Too Many Requests — More than 100,000 requests from one IP within 5 minutes (configurable per deployment). CORS preflights and requests from inside the platform cluster are not counted. The limiter answers before the error filter, so the body is `{ statusCode, error, message }` with no `path`, `method` or `timeStamp`; the `RateLimit-*` response headers say when the window resets. |
| `500` | An unexpected error occurred. Our team has been notified. — An unhandled server-side failure. |

## POST /client/stowbo/host/bookings/{bookingId}/cancel

**Cancel an order**

`operationId: StowboClientController_hostCancel`

Cancels an order at the host's place. As with the guest-side cancel, this is for before anything has been handed over — once an item is checked in it must be checked out.

#### Signature

```http
POST /client/stowbo/host/bookings/{bookingId}/cancel (bookingId: string, body) -> The cancelled order
```

#### Access

Requires a bearer JWT (`Authorization: Bearer <token>`).

#### Errors

| Status | Code | Message | When | What to do |
| --- | --- | --- | --- | --- |
| `401` | HOST_AUTH_REQUIRED | Host authentication required | The caller is not signed in as a host. | Sign in with a host account. |
| `404` | BOOKING_NOT_FOUND | Booking not found | No booking has that id. | List your bookings. |
| `403` | NOT_YOUR_LISTINGS_BOOKING | That booking is not for one of your listings | The booking is at another host's place. | Check the booking id. |
| `400` | ALREADY_CHECKED_IN | This is already checked in — check it out instead of cancelling | An item has been checked in. | Check it out. |

Plus the standard platform errors: `429`, `500`.

#### See also

- `POST /client/stowbo/host/items/{itemId}/checkout`

### Parameters

| Name | In | Type | Required | Description |
| --- | --- | --- | --- | --- |
| `orgid` | header | string | yes | Organization (tenant) identifier. Every request is scoped to this org; data from other orgs is never visible. Issued with your API credentials. |
| `bookingId` | path | string | yes | Booking (order) id. |

### Request body

Optional reason.

```json
{
  "reason": "Guest never arrived"
}
```

### Responses

| Status | Meaning |
| --- | --- |
| `201` | The cancelled order |
| `400` | This is already checked in — check it out instead of cancelling — An item has been checked in. |
| `401` | Host authentication required — The caller is not signed in as a host. |
| `403` | That booking is not for one of your listings — The booking is at another host's place. |
| `404` | Booking not found — No booking has that id. |
| `429` | Too Many Requests — More than 100,000 requests from one IP within 5 minutes (configurable per deployment). CORS preflights and requests from inside the platform cluster are not counted. The limiter answers before the error filter, so the body is `{ statusCode, error, message }` with no `path`, `method` or `timeStamp`; the `RateLimit-*` response headers say when the window resets. |
| `500` | An unexpected error occurred. Our team has been notified. — An unhandled server-side failure. |

## GET /client/stowbo/host/bookings/{bookingId}

**Get an order at my place**

`operationId: StowboClientController_hostBooking`

One order at the host's listing.

#### Signature

```http
GET /client/stowbo/host/bookings/{bookingId} (bookingId: string) -> The order
```

#### Access

Requires a bearer JWT (`Authorization: Bearer <token>`).

#### Errors

| Status | Code | Message | When | What to do |
| --- | --- | --- | --- | --- |
| `401` | HOST_AUTH_REQUIRED | Host authentication required | The caller is not signed in as a host. | Sign in with a host account. |
| `404` | BOOKING_NOT_FOUND | Booking not found | No booking has that id. | List your bookings. |
| `403` | NOT_YOUR_LISTINGS_BOOKING | That booking is not for one of your listings | The booking is at another host's place. | Check the booking id. |

Plus the standard platform errors: `429`, `500`.

#### See also

- `GET /client/stowbo/host/bookings/{bookingId}/items`

### Parameters

| Name | In | Type | Required | Description |
| --- | --- | --- | --- | --- |
| `orgid` | header | string | yes | Organization (tenant) identifier. Every request is scoped to this org; data from other orgs is never visible. Issued with your API credentials. |
| `bookingId` | path | string | yes | Booking (order) id. |

### Responses

| Status | Meaning |
| --- | --- |
| `200` | The order |
| `401` | Host authentication required — The caller is not signed in as a host. |
| `403` | That booking is not for one of your listings — The booking is at another host's place. |
| `404` | Booking not found — No booking has that id. |
| `429` | Too Many Requests — More than 100,000 requests from one IP within 5 minutes (configurable per deployment). CORS preflights and requests from inside the platform cluster are not counted. The limiter answers before the error filter, so the body is `{ statusCode, error, message }` with no `path`, `method` or `timeStamp`; the `RateLimit-*` response headers say when the window resets. |
| `500` | An unexpected error occurred. Our team has been notified. — An unhandled server-side failure. |

## GET /client/stowbo/host/bookings/{bookingId}/due

**Get what a booking owes right now**

`operationId: StowboClientController_bookingDue`

The billed balance plus any not-yet-billed meter on items still present — the number a "Take payment · balance" preset uses, so an open stay shows its real accrued amount. `action` asks the same question for `checkout`, `cancel` or `no_show`.

#### Signature

```http
GET /client/stowbo/host/bookings/{bookingId}/due (bookingId: string, action?: string) -> The payment summary plus the answer for that action
```

#### Access

Requires a bearer JWT (`Authorization: Bearer <token>`).

#### Errors

| Status | Code | Message | When | What to do |
| --- | --- | --- | --- | --- |
| `401` | SIGN_IN_REQUIRED | Sign in required | No customer could be resolved from the token. | Sign in. |
| `404` | BOOKING_NOT_FOUND | Booking not found | No booking has that id. | List your bookings. |
| `403` | NOT_YOUR_LISTINGS_BOOKING | That booking is not for one of your listings | The booking is at another host's place. | Check the booking id. |

Plus the standard platform errors: `429`, `500`.

### Parameters

| Name | In | Type | Required | Description |
| --- | --- | --- | --- | --- |
| `orgid` | header | string | yes | Organization (tenant) identifier. Every request is scoped to this org; data from other orgs is never visible. Issued with your API credentials. |
| `bookingId` | path | string | yes | Booking (order) id. |
| `action` | query | "current" \| "checkout" \| "cancel" \| "no_show" | — |  |

### Responses

| Status | Meaning |
| --- | --- |
| `200` | The payment summary plus the answer for that action |
| `401` | Sign in required — No customer could be resolved from the token. |
| `403` | That booking is not for one of your listings — The booking is at another host's place. |
| `404` | Booking not found — No booking has that id. |
| `429` | Too Many Requests — More than 100,000 requests from one IP within 5 minutes (configurable per deployment). CORS preflights and requests from inside the platform cluster are not counted. The limiter answers before the error filter, so the body is `{ statusCode, error, message }` with no `path`, `method` or `timeStamp`; the `RateLimit-*` response headers say when the window resets. |
| `500` | An unexpected error occurred. Our team has been notified. — An unhandled server-side failure. |

## GET /client/stowbo/host/bookings/{bookingId}/customer

**Get an order's guest**

`operationId: StowboClientController_bookingCustomer`

The guest's contact card — name, email, phone — for a booking at the host's own listing.

#### Signature

```http
GET /client/stowbo/host/bookings/{bookingId}/customer (bookingId: string) -> The guest contact card
```

#### Access

Requires a bearer JWT (`Authorization: Bearer <token>`).

#### Notes

- Personal contact details.

#### Errors

| Status | Code | Message | When | What to do |
| --- | --- | --- | --- | --- |
| `401` | HOST_AUTH_REQUIRED | Host authentication required | The caller is not signed in as a host. | Sign in with a host account. |
| `404` | BOOKING_NOT_FOUND | Booking not found | No booking has that id. | List your bookings. |
| `403` | NOT_YOUR_LISTINGS_BOOKING | That booking is not for one of your listings | The booking is at another host's place. | Check the booking id. |

Plus the standard platform errors: `429`, `500`.

#### See also

- `GET /client/stowbo/bookings/{bookingId}/host`

### Parameters

| Name | In | Type | Required | Description |
| --- | --- | --- | --- | --- |
| `orgid` | header | string | yes | Organization (tenant) identifier. Every request is scoped to this org; data from other orgs is never visible. Issued with your API credentials. |
| `bookingId` | path | string | yes | Booking (order) id. |

### Responses

| Status | Meaning |
| --- | --- |
| `200` | The guest contact card |
| `401` | Host authentication required — The caller is not signed in as a host. |
| `403` | That booking is not for one of your listings — The booking is at another host's place. |
| `404` | Booking not found — No booking has that id. |
| `429` | Too Many Requests — More than 100,000 requests from one IP within 5 minutes (configurable per deployment). CORS preflights and requests from inside the platform cluster are not counted. The limiter answers before the error filter, so the body is `{ statusCode, error, message }` with no `path`, `method` or `timeStamp`; the `RateLimit-*` response headers say when the window resets. |
| `500` | An unexpected error occurred. Our team has been notified. — An unhandled server-side failure. |

## POST /client/stowbo/host/bookings/{bookingId}/requests/{requestId}

**Respond to a guest request**

`operationId: StowboClientController_respondRequest`

Answers a guest's request — `acknowledged`, `ready`, `done` or `declined`. The guest is notified.

#### Signature

```http
POST /client/stowbo/host/bookings/{bookingId}/requests/{requestId} (bookingId: string, requestId: string, body) -> The request
```

#### Access

Requires a bearer JWT (`Authorization: Bearer <token>`).

#### Notes

- Notifies the guest.

#### Errors

| Status | Code | Message | When | What to do |
| --- | --- | --- | --- | --- |
| `401` | HOST_AUTH_REQUIRED | Host authentication required | The caller is not signed in as a host. | Sign in with a host account. |
| `404` | BOOKING_NOT_FOUND | Booking not found | No booking has that id. | List your bookings. |
| `403` | NOT_YOUR_LISTINGS_BOOKING | That booking is not for one of your listings | The booking is at another host's place. | Check the booking id. |

Plus the standard platform errors: `429`, `500`.

#### See also

- `POST /client/stowbo/host/items/{itemId}/request`

### Parameters

| Name | In | Type | Required | Description |
| --- | --- | --- | --- | --- |
| `orgid` | header | string | yes | Organization (tenant) identifier. Every request is scoped to this org; data from other orgs is never visible. Issued with your API credentials. |
| `bookingId` | path | string | yes | Booking (order) id. |
| `requestId` | path | string | yes | Request id. |

### Request body

The response.

```json
{
  "status": "ready"
}
```

### Responses

| Status | Meaning |
| --- | --- |
| `201` | The request |
| `401` | Host authentication required — The caller is not signed in as a host. |
| `403` | That booking is not for one of your listings — The booking is at another host's place. |
| `404` | Booking not found — No booking has that id. |
| `429` | Too Many Requests — More than 100,000 requests from one IP within 5 minutes (configurable per deployment). CORS preflights and requests from inside the platform cluster are not counted. The limiter answers before the error filter, so the body is `{ statusCode, error, message }` with no `path`, `method` or `timeStamp`; the `RateLimit-*` response headers say when the window resets. |
| `500` | An unexpected error occurred. Our team has been notified. — An unhandled server-side failure. |

## GET /client/stowbo/host/bookings/{bookingId}/timeline

**Get an order's timeline**

`operationId: StowboClientController_hostTimeline`

What happened to an order, in order — the record to read when a bill is questioned.

#### Signature

```http
GET /client/stowbo/host/bookings/{bookingId}/timeline (bookingId: string) -> The timeline
```

#### Access

Requires a bearer JWT (`Authorization: Bearer <token>`).

#### Errors

| Status | Code | Message | When | What to do |
| --- | --- | --- | --- | --- |
| `401` | HOST_AUTH_REQUIRED | Host authentication required | The caller is not signed in as a host. | Sign in with a host account. |
| `404` | BOOKING_NOT_FOUND | Booking not found | No booking has that id. | List your bookings. |
| `403` | NOT_YOUR_LISTINGS_BOOKING | That booking is not for one of your listings | The booking is at another host's place. | Check the booking id. |

Plus the standard platform errors: `429`, `500`.

#### See also

- `GET /client/stowbo/bookings/{bookingId}/timeline`

### Parameters

| Name | In | Type | Required | Description |
| --- | --- | --- | --- | --- |
| `orgid` | header | string | yes | Organization (tenant) identifier. Every request is scoped to this org; data from other orgs is never visible. Issued with your API credentials. |
| `bookingId` | path | string | yes | Booking (order) id. |

### Responses

| Status | Meaning |
| --- | --- |
| `200` | The timeline |
| `401` | Host authentication required — The caller is not signed in as a host. |
| `403` | That booking is not for one of your listings — The booking is at another host's place. |
| `404` | Booking not found — No booking has that id. |
| `429` | Too Many Requests — More than 100,000 requests from one IP within 5 minutes (configurable per deployment). CORS preflights and requests from inside the platform cluster are not counted. The limiter answers before the error filter, so the body is `{ statusCode, error, message }` with no `path`, `method` or `timeStamp`; the `RateLimit-*` response headers say when the window resets. |
| `500` | An unexpected error occurred. Our team has been notified. — An unhandled server-side failure. |

## GET /client/stowbo/host/earnings

**Get my earnings**

`operationId: StowboClientController_earnings`

What the host has earned — settled and pending.

#### Signature

```http
GET /client/stowbo/host/earnings () -> Earnings
```

#### Access

Requires a bearer JWT (`Authorization: Bearer <token>`).

#### Errors

| Status | Code | Message | When | What to do |
| --- | --- | --- | --- | --- |
| `401` | HOST_AUTH_REQUIRED | Host authentication required | The caller is not signed in as a host. | Sign in with a host account. |

Plus the standard platform errors: `403`, `429`, `500`.

#### See also

- `GET /client/stowbo/host/transactions`

### Parameters

| Name | In | Type | Required | Description |
| --- | --- | --- | --- | --- |
| `orgid` | header | string | yes | Organization (tenant) identifier. Every request is scoped to this org; data from other orgs is never visible. Issued with your API credentials. |

### Responses

| Status | Meaning |
| --- | --- |
| `200` | Earnings |
| `401` | Host authentication required — The caller is not signed in as a host. |
| `403` | You do not have permission to perform this action — The caller is authenticated but lacks the role required by the endpoint, or is acting on another org. |
| `429` | Too Many Requests — More than 100,000 requests from one IP within 5 minutes (configurable per deployment). CORS preflights and requests from inside the platform cluster are not counted. The limiter answers before the error filter, so the body is `{ statusCode, error, message }` with no `path`, `method` or `timeStamp`; the `RateLimit-*` response headers say when the window resets. |
| `500` | An unexpected error occurred. Our team has been notified. — An unhandled server-side failure. |

