---
title: "REST API Reference"
description: "Every endpoint of the Requiply public REST API v1 with its HTTP method, the key types it accepts, and the SDK method that wraps it, plus request conventions, pagination, dates, and errors."
canonical_url: "https://requiply.com/docs/en/developers/api-reference"
---
# REST API Reference

> Every endpoint of the Requiply public REST API v1 with its HTTP method, the key types it accepts, and the SDK method that wraps it, plus request conventions, pagination, dates, and errors.

The public API lives below:

```text
https://api.requiply.com/api/public/v1
```

Every request authenticates with `Authorization: Bearer <api-key>`; see [Authentication and API Keys](https://requiply.com/docs/en/developers/authentication-and-api-keys). Request and response bodies are JSON. The [TypeScript SDK](https://requiply.com/docs/en/developers/typescript-sdk) wraps every endpoint below, and its resource guides describe the fields in detail.

<note>

No OpenAPI document is published yet. The SDK's TypeScript types are the most precise description of each request and response.

</note>

## Endpoints

**Publishable** endpoints accept both key types. **Secret** endpoints refuse a publishable key with `403`.

### Organization and catalog

<table>
<thead>
  <tr>
    <th>
      Method and path
    </th>
    
    <th>
      Keys
    </th>
    
    <th>
      SDK method
    </th>
  </tr>
</thead>

<tbody>
  <tr>
    <td>
      <code>
        GET /org/info
      </code>
    </td>
    
    <td>
      Publishable
    </td>
    
    <td>
      <a href="https://requiply.com/docs/en/developers/typescript-sdk/organization#orginfo">
        <code>
          org.info()
        </code>
      </a>
    </td>
  </tr>
  
  <tr>
    <td>
      <code>
        GET /org/summary
      </code>
    </td>
    
    <td>
      Secret
    </td>
    
    <td>
      <a href="https://requiply.com/docs/en/developers/typescript-sdk/organization#orgsummary">
        <code>
          org.summary()
        </code>
      </a>
    </td>
  </tr>
  
  <tr>
    <td>
      <code>
        GET /categories/list
      </code>
    </td>
    
    <td>
      Publishable
    </td>
    
    <td>
      <a href="https://requiply.com/docs/en/developers/typescript-sdk/inventory-and-categories#categorieslist">
        <code>
          categories.list()
        </code>
      </a>
    </td>
  </tr>
  
  <tr>
    <td>
      <code>
        GET /services/list
      </code>
    </td>
    
    <td>
      Publishable
    </td>
    
    <td>
      <a href="https://requiply.com/docs/en/developers/typescript-sdk/inventory-and-categories#serviceslist">
        <code>
          services.list()
        </code>
      </a>
    </td>
  </tr>
  
  <tr>
    <td>
      <code>
        GET /inventory/list
      </code>
    </td>
    
    <td>
      Publishable
    </td>
    
    <td>
      <a href="https://requiply.com/docs/en/developers/typescript-sdk/inventory-and-categories#inventorylist">
        <code>
          inventory.list()
        </code>
      </a>
    </td>
  </tr>
  
  <tr>
    <td>
      <code>
        GET /inventory/groups/{id}
      </code>
    </td>
    
    <td>
      Publishable
    </td>
    
    <td>
      <a href="https://requiply.com/docs/en/developers/typescript-sdk/inventory-and-categories#inventorygetgroup">
        <code>
          inventory.getGroup()
        </code>
      </a>
    </td>
  </tr>
  
  <tr>
    <td>
      <code>
        GET /inventory/status
      </code>
    </td>
    
    <td>
      Secret
    </td>
    
    <td>
      <a href="https://requiply.com/docs/en/developers/typescript-sdk/inventory-and-categories#inventorystatus">
        <code>
          inventory.status()
        </code>
      </a>
    </td>
  </tr>
  
  <tr>
    <td>
      <code>
        GET /bundles/list
      </code>
    </td>
    
    <td>
      Publishable
    </td>
    
    <td>
      <a href="https://requiply.com/docs/en/developers/typescript-sdk/inventory-and-categories#bundleslist">
        <code>
          bundles.list()
        </code>
      </a>
    </td>
  </tr>
  
  <tr>
    <td>
      <code>
        GET /bundles/{id}
      </code>
    </td>
    
    <td>
      Publishable
    </td>
    
    <td>
      <a href="https://requiply.com/docs/en/developers/typescript-sdk/inventory-and-categories#bundlesget">
        <code>
          bundles.get()
        </code>
      </a>
    </td>
  </tr>
</tbody>
</table>

[Bundles](https://requiply.com/docs/en/guides/inventory/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

<table>
<thead>
  <tr>
    <th>
      Method and path
    </th>
    
    <th>
      Keys
    </th>
    
    <th>
      SDK method
    </th>
  </tr>
</thead>

<tbody>
  <tr>
    <td>
      <code>
        POST /availability/calendar
      </code>
    </td>
    
    <td>
      Publishable
    </td>
    
    <td>
      <a href="https://requiply.com/docs/en/developers/typescript-sdk/availability-and-pricing#availabilitycalendar">
        <code>
          availability.calendar()
        </code>
      </a>
    </td>
  </tr>
  
  <tr>
    <td>
      <code>
        POST /availability/items
      </code>
    </td>
    
    <td>
      Publishable
    </td>
    
    <td>
      <a href="https://requiply.com/docs/en/developers/typescript-sdk/availability-and-pricing#availabilityitems">
        <code>
          availability.items()
        </code>
      </a>
    </td>
  </tr>
  
  <tr>
    <td>
      <code>
        POST /pricing/quote
      </code>
    </td>
    
    <td>
      Publishable
    </td>
    
    <td>
      <a href="https://requiply.com/docs/en/developers/typescript-sdk/availability-and-pricing#pricingquote">
        <code>
          pricing.quote()
        </code>
      </a>
    </td>
  </tr>
  
  <tr>
    <td>
      <code>
        POST /bookings/create
      </code>
    </td>
    
    <td>
      Publishable, booking requests only
    </td>
    
    <td>
      <a href="https://requiply.com/docs/en/developers/typescript-sdk/bookings#bookingscreate">
        <code>
          bookings.create()
        </code>
      </a>
    </td>
  </tr>
  
  <tr>
    <td>
      <code>
        GET /bookings/list
      </code>
    </td>
    
    <td>
      Secret
    </td>
    
    <td>
      <a href="https://requiply.com/docs/en/developers/typescript-sdk/bookings#bookingslist">
        <code>
          bookings.list()
        </code>
      </a>
    </td>
  </tr>
  
  <tr>
    <td>
      <code>
        GET /bookings/{id}
      </code>
    </td>
    
    <td>
      Secret
    </td>
    
    <td>
      <a href="https://requiply.com/docs/en/developers/typescript-sdk/bookings#bookingsget">
        <code>
          bookings.get()
        </code>
      </a>
    </td>
  </tr>
  
  <tr>
    <td>
      <code>
        POST /bookings/{id}/notes
      </code>
    </td>
    
    <td>
      Secret
    </td>
    
    <td>
      <a href="https://requiply.com/docs/en/developers/typescript-sdk/bookings#bookingsaddnote">
        <code>
          bookings.addNote()
        </code>
      </a>
    </td>
  </tr>
</tbody>
</table>

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

<table>
<thead>
  <tr>
    <th>
      Method and path
    </th>
    
    <th>
      Keys
    </th>
    
    <th>
      SDK method
    </th>
  </tr>
</thead>

<tbody>
  <tr>
    <td>
      <code>
        POST /clients/lookup
      </code>
    </td>
    
    <td>
      Secret
    </td>
    
    <td>
      <a href="https://requiply.com/docs/en/developers/typescript-sdk/clients#clientslookup">
        <code>
          clients.lookup()
        </code>
      </a>
    </td>
  </tr>
  
  <tr>
    <td>
      <code>
        POST /clients/create
      </code>
    </td>
    
    <td>
      Secret
    </td>
    
    <td>
      <a href="https://requiply.com/docs/en/developers/typescript-sdk/clients#clientscreate">
        <code>
          clients.create()
        </code>
      </a>
    </td>
  </tr>
</tbody>
</table>

### Goods for sale and sales

<table>
<thead>
  <tr>
    <th>
      Method and path
    </th>
    
    <th>
      Keys
    </th>
    
    <th>
      SDK method
    </th>
  </tr>
</thead>

<tbody>
  <tr>
    <td>
      <code>
        GET /sale-items/list
      </code>
    </td>
    
    <td>
      Secret; publishable while the organization sells to customers
    </td>
    
    <td>
      <a href="https://requiply.com/docs/en/developers/typescript-sdk/sales#saleitemslist">
        <code>
          saleItems.list()
        </code>
      </a>
    </td>
  </tr>
  
  <tr>
    <td>
      <code>
        GET /sale-items/{id}
      </code>
    </td>
    
    <td>
      Secret; publishable while the organization sells to customers
    </td>
    
    <td>
      <a href="https://requiply.com/docs/en/developers/typescript-sdk/sales#saleitemsget">
        <code>
          saleItems.get()
        </code>
      </a>
    </td>
  </tr>
  
  <tr>
    <td>
      <code>
        GET /sales/list
      </code>
    </td>
    
    <td>
      Secret
    </td>
    
    <td>
      <a href="https://requiply.com/docs/en/developers/typescript-sdk/sales#saleslist">
        <code>
          sales.list()
        </code>
      </a>
    </td>
  </tr>
  
  <tr>
    <td>
      <code>
        GET /sales/{id}
      </code>
    </td>
    
    <td>
      Secret
    </td>
    
    <td>
      <a href="https://requiply.com/docs/en/developers/typescript-sdk/sales#salesget">
        <code>
          sales.get()
        </code>
      </a>
    </td>
  </tr>
  
  <tr>
    <td>
      <code>
        POST /sales/create
      </code>
    </td>
    
    <td>
      Secret
    </td>
    
    <td>
      <a href="https://requiply.com/docs/en/developers/typescript-sdk/sales#salescreate">
        <code>
          sales.create()
        </code>
      </a>
    </td>
  </tr>
</tbody>
</table>

These endpoints answer `403` with `data.reason: "feature_disabled"` while **Enable sales** is off under [Features](https://requiply.com/docs/en/guides/settings/organization/features#enable-sales) 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](https://requiply.com/docs/en/developers/typescript-sdk/sales#with-a-publishable-key).

### Reports

All reports need a **secret key** and take their parameters as query strings.

<table>
<thead>
  <tr>
    <th>
      Method and path
    </th>
    
    <th>
      SDK method
    </th>
  </tr>
</thead>

<tbody>
  <tr>
    <td>
      <code>
        GET /reports/revenue
      </code>
    </td>
    
    <td>
      <a href="https://requiply.com/docs/en/developers/typescript-sdk/reports#reportsrevenue">
        <code>
          reports.revenue()
        </code>
      </a>
    </td>
  </tr>
  
  <tr>
    <td>
      <code>
        GET /reports/bookings-summary
      </code>
    </td>
    
    <td>
      <a href="https://requiply.com/docs/en/developers/typescript-sdk/reports#reportsbookingssummary">
        <code>
          reports.bookingsSummary()
        </code>
      </a>
    </td>
  </tr>
  
  <tr>
    <td>
      <code>
        GET /reports/utilization
      </code>
    </td>
    
    <td>
      <a href="https://requiply.com/docs/en/developers/typescript-sdk/reports#reportsutilization">
        <code>
          reports.utilization()
        </code>
      </a>
    </td>
  </tr>
  
  <tr>
    <td>
      <code>
        GET /reports/top-items
      </code>
    </td>
    
    <td>
      <a href="https://requiply.com/docs/en/developers/typescript-sdk/reports#reportstopitems">
        <code>
          reports.topItems()
        </code>
      </a>
    </td>
  </tr>
  
  <tr>
    <td>
      <code>
        GET /reports/top-clients
      </code>
    </td>
    
    <td>
      <a href="https://requiply.com/docs/en/developers/typescript-sdk/reports#reportstopclients">
        <code>
          reports.topClients()
        </code>
      </a>
    </td>
  </tr>
  
  <tr>
    <td>
      <code>
        GET /reports/outstanding
      </code>
    </td>
    
    <td>
      <a href="https://requiply.com/docs/en/developers/typescript-sdk/reports#reportsoutstanding">
        <code>
          reports.outstanding()
        </code>
      </a>
    </td>
  </tr>
  
  <tr>
    <td>
      <code>
        GET /reports/overdue
      </code>
    </td>
    
    <td>
      <a href="https://requiply.com/docs/en/developers/typescript-sdk/reports#reportsoverdue">
        <code>
          reports.overdue()
        </code>
      </a>
    </td>
  </tr>
  
  <tr>
    <td>
      <code>
        GET /reports/pipeline
      </code>
    </td>
    
    <td>
      <a href="https://requiply.com/docs/en/developers/typescript-sdk/reports#reportspipeline">
        <code>
          reports.pipeline()
        </code>
      </a>
    </td>
  </tr>
</tbody>
</table>

## Conventions

<table>
<thead>
  <tr>
    <th>
      Topic
    </th>
    
    <th>
      Rule
    </th>
  </tr>
</thead>

<tbody>
  <tr>
    <td>
      <strong>
        Parameters
      </strong>
    </td>
    
    <td>
      <code>
        GET
      </code>
      
       endpoints take query-string parameters. <code>
        POST
      </code>
      
       endpoints take a JSON body.
    </td>
  </tr>
  
  <tr>
    <td>
      <strong>
        Pagination
      </strong>
    </td>
    
    <td>
      List endpoints return <code>
        nextCursor
      </code>
      
      . Pass it back as <code>
        cursor
      </code>
      
       for the next page; <code>
        null
      </code>
      
       means there are no more pages. <code>
        limit
      </code>
      
       is 1 to 100 (default 25) on catalog, availability, and sales lists, 1 to 200 (default 50) on <code>
        bookings/list
      </code>
      
      , and 1 to 500 (default 100) on <code>
        inventory/status
      </code>
      
      .
    </td>
  </tr>
  
  <tr>
    <td>
      <strong>
        Dates and times
      </strong>
    </td>
    
    <td>
      ISO 8601. On quotes, booking creation, and <code>
        availability/items
      </code>
      
      , a date-time without an offset (<code>
        2026-07-01T10:00:00
      </code>
      
      ) is read in the organization's timezone, daylight saving included. A value with <code>
        Z
      </code>
      
       or an offset is used as given. A date with no time is midnight.
    </td>
  </tr>
  
  <tr>
    <td>
      <strong>
        IDs
      </strong>
    </td>
    
    <td>
      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 <code>
        ?idKind=org
      </code>
      
      .
    </td>
  </tr>
  
  <tr>
    <td>
      <strong>
        Money
      </strong>
    </td>
    
    <td>
      Amounts are in the organization's major currency unit (for example <code>
        1250.5
      </code>
      
      ), with the <code>
        currency
      </code>
      
       code next to them.
    </td>
  </tr>
  
  <tr>
    <td>
      <strong>
        Subrentals
      </strong>
    </td>
    
    <td>
      Products sourced from suppliers are never returned to or accepted from a publishable key. A secret key sees them when <a href="https://requiply.com/docs/en/guides/settings/organization/features">
        Subrentals
      </a>
      
       is on.
    </td>
  </tr>
</tbody>
</table>

## Errors

A failed request answers with an HTTP error status and a JSON body:

```json
{
  "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](https://requiply.com/docs/en/developers/typescript-sdk/error-handling#error-reasons).

<table>
<thead>
  <tr>
    <th>
      Status
    </th>
    
    <th>
      Typical cause
    </th>
  </tr>
</thead>

<tbody>
  <tr>
    <td>
      <code>
        400
      </code>
    </td>
    
    <td>
      A missing or malformed field, such as an invalid date or an empty <code>
        items
      </code>
      
       list.
    </td>
  </tr>
  
  <tr>
    <td>
      <code>
        401
      </code>
    </td>
    
    <td>
      The <code>
        Authorization
      </code>
      
       header is missing, or the key is unknown or revoked.
    </td>
  </tr>
  
  <tr>
    <td>
      <code>
        403
      </code>
    </td>
    
    <td>
      The key type cannot use the endpoint, or a feature or permission is off.
    </td>
  </tr>
  
  <tr>
    <td>
      <code>
        404
      </code>
    </td>
    
    <td>
      The booking, product, client, or sale does not exist in this organization.
    </td>
  </tr>
  
  <tr>
    <td>
      <code>
        409
      </code>
    </td>
    
    <td>
      The request conflicts with the current state, for example a product is archived or out of stock.
    </td>
  </tr>
  
  <tr>
    <td>
      <code>
        429
      </code>
    </td>
    
    <td>
      The key went over its rate limit. Wait the number of seconds in <code>
        Retry-After
      </code>
      
      .
    </td>
  </tr>
</tbody>
</table>

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](https://requiply.com/docs/en/developers/typescript-sdk/bookings#handling-the-response).

## Recording a sale over REST

`POST /sales/create` takes:

```json
{
  "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()`](https://requiply.com/docs/en/developers/typescript-sdk/sales#salescreate).


## Sitemap

See the full [sitemap](https://requiply.com/docs/sitemap.md) for all pages.
