Use Your shop API when your store doesn't run on Shopify or WooCommerce. You add a few read endpoints to your backend that answer in the JSON shape below, and Kai can then:
look up orders ("Where is my order?"),
recommend products from your live catalogue,
start returns, and
check and share discount codes.
Kai shows the results as cards in the chat, and your team sees the customer's orders in the inbox.
Open Settings → Apps → Add app and choose Your shop API. Review its uses and continue to setup. Enter the HTTPS base URL and headers Gleap should send, then use Test connection before connecting it.
How Gleap calls your API
Base URL |
|
Headers | The headers you entered (up to 10), plus |
Timeout | 10 seconds per request. |
Response size | Up to 2 MB. |
Status codes |
|
All paths below are relative to your base URL. With the base URL https://shop.example.com/api/gleap, products are read from https://shop.example.com/api/gleap/products.
Endpoints
Method | Path | Required | Used for |
|---|---|---|---|
|
| Yes | Product recommendations, Test connection |
|
| Yes | A single product |
|
| Yes | Order lookups by number |
|
| Yes | Finding the customer |
|
| Yes | The customer's recent orders (Kai and the inbox) |
|
| Optional | Checking a discount code |
|
| Optional | Starting a return |
Products
GET /products?q=hiking%20boots&max_price=120&in_stock=true&limit=6
Parameter | |
|---|---|
| Search words, in the shop's language. |
| Optional. Upper price limit in the shop currency. |
| Optional. |
| Maximum number of products to return. Gleap asks for 6 or fewer. |
{
"products": [
{
"id": "sku-4012",
"title": "Trail Runner GTX",
"subtitle": "Waterproof trail shoe",
"image": "https://cdn.example.com/trail-runner.png",
"price": { "amount": 89.9, "currency": "EUR" },
"compareAtPrice": { "amount": 119, "currency": "EUR" },
"rating": 4.6,
"reviewCount": 212,
"inStock": true,
"url": "https://shop.example.com/products/trail-runner-gtx",
"addToCartUrl": "https://shop.example.com/cart/add?sku=sku-4012",
"variants": [
{ "id": "sku-4012-42", "title": "42 / Blue", "price": { "amount": 89.9, "currency": "EUR" }, "inStock": true, "stock": 4 }
]
}
]
}GET /products/{id} returns { "product": { … } } in the same shape, or 404.
Field | Type | |
|---|---|---|
| string or number | Required. |
| string | Required. |
| string | Shown under the title. |
| https URL | |
|
| |
| number, 0–5 | |
| integer | |
| boolean | |
| https URL | The product page. |
| https URL | Optional. A link that puts the product into the cart. The + button on the product card opens it. |
| array | Optional: |
Orders
GET /orders/1042?email=sam%40example.com
The number is URL-encoded, without a leading #. email is the address the customer gave in the chat; when Gleap knows the signed-in customer, it is their email from /customers. You may return 404 when the email doesn't match. Gleap checks it again either way.
{
"order": {
"id": "ord_88123",
"number": "1042",
"email": "[email protected]",
"customerId": "cus_311",
"status": "shipped",
"createdAt": "2026-10-08T09:12:00Z",
"currency": "EUR",
"items": [
{
"id": "line_1",
"title": "Trail Runner GTX",
"variant": "42 / Blue",
"image": "https://cdn.example.com/trail-runner.png",
"quantity": 1,
"price": { "amount": 89.9, "currency": "EUR" }
}
],
"subtotal": { "amount": 89.9, "currency": "EUR" },
"shipping": { "amount": 4.9, "currency": "EUR" },
"total": { "amount": 94.8, "currency": "EUR" },
"fulfillments": [
{
"carrier": "DHL",
"trackingNumber": "JD014600006281234567",
"trackingUrl": "https://www.dhl.com/track?id=JD014600006281234567",
"shippedAt": "2026-10-09T15:00:00Z",
"estimatedDeliveryAt": "2026-10-15T16:00:00Z",
"itemIds": ["line_1"]
}
],
"statusUrl": "https://shop.example.com/account/orders/1042"
}
}GET /orders?customer_id=cus_311&limit=5 and GET /orders?email=sam%40example.com&limit=5 return { "orders": [ … ] }, newest first. Gleap drops any order that doesn't belong to that customer or email.
Field | Type | |
|---|---|---|
| string or number | Required. What the customer knows ("1042"). |
| string | Your internal id. Defaults to |
| string | The order's email. Required for lookups by number and email. |
| string | The customer's |
| string | Required. One of |
| ISO 8601 date | Required. |
| array | Required (may be empty). Each item: |
| Required. | |
| array | Shipments: |
| https URL | Your order status page, safe to give the customer. |
Customers
GET /customers?email=sam%40example.com and GET /customers?user_id=user_1842 return:
{
"customers": [
{
"id": "cus_311",
"email": "[email protected]",
"name": "Sam Rivera",
"userId": "user_1842",
"ordersCount": 7,
"totalSpent": { "amount": 512.4, "currency": "EUR" },
"createdAt": "2025-03-02T10:00:00Z"
}
]
}user_id is the user id your app passes to Gleap.identify with identity verification. Return only the customer with exactly that user id, and include it as userId. Gleap drops any customer whose userId (or, for email lookups, email) doesn't match.
Discount codes (optional)
GET /discounts/SPRING10 returns 404 for an unknown code, or:
{
"discount": {
"valid": true,
"code": "SPRING10",
"headline": "10% off your next order",
"expires": "2026-10-31T23:59:59Z",
"applyUrl": "https://shop.example.com/discount/SPRING10"
}
}Return "valid": false for codes that are expired or used up. Kai only shares a code after this check says it is valid. applyUrl is optional: the Apply to bag button on the offer card opens it.
Returns (optional)
Kai never starts a return on its own. It shows the customer a confirm card, and Gleap calls this endpoint once, when the customer taps Start return (or when a teammate approves a return an AI agent asked for).
POST /returns
{
"orderNumber": "1042",
"email": "[email protected]",
"items": [{ "id": "line_1", "quantity": 1 }],
"reason": "Doesn't fit",
"exchange": false,
"reference": "Gleap ticket 6703c1f0e4b0a1b2c3d4e5f6"
}{
"return": {
"returnId": "ret_5521",
"labelUrl": "https://shop.example.com/returns/ret_5521/label.pdf",
"message": "Return created, label attached."
}
}With a labelUrl, the customer gets the label link in the chat. Without one, Kai tells them your team emails the label.
Money
{ "amount": 89.9, "currency": "EUR" }amount is in major units (a number or a numeric string such as "89.90"). currency is the 3-letter ISO code. Gleap formats prices in the customer's language.
Who sees order data
Products and discount codes are public. Orders are only shown to the order's customer:
Signed-in customers (identity verification on): Gleap asks
/customers?user_id=with the verified user id and shows that customer's orders.Everyone else has to give the order number and the email used for the order. Kai asks for both with a small form. A wrong email gets the same answer as an unknown number, and after 5 failed tries in one conversation Kai stops looking up orders.
Gleap never lists orders for an email alone, and never sends your headers or keys to the browser or into a chat card.
Kai's switches
Each connection has four switches under Integrations → Your shop API:
Switch | Default |
|---|---|
Kai looks up orders | On |
Kai recommends products | On |
Kai starts returns (needs | Off |
Kai shares discount codes (needs | Off |
Test connection
Test connection calls GET /products?q=test&limit=3 with your headers. It passes when your API answers 200 with { "products": [ … ] }; an empty list is fine.

