Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
$kind: collection
description: |-
Carts hold the products a storefront customer intends to purchase. Use cart endpoints to create or retrieve a cart, add or update line items, empty the cart, and prepare it for checkout.
Carts hold the products a storefront customer intends to purchase. Use cart endpoints to create or retrieve a cart, add or update line items, apply or preview promo codes and promotions, empty the cart, and prepare it for checkout.
order: 1000
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,8 @@ example: |
"total_unique_items": 2,
"items": [],
"events": [],
"discount_code": null,
"discount_code": "SUMMER25",
"promo_codes": ["SUMMER25"],
"expires_at": "2026-05-08T09:30:00Z",
"created_at": "2026-05-07T09:30:00Z",
"updated_at": "2026-05-07T09:30:00Z"
Expand Down Expand Up @@ -44,7 +45,10 @@ fields:
description: "Cart event history."
- name: discount_code
type: string
description: "Discount code applied to the cart."
description: "Promo codes applied to the cart, comma separated. Prefer `promo_codes`."
- name: promo_codes
type: array of strings
description: "Promo codes applied to the cart with Apply Promotion Code to Cart. They are used automatically at checkout."
- name: expires_at
type: timestamp
description: "Time the cart expires."
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
$kind: params
fields:
- name: code
type: string
required: true
description: "The promo code to apply."
- name: pickup
type: boolean
description: "Price the cart as a pickup order when validating the code."
- name: service_quote
type: string
description: "Delivery service quote public ID, for free delivery codes."
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
$kind: http-request
description: |-
Applies a promo code to the cart after checking that it can be used on it. Codes are case insensitive. On success it returns `{ "cart": Cart, "promotions": preview }` (see Preview Cart Promotions) and stores the code in the cart's `promo_codes`; codes applied to a cart are used automatically at checkout.

A code that cannot be applied returns `400` with the reason, e.g. `Promotion code "SUMMER" cannot be applied (invalid_code).` and `"reason": "invalid_code"`. Reasons: `invalid_code`, `not_applicable`, `not_active`, `usage_limit_reached`, `customer_usage_limit_reached`, `budget_exhausted`, `currency_mismatch`, `first_order_only`, `min_subtotal`, `min_items`, `no_eligible_items`, `pickup_order`, `no_discount`. A code that is valid but loses to a better combination of promotions is kept on the cart and reported in `promotions.rejected` as `not_combinable`.
url: "{{base_url}}/{{api_prefix}}/{{namespace}}/carts/{{cart_id}}/promo-code"
method: POST
headers:
- key: Customer-Token
value: "{{customer_token}}"
- key: Content-Type
value: application/json
body:
type: json
content: |-
{
"code": "{{promo_code}}"
}
scripts:
- type: beforeRequest
code: |-
// Uses {{promo_code}} when the environment provides a real code. Without one it
// sends an unknown code, and the request documents the refusal contract.
if (!pm.environment.get('promo_code')) {
pm.variables.set('promo_code', 'NOT-A-REAL-CODE');
pm.variables.set('expected_status', 400);
}
language: text/javascript
- type: afterResponse
code: |-
if (pm.response.code === 400) {
pm.test('An unusable code is refused with its reason', function () {
pm.expect(pm.response.json().error).to.include('cannot be applied');
});
}
language: text/javascript
order: 1200
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
$kind: params
fields:
- name: pickup
type: boolean
description: "Price the cart as a pickup order (no delivery discounts)."
- name: service_quote
type: string
description: "Delivery service quote public ID, used to price free delivery promotions."
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
$kind: http-request
description: |-
Previews the discounts the cart currently qualifies for: the storefront's automatic promotions plus the promo codes applied to the cart. Pass `pickup` and `service_quote` so delivery discounts are priced. Customer rules (first order only, per-customer limits) are only checked when a `Customer-Token` is sent, and every rule is checked again at checkout.

Returns `{ "discount", "discount_subtotal", "discount_delivery", "applied": [...], "rejected": [...] }`. Each applied entry has `promotion`, `name`, `type`, `code`, `amount` and `delivery_amount` (minor units). Each rejected entry is `{ "code", "reason" }`.
url: "{{base_url}}/{{api_prefix}}/{{namespace}}/carts/{{cart_id}}/promotions"
method: GET
headers:
- key: Customer-Token
value: "{{customer_token}}"
queryParams:
pickup: "false"
service_quote: "{{service_quote_id}}"
scripts:
- type: afterResponse
code: |-
pm.test('Promotion preview carries the discount totals', function () {
var body = pm.response.json();
pm.expect(body.discount).to.be.a('number');
pm.expect(body.applied).to.be.an('array');
pm.expect(body.rejected).to.be.an('array');
});
language: text/javascript
order: 1100
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
$kind: http-request
description: |-
Removes a promo code from the cart and returns `{ "cart": Cart, "promotions": preview }`. Removing a code that is not on the cart is not an error.
url: "{{base_url}}/{{api_prefix}}/{{namespace}}/carts/{{cart_id}}/promo-code/{{promo_code}}"
method: DELETE
headers:
- key: Customer-Token
value: "{{customer_token}}"
scripts:
- type: beforeRequest
code: |-
if (!pm.environment.get('promo_code')) {
pm.variables.set('promo_code', 'NOT-A-REAL-CODE');
}
language: text/javascript
order: 1300
Original file line number Diff line number Diff line change
Expand Up @@ -12,3 +12,6 @@ fields:
- name: pickup
type: boolean
description: "Set true for a pickup order; a cash pickup checkout needs no service quote."
- name: promo_codes
type: array of strings
description: "Promo codes to apply, as an array or a comma separated string. `promo_code` and `discount_code` are accepted for a single code. Codes already applied to the cart are always included. The checkout is refused with `400` and `promotions.rejected[]` (`{ code, reason }`) when a code cannot be applied; the discount of the storefront's automatic promotions is applied without a code."
Original file line number Diff line number Diff line change
Expand Up @@ -24,3 +24,6 @@ fields:
- name: delivery_tip
type: number
description: "Tip amount allocated to delivery."
- name: promo_codes
type: array of strings
description: "Promo codes to apply, as an array or a comma separated string. `promo_code` and `discount_code` are accepted for a single code. Codes already applied to the cart are always included. The checkout is refused with `400` and `promotions.rejected[]` (`{ code, reason }`) when a code cannot be applied; the discount of the storefront's automatic promotions is applied without a code."
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
$kind: http-request
description: |-
Initializes a checkout preview for a cart, customer, gateway, and delivery or pickup option. The response prepares gateway-specific client data or a checkout token before the order is captured.

Promotions are priced when the checkout is created: automatic promotions and any promo codes (from `promo_codes` or applied to the cart) are subtracted from the amount charged, and each use is reserved for the checkout. A code that cannot be applied refuses the checkout with `400`.
url: "{{base_url}}/{{api_prefix}}/{{namespace}}/checkouts/before"
method: GET
queryParams:
Expand Down
Original file line number Diff line number Diff line change
@@ -1,15 +1,29 @@
$kind: params
fields:
- name: name
- name: customer
type: string
description: "Display name for the resource."
- name: description
required: true
description: "Customer public ID. When Customer-Token is present it must identify the authenticated customer."
- name: cart
type: string
description: "Human-readable description of the resource."
- name: status
type: enum
values: ["active", "inactive"]
description: "Lifecycle status to apply to the resource."
- name: meta
required: true
description: "Cart public ID or unique identifier."
- name: payment_intent_id
type: string
description: "Arbitrary metadata stored with the resource."
required: true
description: "Stripe PaymentIntent to update. `paymentIntent` and `paymentIntentId` are accepted aliases."
- name: service_quote
type: string
description: "Delivery service quote public ID. `serviceQuote` is an accepted alias."
- name: pickup
type: boolean
description: "Whether the order is a pickup order."
- name: tip
type: number
description: "Tip, as an amount or a percentage string such as `10%`."
- name: delivery_tip
type: number
description: "Delivery tip, as an amount or a percentage string. `deliveryTip` is an accepted alias."
- name: promo_codes
type: array of strings
description: "Promo codes to apply, as an array or a comma separated string. `promo_code` and `discount_code` are accepted for a single code. Codes already applied to the cart are always included. The checkout is refused with `400` and `promotions.rejected[]` (`{ code, reason }`) when a code cannot be applied; the discount of the storefront's automatic promotions is applied without a code."
Original file line number Diff line number Diff line change
Expand Up @@ -3,10 +3,16 @@ fields:
- name: token
type: string
required: true
description: "Push notification device token."
description: "Push notification device token: the APNs device token on iOS, the FCM registration token on Android."
- name: platform
type: string
description: "Device platform. `os` is also accepted as an alias."
type: enum
values: ["ios", "android"]
required: true
description: "Device platform, case insensitive. `os` is also accepted as an alias."
- name: os
type: string
description: "Device platform alias used when `platform` is not provided."
- name: environment
type: enum
values: ["production", "sandbox"]
description: "Optional APNs environment that issued an iOS token (sandbox for development builds). When omitted the server tries production and falls back to sandbox. Stored only on Fleetbase versions that record device push metadata."
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
$kind: http-request
description: |-
Registers a device token for the authenticated storefront customer. Use this to enable push notifications for the customer device.
Registers a push notification device token for the authenticated storefront customer. Call it whenever the app receives a new token or a different customer signs in: a token identifies one app install, so it always moves to the customer who registered it most recently. `platform` must be `ios` or `android` (case insensitive); the token is an APNs device token on iOS and an FCM registration token on Android. Returns `{ "status": "OK", "device": "<device public id>" }`, or `400` for a missing token or unsupported platform.
url: "{{base_url}}/{{api_prefix}}/{{namespace}}/customers/register-device"
method: POST
headers:
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
$kind: params
fields:
- name: token
type: string
required: true
description: "The push notification device token to remove."
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
$kind: http-request
description: |-
Removes a push notification device token from the authenticated customer, typically on sign out, so the device stops receiving that customer's notifications. Returns `{ "status": "OK", "deleted": n }`; unregistering a token the customer does not have deletes nothing and is not an error.
url: "{{base_url}}/{{api_prefix}}/{{namespace}}/customers/unregister-device"
method: POST
headers:
- key: Customer-Token
value: "{{customer_token}}"
- key: Content-Type
value: application/json
body:
type: json
content: |-
{
"token": "{{device_token}}"
}
scripts:
- type: beforeRequest
code: |-
// Register customer device uses {{device_token}}; fall back to a placeholder so
// the request still exercises the endpoint when none is configured.
if (!pm.environment.get('device_token')) {
pm.variables.set('device_token', 'postman-placeholder-device-token');
}
language: text/javascript
order: 5100
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
$kind: collection
description: |-
The authenticated customer's notification inbox. Order status updates, promotional messages and campaigns are stored here as well as sent by push, so the app can list them, show an unread badge and mark them as read. Every request needs the `Customer-Token` header. A customer only sees their own notifications, limited to the storefront app the request is made with: a store key sees that store's notifications, a network key sees the network's and its member stores'. Notifications that reference no storefront are shown in every app.

New notifications are also broadcast in realtime on the SocketCluster channel `contact.{customer uuid}` with the same shape as an inbox item.
order: 4500
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
$kind: object
name: Notification
description: |-
An inbox item. `type` identifies what the notification is about (for example `order_accepted`, `order_completed`, `promotional` or `campaign`), and `data` carries the identifiers the app needs to deep link. Recipient details are never included.
example: |
{
"id": "0f4c9a52-8d3f-4a6e-9f0e-2b1f7f2f8c11",
"type": "order_completed",
"title": "Your order from Acme Market has been delivered",
"body": "Your order from Acme Market has been delivered, enjoy!",
"image": null,
"data": {
"order_id": "order_9Kx2mQ1",
"storefront_id": "store_3Xb9kL2",
"store_id": "store_3Xb9kL2"
},
"is_read": false,
"read_at": null,
"created_at": "2026-09-26T09:30:00Z"
}
fields:
- name: id
type: string
description: "Notification id (uuid)."
- name: type
type: string
description: "What the notification is about, e.g. `order_accepted`, `order_enroute`, `order_nearby`, `order_completed`, `order_canceled`, `order_ready`, `order_driver_assigned`, `promotional` or `campaign`."
- name: title
type: string
description: "Notification title."
- name: body
type: string
description: "Notification message."
- name: image
type: string
description: "Optional image URL."
- name: data
type: object
description: "Deep link data with null values removed, such as `order_id`, `store_id`, `network_id`, `promotion_id`, `campaign_id` and `action`/`action_id`/`action_url`."
- name: is_read
type: boolean
description: "Whether the customer has read the notification."
- name: read_at
type: timestamp
description: "When the notification was read."
- name: created_at
type: timestamp
description: "When the notification was created."
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
$kind: http-request
description: |-
Returns `{ "count": n }`, the number of unread notifications for the authenticated customer in the current storefront. Use it for badges.
url: "{{base_url}}/{{api_prefix}}/{{namespace}}/notifications/unread-count"
method: GET
headers:
- key: Customer-Token
value: "{{customer_token}}"
scripts:
- type: afterResponse
code: |-
pm.test('Unread count is a number', function () {
pm.expect(pm.response.json().count).to.be.a('number');
});
language: text/javascript
order: 2000
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
$kind: http-request
description: |-
Deletes one of the authenticated customer's notifications. Returns `{ "status": "OK", "id": "...", "deleted": true }`.
url: "{{base_url}}/{{api_prefix}}/{{namespace}}/notifications/{{notification_id}}"
method: DELETE
headers:
- key: Customer-Token
value: "{{customer_token}}"
scripts:
- type: beforeRequest
code: |-
// Addresses the first notification returned by List Notifications. A fresh
// stack has none, so without one this documents the not-found contract.
if (!pm.environment.get('notification_id')) {
pm.variables.set('notification_id', 'missing-notification');
pm.variables.set('expected_status', 404);
}
language: text/javascript
order: 6000
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
$kind: http-request
description: |-
Returns the authenticated customer's notification preferences, `{ "order_updates": true, "promotions": true }` by default. `order_updates` controls push notifications about the customer's orders (the inbox copy is always kept); `promotions` controls promotional notifications and campaigns entirely.
url: "{{base_url}}/{{api_prefix}}/{{namespace}}/notifications/preferences"
method: GET
headers:
- key: Customer-Token
value: "{{customer_token}}"
order: 7000
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
$kind: params
fields:
- name: unread
type: boolean
description: "Only return notifications that have not been read."
- name: type
type: string
description: "Only return notifications of this type, e.g. `order_completed` or `promotional`."
- name: limit
type: integer
description: "Maximum number of notifications to return. Defaults to 25, maximum 100."
- name: offset
type: integer
description: "Number of notifications to skip."
Loading
Loading