# Stowbo · Custody

Part of AppEngine API Documentation. Full index: https://appengine.appmint.io/documentation.md
## GET /stowbo/custody

**List what is in custody right now**

`operationId: StowboController_custody`

Every booking **item** in an open custody session (checked in, not checked out) — one entry per thing, not per booking. Overdue items come first, then those due to leave today, then the rest, each group ordered by end date. Cancelled and ended items are excluded.

#### Signature

```http
GET /stowbo/custody (listing?: string) -> Items in custody
```

#### Access

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

#### Notes

- Reads at most 5,000 booking items.

#### Errors

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

#### See also

- `GET /stowbo/overdue`
- `GET /stowbo/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. |
| `listing` | query | string | — | Restrict to one listing (exact name; child listings are not included). |

### Responses

| Status | Meaning |
| --- | --- |
| `200` | Items in custody |
| `401` | Authentication failed: Invalid or expired token — The `Authorization` header is missing, malformed, or the JWT has expired. |
| `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 /stowbo/overdue

**List what is past its window and still here**

`operationId: StowboController_overdue`

Every booking item in custody whose end date has passed — the work queue for chasing guests and the basis for overstay charges. Derived, never stored: an item leaves this list the moment it is checked out or its stay is extended. Open (metered) stays have no end and never appear here.

#### Signature

```http
GET /stowbo/overdue () -> Overdue items, longest overdue first
```

#### Access

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

#### Notes

- Takes no `listing` filter — it always spans the whole org.

#### Errors

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

#### See also

- `GET /stowbo/custody`
- `POST /stowbo/booking/{bookingId}/extend`

### 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` | Overdue items, longest overdue first |
| `401` | Authentication failed: Invalid or expired token — The `Authorization` header is missing, malformed, or the JWT has expired. |
| `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 /stowbo/listing/{listing}/occupancy-now

**See what is in a space right now**

`operationId: StowboController_occupancyNow`

The items physically present in a listing now (active or disputed booking items whose last movement was in), with who they belong to and whether they are overstaying.

#### Signature

```http
GET /stowbo/listing/{listing}/occupancy-now (listing: string) -> What is here
```

#### Access

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

#### Notes

- The listing name is not checked — an unknown listing returns nothing occupied, not a 404.

#### Errors

Plus the standard platform errors: `401`, `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. |
| `listing` | path | string | yes | Listing `name`. A site aggregates its child listings; a leaf listing stands alone. |

### Responses

| Status | Meaning |
| --- | --- |
| `200` | What is here |
| `401` | Authentication failed: Invalid or expired token — The `Authorization` header is missing, malformed, or the JWT has expired. |
| `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 /stowbo/items/{itemId}/checkin

**Check an item in**

`operationId: StowboController_itemCheckIn`

Takes custody of a booking item on the host's behalf and optionally assigns its unit or identifier.

#### Signature

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

#### Access

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

#### Errors

| Status | Code | Message | When | What to do |
| --- | --- | --- | --- | --- |
| `404` | ITEM_NOT_FOUND | Booking item <id> not found | No booking item has that id. | Find it with `GET /stowbo/items`. |
| `409` | SESSION_CLOSED | That session is already closed | The item was already checked out. | — |

Plus the standard platform errors: `401`, `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. |
| `itemId` | path | string | yes | `stowbo_booking_item` sk — one thing booked, not the whole order. |

### Request body

### Responses

| Status | Meaning |
| --- | --- |
| `201` | The booking item |
| `401` | Authentication failed: Invalid or expired token — The `Authorization` header is missing, malformed, or the JWT has expired. |
| `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 <id> not found — No booking item has that id. |
| `409` | That session is already 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. |

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

**Get what an item owes before check-out**

`operationId: StowboController_itemCheckoutStatement`

The check-out statement for one item: time used, any overstay, and the rate lines — without closing anything. `canCheckOut` is false while the item is still present.

#### Signature

```http
GET /stowbo/items/{itemId}/checkout (itemId: string) -> The statement
```

#### Access

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

#### Errors

| Status | Code | Message | When | What to do |
| --- | --- | --- | --- | --- |
| `404` | ITEM_NOT_FOUND | Booking item <id> not found | No booking item has that id. | Find it with `GET /stowbo/items`. |

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

#### See also

- `POST /stowbo/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 | `stowbo_booking_item` sk — one thing booked, not the whole order. |

### Responses

| Status | Meaning |
| --- | --- |
| `200` | The statement |
| `401` | Authentication failed: Invalid or expired token — The `Authorization` header is missing, malformed, or the JWT has expired. |
| `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 <id> 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 /stowbo/items/{itemId}/checkout

**Check an item out**

`operationId: StowboController_itemCheckOut`

Closes the item's custody session — the only place an item stops occupying capacity. What it cost is added to the order; the order completes when every item has checked out. Refused while the item is still present: record the move-out first.

#### Signature

```http
POST /stowbo/items/{itemId}/checkout (itemId: string, body) -> The item, its statement, and `orderComplete`
```

#### Access

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

#### Errors

| Status | Code | Message | When | What to do |
| --- | --- | --- | --- | --- |
| `404` | ITEM_NOT_FOUND | Booking item <id> not found | No booking item has that id. | Find it with `GET /stowbo/items`. |
| `409` | ALREADY_CHECKED_OUT | Already checked out | The session is already closed. | — |

Plus the standard platform errors: `401`, `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. |
| `itemId` | path | string | yes | `stowbo_booking_item` sk — one thing booked, not the whole order. |

### Request body

### Responses

| Status | Meaning |
| --- | --- |
| `201` | The item, its statement, and `orderComplete` |
| `401` | Authentication failed: Invalid or expired token — The `Authorization` header is missing, malformed, or the JWT has expired. |
| `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 <id> not found — No booking item has that id. |
| `409` | Already checked out — The session is already closed. |
| `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 /stowbo/items/{itemId}/movement

**Record an item going in or out**

`operationId: StowboController_itemMovement`

Records one movement within the custody session. A move-out is not a check-out: the space stays held. A movement that matches an open guest request completes it.

#### Signature

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

#### Access

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

#### Errors

| Status | Code | Message | When | What to do |
| --- | --- | --- | --- | --- |
| `404` | ITEM_NOT_FOUND | Booking item <id> not found | No booking item has that id. | Find it with `GET /stowbo/items`. |
| `400` | INVALID_DIRECTION | direction must be 'in' or 'out' | Missing or other value. | — |
| `409` | SESSION_CLOSED | That session is closed | The item was checked out. | — |

Plus the standard platform errors: `401`, `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. |
| `itemId` | path | string | yes | `stowbo_booking_item` sk — one thing booked, not the whole order. |

### Request body

```json
{
  "direction": "out",
  "note": "Guest collecting overnight bag"
}
```

### Responses

| Status | Meaning |
| --- | --- |
| `201` | The booking item |
| `400` | direction must be 'in' or 'out' — Missing or other value. |
| `401` | Authentication failed: Invalid or expired token — The `Authorization` header is missing, malformed, or the JWT has expired. |
| `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 <id> not found — No booking item has that id. |
| `409` | That session is closed — The item was 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 /stowbo/items/{itemId}/assign

**Assign an item to a unit**

`operationId: StowboController_itemAssign`

Puts the item in a unit of its listing, or moves it to a different one. The customer is told the new spot.

#### Signature

```http
POST /stowbo/items/{itemId}/assign (itemId: string, body) -> The booking item
```

#### Access

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

#### Errors

| Status | Code | Message | When | What to do |
| --- | --- | --- | --- | --- |
| `404` | ITEM_NOT_FOUND | Booking item <id> not found | No booking item has that id. | Find it with `GET /stowbo/items`. |
| `400` | UNIT_REQUIRED | unit is required | No unit. | — |

Plus the standard platform errors: `401`, `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. |
| `itemId` | path | string | yes | `stowbo_booking_item` sk — one thing booked, not the whole order. |

### Request body

### Responses

| Status | Meaning |
| --- | --- |
| `201` | The booking item |
| `400` | unit is required — No unit. |
| `401` | Authentication failed: Invalid or expired token — The `Authorization` header is missing, malformed, or the JWT has expired. |
| `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 <id> 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. |

