curl https://api.khaime.com/api/v1/products \
-H "X-API-Key: pk_sandbox_your_key"
curl "https://api.khaime.com/api/v1/products?category_id=5" \
-H "X-API-Key: pk_sandbox_your_key"
curl "https://api.khaime.com/api/v1/products?category_slug=online-courses" \
-H "X-API-Key: pk_sandbox_your_key"
curl "https://api.khaime.com/api/v1/products?category_slug=Online%20Courses" \
-H "X-API-Key: pk_sandbox_your_key"
curl "https://api.khaime.com/api/v1/products?category_slug=online-courses,workshops" \
-H "X-API-Key: pk_sandbox_your_key"
Products & Pricing
List Products
List all products for your merchant account.
GET
/
products
curl https://api.khaime.com/api/v1/products \
-H "X-API-Key: pk_sandbox_your_key"
curl "https://api.khaime.com/api/v1/products?category_id=5" \
-H "X-API-Key: pk_sandbox_your_key"
curl "https://api.khaime.com/api/v1/products?category_slug=online-courses" \
-H "X-API-Key: pk_sandbox_your_key"
curl "https://api.khaime.com/api/v1/products?category_slug=Online%20Courses" \
-H "X-API-Key: pk_sandbox_your_key"
curl "https://api.khaime.com/api/v1/products?category_slug=online-courses,workshops" \
-H "X-API-Key: pk_sandbox_your_key"
Intro
Retrieves the products in your merchant account’s Khaime catalog, with filtering by type and category and standard offset pagination.Context
Products listed here are what Create Payment Intent and Get Product Pricing reference byproduct_id. If you don’t need a catalog entry at all — for example a WooCommerce order where the product lives on your own platform — Create Charge skips this catalog entirely.
Hows
Query parameters
| Parameter | Type | Description |
|---|---|---|
category_id | integer | Filter by product category ID |
category_slug | string | Filter by category slug or name. Comma-separated for multiple. Matches slug exactly OR name case-insensitively, so you can pass either online-courses or Online Courses. Unioned with category_id if both are provided. If the value matches no categories, the response is empty (the filter is not silently dropped). |
product_type | string | Filter by type: digital, physical_product, or gift_card |
limit | integer | Results per page (1-100, default 20) |
offset | integer | Pagination offset (default 0) |
sort_by | string | Sort field (default updatedAt) |
sort_order | string | ASC or DESC (default DESC) |
Response
Important: Products are returned in a nested structure. The array is at
response.data.products, NOT response.data directly.{
"status": true,
"success": true,
"message": "Products retrieved successfully",
"data": {
"products": [
{
"id": 3046,
"title": "Premium T-Shirt",
"slug": "premium-t-shirt",
"description": "High-quality cotton t-shirt",
"price": 2999,
"currency": "USD",
"product_type": "physical_product",
"is_published": true,
"has_variation": true,
"total_quantity": 150,
"images": [
"https://d2ipu1j7d156ey.cloudfront.net/path/to/image.webp"
],
"product_variation": {
"variation_type": "color",
"variations": [
{
"id": "var_red",
"variant_label": "Red",
"variant_object": "#FF0000",
"variation_quantity": 75,
"variation_add_price": 0,
"has_sub_variants": true,
"sub_variation": {
"sub_variation_type": "size",
"sub_variants": [
{
"id": "var_red_s",
"variant_label": "Small",
"variant_quantity": 25,
"subvariant_add_price": 0
},
{
"id": "var_red_l",
"variant_label": "Large",
"variant_quantity": 20,
"subvariant_add_price": 200
}
]
}
}
]
}
}
],
"pagination": {
"limit": 20,
"offset": 0,
"count": 15,
"has_more": false
}
}
}
has_more is true whenever the returned page is exactly limit items long — treat it as “there may be more,” and keep paging with offset until a page comes back shorter than limit.
Products can carry a two-level variation structure (product_variation.variations[], optionally with nested sub_variation.sub_variants[]) when has_variation is true; every price field in the response — price, variation_add_price, subvariant_add_price — is in the smallest currency unit (cents/kobo/pence). See API Response Schemas for the full field-by-field breakdown and Validate Cart for how variant/sub-variant IDs feed into a cart.
Error codes
| Status | Cause |
|---|---|
400 | Invalid product_type (not one of the three valid types) or a non-integer category_id. |
401 | Invalid API key. |
curl https://api.khaime.com/api/v1/products \
-H "X-API-Key: pk_sandbox_your_key"
curl "https://api.khaime.com/api/v1/products?category_id=5" \
-H "X-API-Key: pk_sandbox_your_key"
curl "https://api.khaime.com/api/v1/products?category_slug=online-courses" \
-H "X-API-Key: pk_sandbox_your_key"
curl "https://api.khaime.com/api/v1/products?category_slug=Online%20Courses" \
-H "X-API-Key: pk_sandbox_your_key"
curl "https://api.khaime.com/api/v1/products?category_slug=online-courses,workshops" \
-H "X-API-Key: pk_sandbox_your_key"
Whys
category_slug accepts both the slug and the display name, comma-separated, because partner integrations often have the human-readable category name on hand (from their own CMS or storefront) rather than Khaime’s internal slug — requiring an exact slug match would push an extra lookup step onto every integration. A category_slug that matches nothing returns an empty product list rather than silently ignoring the filter, so a typo in a category name doesn’t quietly turn into “no filter,” masking the mistake as an unfiltered success.
Why nots
- This only lists products already in your Khaime catalog — it has no visibility into products that live on your own platform (e.g. WooCommerce) and are only ever charged for via Create Charge.
- Responses are not localized — prices come back in the product’s own currency, and a
currencyparameter is ignored. To display prices in the customer’s currency, get the supported codes from Get Currencies, then fetch each product with Get Product (?currency=) or Get Product Pricing. Prices, Fees and Totals shows the full checkout flow. limitis capped at 100 — there’s no way to fetch the entire catalog in a single call for large product counts; page withoffsetinstead.
