SIGNALS Documentation
API Reference

Availability

Read-only availability queries for the rental availability engine.

Availability API

Read-only availability queries for the rental availability engine. Availability is the quantity of a catalogue item that is free to book at a warehouse over time: available = total_stock - total_demanded, and may be negative when demand exceeds stock (a shortage).

The endpoint serves a two-tier read strategy:

  • A point query (single date) is computed on-the-fly from active demands — always live, no snapshot dependency.
  • A range query (from + to) is read from pre-calculated availability snapshots, with a calculated_at freshness marker so consumers know how current the data is.

Endpoints

Method URL Description
GET /api/v1/availability Availability for a catalogue item at a warehouse
GET /api/v1/availability/calendar Multi-catalogue-item daily availability grid for a warehouse
GET /api/v1/availability/{catalogue_item}/gantt Demand-bar Gantt for a single catalogue item at a warehouse
GET /api/v1/availability/shortages Warehouse-wide shortage sweep over a date range
GET /api/v1/catalogue_items/{catalogue_item}/availability Availability for a specific catalogue item
GET /api/v1/catalogue_items/{catalogue_item}/available-assets Barcoded assets of a catalogue item free across a window

Authentication

Requires a Sanctum bearer token with the availability:read ability, and the availability.view permission.

Query Parameters

Parameter Required Description
catalogue_item_id Yes (flat endpoint only) The catalogue item to query. Supplied by the route on the nested endpoint.
warehouse_id Yes The warehouse to query.
date One of date or from+to ISO date/time for a point query.
from With to Range start (ISO) for a range query.
to With from Range end (ISO) for a range query.

date cannot be combined with from/to. Dates are aligned to the configured availability resolution slot (daily, half-daily, or hourly) in the warehouse's local timezone.

Point Query

GET /api/v1/availability?catalogue_item_id=5&warehouse_id=1&date=2026-07-02

Response

{
    "availability": {
        "catalogue_item_id": 5,
        "warehouse_id": 1,
        "date": "2026-07-02T00:00:00.000Z",
        "total_stock": 10,
        "total_demanded": 4,
        "available": 6,
        "demand_breakdown": {
            "rental_item": 4
        }
    }
}

demand_breakdown reports the demanded quantity per source type (e.g. rental_item, repair).

Range Query

GET /api/v1/availability?catalogue_item_id=5&warehouse_id=1&from=2026-07-01&to=2026-07-04

Response

{
    "availability": {
        "catalogue_item_id": 5,
        "warehouse_id": 1,
        "from": "2026-07-01T00:00:00.000Z",
        "to": "2026-07-04T00:00:00.000Z",
        "min_available": 6,
        "max_available": 10,
        "calculated_at": "2026-06-18T09:30:00.000Z",
        "slots": [
            {
                "slot_start": "2026-07-01T00:00:00.000Z",
                "total_stock": 10,
                "total_demanded": 4,
                "available": 6,
                "demand_breakdown": { "rental_item": 4 }
            }
        ]
    }
}

slots contains one entry per resolution-aligned time slot in the range. min_available / max_available summarise the range; calculated_at is the oldest snapshot recalculation time in the range (null when no snapshots exist yet for the range).

Available Assets (barcoded catalogue items)

For catalogue items tracked as barcoded (one physical unit per asset), list the specific assets that are free for an entire window — i.e. no active demand claims that asset over a period overlapping [from, to). A loose catalogue item has no discrete assets and returns an empty collection; use the point/range endpoints above for quantity-based reads.

GET /api/v1/catalogue_items/5/available-assets?warehouse_id=1&from=2026-07-02&to=2026-07-04

Query Parameters

Parameter Required Description
warehouse_id Yes The warehouse to query.
from Yes Window start (ISO).
to Yes Window end (ISO), on or after from.

Response

{
    "available_assets": [
        {
            "id": 42,
            "item_name": "Shure SM58",
            "asset_number": "A-0042",
            "serial_number": "SN-000042",
            "barcode": null,
            "location": "Bay 3"
        }
    ],
    "meta": { "total": 1, "per_page": 1, "page": 1 }
}

The overlap is evaluated against the demand period: on PostgreSQL via the native tstzrange && operator (backed by the idx_demands_asset_period GiST index and the excl_demands_asset_period exclusion constraint), and via a scalar comparison on the SQLite test connection.

Calendar Grid

GET /api/v1/availability/calendar?warehouse_id=1&from=2026-07-01&to=2026-07-14

Returns the pre-calculated daily availability summary for all (or a filtered subset of) catalogue items at a warehouse over a date range. Each catalogue item row contains one entry per day with the available quantity, a shortage flag, and the pending check-in count. This drives the Equipment Availability calendar view.

Note: Kit and composed catalogue items whose availability is derived at read time (rather than from a demand snapshot) do not appear in the calendar grid. Use the point/range endpoints for those.

Query Parameters

Parameter Required Description
warehouse_id Yes The warehouse to query.
from Yes Start date (ISO).
to Yes End date (ISO, on or after from).
catalogue_item_ids[] No Array of catalogue item ids to narrow the result (omit for all catalogue items).

Response

{
    "calendar": {
        "warehouse_id": 1,
        "from": "2026-07-01T00:00:00+00:00",
        "to": "2026-07-14T00:00:00+00:00",
        "catalogue_items": [
            {
                "catalogue_item_id": 5,
                "catalogue_item_name": "MegaPointe Moving Head",
                "days": [
                    {
                        "date": "2026-07-01",
                        "available": 6,
                        "has_shortage": false,
                        "pending_checkin": 0
                    },
                    {
                        "date": "2026-07-02",
                        "available": -2,
                        "has_shortage": true,
                        "pending_checkin": 3
                    }
                ]
            }
        ]
    }
}

Gantt (demand bars for one catalogue item)

GET /api/v1/availability/{catalogue_item}/gantt?warehouse_id=1&from=2026-07-01&to=2026-07-14

Returns the individual demand bars for a single catalogue item at a warehouse, decomposed into their prep / on-hire / turnaround zones. Shortage windows are surfaced as a separate shortages array. This drives the per-catalogue-item Gantt timeline view.

Query Parameters

Parameter Required Description
warehouse_id Yes The warehouse to query.
from Yes Start date (ISO).
to Yes End date (ISO, on or after from).
asset_ids[] No Array of barcoded asset ids to narrow the result (omit for all assets).

Response

{
    "gantt": {
        "catalogue_item_id": 5,
        "warehouse_id": 1,
        "from": "2026-07-01T00:00:00+00:00",
        "to": "2026-07-14T00:00:00+00:00",
        "total_stock": 10,
        "demands": [
            {
                "demand_id": 42,
                "asset_id": 7,
                "asset_serial": "SN-0007",
                "quantity": 1,
                "source_type": "rental_item",
                "source_id": 1001,
                "source_name": "Corporate Conference 2026",
                "colour": null,
                "phase": "reserved",
                "period_start": "2026-07-01T08:00:00Z",
                "buffer_before_end": "2026-07-01T09:00:00Z",
                "buffer_after_start": "2026-07-05T18:00:00Z",
                "period_end": "2026-07-06T09:00:00Z",
                "starts_at": "2026-07-01T09:00:00Z",
                "ends_at": "2026-07-05T18:00:00Z"
            }
        ],
        "shortages": [
            {
                "from": "2026-07-02T00:00:00Z",
                "to": "2026-07-04T00:00:00Z",
                "severity": 2,
                "in_buffer_zone": false
            }
        ]
    }
}

Each demand has:

Field Type Description
demand_id integer Demand record id
asset_id integer|null Barcoded asset id (null for bulk-quantity demands)
asset_serial string|null Serial number of the asset
quantity integer Quantity demanded
source_type string Demand source type (e.g. rental_item)
source_id integer Source record id
source_name string|null Display name of the source (rental title)
colour string|null Optional display colour hint
phase string Current demand phase (e.g. reserved, on_hire)
period_start string Earliest boundary including prep buffer
buffer_before_end string End of the prep/turnaround-before zone
buffer_after_start string Start of the post-return turnaround zone
period_end string Latest boundary including post-return buffer
starts_at string Hire start (the on-hire window start)
ends_at string Hire end (the on-hire window end)

Warehouse-Wide Shortages

GET /api/v1/availability/shortages?warehouse_id=1&from=2026-07-01&to=2026-07-14

Returns the pre-calculated shortage windows from the daily-summary read model — any day/catalogue-item/warehouse combination where available < 0. This drives the calendar shortage panel and dashboard shortage widget. Omit warehouse_id to sweep all warehouses.

Query Parameters

Parameter Required Description
from Yes Start date (ISO).
to Yes End date (ISO, on or after from).
warehouse_id No Narrow to a single warehouse. Omit to sweep all warehouses.

Response

{
    "shortages": [
        {
            "catalogue_item_id": 5,
            "catalogue_item_name": "MegaPointe Moving Head",
            "warehouse_id": 1,
            "date": "2026-07-02",
            "available": -2,
            "severity": 2,
            "calculated_at": "2026-06-18T09:30:00Z"
        }
    ],
    "meta": { "total": 1, "per_page": 50, "page": 1 }
}

severity is the absolute shortfall at its worst point on that day. calculated_at is the snapshot recalculation timestamp for that slot.

Error Cases

Status Condition
401 No valid Sanctum token
403 Token lacks availability:read, or user lacks availability.view
422 Missing warehouse_id/catalogue_item_id, no date or from+to, or date combined with from/to
422 Available-assets: missing warehouse_id, from, or to
422 Calendar/Gantt/Shortages: missing warehouse_id (where required), from, or to