REST API Reference
The public API lives below:
https://api.requiply.com/api/public/v1
Every request authenticates with Authorization: Bearer <api-key>; see Authentication and API Keys. Request and response bodies are JSON. The TypeScript SDK wraps every endpoint below, and its resource guides describe the fields in detail.
Endpoints
Publishable endpoints accept both key types. Secret endpoints refuse a publishable key with 403.
Organization and catalog
| Method and path | Keys | SDK method |
|---|---|---|
GET /org/info | Publishable | org.info() |
GET /org/summary | Secret | org.summary() |
GET /categories/list | Publishable | categories.list() |
GET /services/list | Publishable | services.list() |
GET /inventory/list | Publishable | inventory.list() |
GET /inventory/groups/{id} | Publishable | inventory.getGroup() |
GET /inventory/status | Secret | inventory.status() |
GET /bundles/list | Publishable | bundles.list() |
GET /bundles/{id} | Publishable | bundles.get() |
Bundles are fixed sets of products with one discount. Both bundle endpoints take optional startDate and endDate query parameters; with both, each bundle reports availableQuantity, the whole sets free in that period. They list only complete, active bundles. A secret key sees bundles whenever the Bundles feature is on; a publishable key only while External recommendations are on as well. Otherwise the list is empty and bundles/{id} answers 404. GET /inventory/groups/{id} also returns the bundles that contain the group.
Availability, pricing, and bookings
| Method and path | Keys | SDK method |
|---|---|---|
POST /availability/calendar | Publishable | availability.calendar() |
POST /availability/items | Publishable | availability.items() |
POST /pricing/quote | Publishable | pricing.quote() |
POST /bookings/create | Publishable, booking requests only | bookings.create() |
GET /bookings/list | Secret | bookings.list() |
GET /bookings/{id} | Secret | bookings.get() |
POST /bookings/{id}/notes | Secret | bookings.addNote() |
A publishable key must send "asRequest": true to POST /bookings/create; anything else gets 403 with data.reason: "request_only".
POST /pricing/quote and POST /bookings/create accept bundles: [{ bundleId, quantity }] next to items; items may then be empty. Quotes return bundleDiscountAmount (already inside total) and lineBundles, one entry per bundle priced for the period. Sending bundles while the Bundles feature is off answers 403.
Clients
| Method and path | Keys | SDK method |
|---|---|---|
POST /clients/lookup | Secret | clients.lookup() |
POST /clients/create | Secret | clients.create() |
Goods for sale and sales
| Method and path | Keys | SDK method |
|---|---|---|
GET /sale-items/list | Secret; publishable while the organization sells to customers | saleItems.list() |
GET /sale-items/{id} | Secret; publishable while the organization sells to customers | saleItems.get() |
GET /sales/list | Secret | sales.list() |
GET /sales/{id} | Secret | sales.get() |
POST /sales/create | Secret | sales.create() |
These endpoints answer 403 with data.reason: "feature_disabled" while Enable sales is off under Features or the organization is not on the Advanced plan. What a publishable key sees, and when it gets selling_disabled instead, is described in Sales and Goods for Sale.
Reports
All reports need a secret key and take their parameters as query strings.
| Method and path | SDK method |
|---|---|
GET /reports/revenue | reports.revenue() |
GET /reports/bookings-summary | reports.bookingsSummary() |
GET /reports/utilization | reports.utilization() |
GET /reports/top-items | reports.topItems() |
GET /reports/top-clients | reports.topClients() |
GET /reports/outstanding | reports.outstanding() |
GET /reports/overdue | reports.overdue() |
GET /reports/pipeline | reports.pipeline() |
Conventions
| Topic | Rule |
|---|---|
| Parameters | GET endpoints take query-string parameters. POST endpoints take a JSON body. |
| Pagination | List endpoints return nextCursor. Pass it back as cursor for the next page; null means there are no more pages. limit is 1 to 100 (default 25) on catalog, availability, and sales lists, 1 to 200 (default 50) on bookings/list, and 1 to 500 (default 100) on inventory/status. |
| Dates and times | ISO 8601. On quotes, booking creation, and availability/items, a date-time without an offset (2026-07-01T10:00:00) is read in the organization's timezone, daylight saving included. A value with Z or an offset is used as given. A date with no time is midnight. |
| IDs | Products, categories, services, goods for sale, and sales use UUIDs. Bookings and clients use numbers. Bookings and sales also have the number staff see in the app: pass it with ?idKind=org. |
| Money | Amounts are in the organization's major currency unit (for example 1250.5), with the currency code next to them. |
| Subrentals | Products sourced from suppliers are never returned to or accepted from a publishable key. A secret key sees them when Subrentals is on. |
Errors
A failed request answers with an HTTP error status and a JSON body:
{
"statusCode": 409,
"message": "Only 2 × Memory card 128 GB left",
"data": { "reason": "out_of_stock", "saleItemId": "3f6c…", "availableQuantity": 2 }
}
message is meant for people. When the API gives a machine-readable reason, it is in data.reason, sometimes with more fields in data. Branch on data.reason, never on the message text. The reasons are listed in Error Handling.
| Status | Typical cause |
|---|---|
400 | A missing or malformed field, such as an invalid date or an empty items list. |
401 | The Authorization header is missing, or the key is unknown or revoked. |
403 | The key type cannot use the endpoint, or a feature or permission is off. |
404 | The booking, product, client, or sale does not exist in this organization. |
409 | The request conflicts with the current state, for example a product is archived or out of stock. |
429 | The key went over its rate limit. Wait the number of seconds in Retry-After. |
A booking the organization cannot accept, for example because the items are taken or the pickup is outside working hours, is not an error: POST /bookings/create answers 200 with success: false. See Bookings.
Recording a sale over REST
POST /sales/create takes:
{
"lines": [{ "saleItemId": "3f6c…", "quantity": 2 }],
"clientId": 23,
"paymentMethod": "payOnPickup",
"soldAt": "2026-09-29T14:00:00Z",
"note": "Counter sale"
}
It answers 201 with the sale, stockWarnings (products whose stock goes below zero; the sale is still recorded), and the payment with its link for an online method. The field rules are in sales.create().