Skip to main content

Products

Retrieve a paginated list of products available in a specific shop, filtered by market.

List Products

GET /v2/public/products/{shop_identifier}
shop_identifier
string
required
Unique identifier for the shop
market
string
required
Market identifier (e.g. DE for Germany)
Filter products and SKUs by name
page
integer
default:"0"
Page number (0-indexed)
limit
integer
default:"50"
Results per page (max 150)
Required permission: product:read

Example Request

curl -X GET "https://api.rxscale.com/v2/public/products/my-shop?market=DE&page=0&limit=25" \
  -H "X-API-Key: your-api-key-here"

Response

{
  "data": [
    {
      "uid": "prod-abc123",
      "display_name": "Medication X",
      "attributes": {
        "category": "Pain Relief"
      },
      "skus": [
        {
          "uid": "sku-456",
          "display_name": "Medication X 100mg",
          "attributes": {
            "package_size": "100mg"
          },
          "availability": "High",
          "telemedicine_provider_data": {
            "external_id": "partner-sku-456"
          },
          "price": 1299,
          "currency": "EUR",
          "unit": "g",
          "standard_selling_unit": 10
        },
        {
          "uid": "sku-789",
          "display_name": "Medication X 200mg",
          "attributes": {
            "package_size": "200mg"
          },
          "availability": "Medium",
          "telemedicine_provider_data": {
            "external_id": "partner-sku-789"
          },
          "price": 1999,
          "currency": "EUR",
          "unit": "g",
          "standard_selling_unit": 20
        }
      ]
    }
  ],
  "totalRegistries": 42,
  "totalPages": 2
}

Response Fields

FieldTypeDescription
dataarrayList of product objects
data[].uidstringProduct UID
data[].display_namestringProduct display name
data[].attributesobjectProduct attributes as key-value pairs
data[].skusarrayAvailable SKUs for this product in the given market
data[].skus[].uidstringSKU UID (use this when creating checkouts)
data[].skus[].display_namestringSKU display name
data[].skus[].attributesobjectSKU attributes as key-value pairs
data[].skus[].availabilitystringAvailability bucket (High, Medium, Low, or Unavailable)
data[].skus[].telemedicine_provider_data.external_idstringExternal SKU identifier for the telemedicine provider
data[].skus[].priceintegerPrice in euro cents
data[].skus[].currencystringPrice currency
data[].skus[].unitstringSKU unit
data[].skus[].standard_selling_unitnumberStandard selling unit
totalRegistriesintegerTotal number of matching products
totalPagesintegerTotal number of pages

Error Responses

Status CodeDescription
400Missing market query parameter
404Shop not found

Check Live Stock

Check whether one or more SKUs are currently available in the requested quantities before the checkout starts.
POST /v2/public/products/{shop_identifier}/live-stock
shop_identifier
string
required
Unique identifier for the shop
Required permission: product:read
Live stock is checked against Shopify’s current available inventory for the mapped product variants. This includes inventory already held by Shopify orders and draft-order reservations.

Request Body

[
  {
    "sku_uid": "sku-456",
    "quantity": 2
  },
  {
    "sku_uid": "sku-789",
    "quantity": 1
  }
]
FieldTypeRequiredDescription
sku_uidstringYesSKU UID from the product catalog
quantityintegerYesQuantity to check. Must be at least 1
Each sku_uid can appear only once per live stock request.

Example Request

curl -X POST "https://api.rxscale.com/v2/public/products/my-shop/live-stock" \
  -H "X-API-Key: your-api-key-here" \
  -H "Content-Type: application/json" \
  -d '[
    {
      "sku_uid": "sku-456",
      "quantity": 2
    }
  ]'

Available Response

When all requested quantities are available, the endpoint returns 200 OK.
{
  "available": true,
  "lines": [
    {
      "sku_uid": "sku-456",
      "quantity": 2,
      "available": true,
      "available_stock": 12
    }
  ]
}

Unavailable Response

When at least one requested quantity is not available, the endpoint returns 409 Conflict.
{
  "available": false,
  "lines": [
    {
      "sku_uid": "sku-456",
      "quantity": 2,
      "available": false,
      "available_stock": 1
    }
  ]
}

Response Fields

FieldTypeDescription
availablebooleantrue only when all requested quantities are available
lines[].sku_uidstringRequested SKU UID
lines[].quantityintegerRequested quantity
lines[].availablebooleanWhether this SKU has enough stock
lines[].available_stockintegerCurrent stock available for the SKU in the shop

Error Responses

Status CodeDescription
400Body validation failed or duplicate sku_uid values
404Shop or SKU not found
409At least one requested quantity is unavailable

Reserve Products

Create a Shopify draft order with a 24-hour inventory reservation before prescriptions are available. Use the returned draft order ID later as reserved_draft_order_id when uploading signed prescriptions.
POST /v2/public/products/{shop_identifier}/reservation
shop_identifier
string
required
Unique identifier for the shop
Required permission: create_prescription_checkout
The reservation request does not include prescriptions or patient data. RxScale adds telemedicine provider attributes from the API key automatically.
The API key must be linked to a telemedicine provider. Requests with a non-telemedicine API key are rejected with 400 Bad Request before any inventory is held, because the resulting draft order could not be matched on the later prescription upload.

Request Body

{
  "external_reservation_id": "caller-reservation-123",
  "lines": [
    {
      "sku_uid": "sku-456",
      "quantity": 1
    }
  ]
}
FieldTypeRequiredDescription
external_reservation_idstringNoYour reservation identifier. Stored on the Shopify draft order and returned in the response
linesarrayYesProducts to reserve
lines[].sku_uidstringYesSKU UID from the product catalog
lines[].quantityintegerYesQuantity to reserve
Each sku_uid can appear only once per reservation request. Duplicate SKU lines are rejected because the later prescription upload must match each reserved draft-order line unambiguously.

Example Request

curl -X POST "https://api.rxscale.com/v2/public/products/my-shop/reservation" \
  -H "X-API-Key: your-api-key-here" \
  -H "Content-Type: application/json" \
  -d '{
    "external_reservation_id": "caller-reservation-123",
    "lines": [
      {
        "sku_uid": "sku-456",
        "quantity": 1
      }
    ]
  }'

Response

{
  "status": "success",
  "external_reservation_id": "caller-reservation-123",
  "draft_order": {
    "id": "123",
    "invoiceUrl": "https://example.myshopify.com/invoice/...",
    "reserve_inventory_until": "2026-05-16T17:20:00Z"
  }
}
The draft_order.id is the Shopify legacy DraftOrder ID, not the Shopify GID. Pass this value to POST /v2/public/prescriptions/{shop_identifier} as reserved_draft_order_id after the prescriptions are signed.

Error Responses

Status CodeDescription
400API key is not linked to a telemedicine provider, body validation failed, or duplicate sku_uid values
404Shop or SKU not found