Shop API Resources
The Shop API provides comprehensive endpoints for customer-facing e-commerce operations. This resource covers product browsing, catalog management, and basic shop information.
Authentication
All Shop API endpoints require the X-STOREFRONT-KEY header for authentication.
Getting Your Storefront Key
To use the Shop APIs, you need a Storefront Key. Generate one using the Artisan command:
php artisan bagisto-api:generate-key --name="Web Storefront"This will output a key in the format: pk_storefront_xxxxx
Headers Required
All requests must include:
X-STOREFRONT-KEY: pk_storefront_xxxxx
Content-Type: application/jsonRate Limiting
- Default limit: 100 requests per minute per key
- Response headers: Each response includes rate limit information
X-RateLimit-Limit: Total requests allowedX-RateLimit-Remaining: Remaining requests this minuteX-RateLimit-Reset: Unix timestamp when limit resets
Error Responses
401 - Missing Key
{
"message": "X-STOREFRONT-KEY header is required",
"error": "missing_key"
}403 - Invalid Key
{
"message": "Invalid storefront key",
"error": "invalid_key"
}429 - Rate Limit Exceeded
{
"message": "Rate limit exceeded",
"error": "rate_limit_exceeded",
"retry_after": 35
}Products
List Products
Retrieve a paginated collection of products.
Endpoint:
GET /api/shop/productsHeaders:
X-STOREFRONT-KEY: pk_storefront_xxxxx
Content-Type: application/jsonParameters:
page: Page number (default: 1)itemsPerPage: Items per page (default: 30, max: 100)name: Filter by product namestatus: Filter by status (true/false)
:::tabs
== cURL
curl -X GET "https://your-domain.com/api/shop/products?page=1&itemsPerPage=10" \
-H "Content-Type: application/json" \
-H "X-STOREFRONT-KEY: pk_storefront_xxxxx"== Node.js
const response = await fetch('https://your-domain.com/api/shop/products?page=1&itemsPerPage=10', {
method: 'GET',
headers: {
'Content-Type': 'application/json',
'X-STOREFRONT-KEY': 'pk_storefront_xxxxx'
}
});
const data = await response.json();
console.log(data);== Python
import requests
response = requests.get(
'https://your-domain.com/api/shop/products',
params={'page': 1, 'itemsPerPage': 10},
headers={
'Content-Type': 'application/json',
'X-STOREFRONT-KEY': 'pk_storefront_xxxxx'
}
)
data = response.json()
print(data)== PHP
<?php
$client = new GuzzleHttp\Client();
$response = $client->request('GET', 'https://your-domain.com/api/shop/products', [
'query' => [
'page' => 1,
'itemsPerPage' => 10
],
'headers' => [
'Content-Type' => 'application/json',
'X-STOREFRONT-KEY' => 'pk_storefront_xxxxx'
]
]);
$data = json_decode($response->getBody(), true);
print_r($data);:::
Response (200 OK):
{
"@context": "/api/contexts/Product",
"@id": "/api/shop/products",
"@type": "hydra:Collection",
"hydra:member": [
{
"@id": "/api/shop/products/1",
"@type": "Product",
"id": 1,
"sku": "SKU-001",
"name": "Premium Wireless Headphones",
"price": "199.99",
"status": true,
"url_key": "premium-wireless-headphones"
}
],
"hydra:totalItems": 150,
"hydra:view": {
"hydra:first": "/api/shop/products?page=1",
"hydra:next": "/api/shop/products?page=2",
"hydra:last": "/api/shop/products?page=8"
}
}Get Product Details
Retrieve comprehensive information about a specific product.
Endpoint:
GET /api/shop/products/{id}:::tabs
== cURL
curl -X GET "https://your-domain.com/api/shop/products/1" \
-H "Content-Type: application/json"== Node.js
const productId = 1;
const response = await fetch(`https://your-domain.com/api/shop/products/${productId}`, {
method: 'GET',
headers: {
'Content-Type': 'application/json'
}
});
const product = await response.json();
console.log(product);== Python
import requests
product_id = 1
response = requests.get(
f'https://your-domain.com/api/shop/products/{product_id}',
headers={'Content-Type': 'application/json'}
)
product = response.json()
print(product):::
Response (200 OK):
{
"@context": "/api/contexts/Product",
"@id": "/api/shop/products/1",
"@type": "Product",
"id": 1,
"sku": "SKU-001",
"name": "Premium Wireless Headphones",
"description": "High-quality wireless headphones with noise cancellation",
"short_description": "Best in class wireless audio",
"price": "199.99",
"cost": "100.00",
"status": true,
"type": "simple",
"weight": "0.25",
"url_key": "premium-wireless-headphones"
}Create Product
Create a new product in the catalog (admin only).
Endpoint:
POST /api/shop/products:::tabs
== cURL
curl -X POST "https://your-domain.com/api/shop/products" \
-H "Content-Type: application/json" \
-H "Authorization: Bearer YOUR_ADMIN_TOKEN" \
-d '{
"sku": "NEW-PRODUCT-001",
"name": "New Product",
"description": "Product description",
"price": "99.99",
"cost": "50.00",
"status": true
}'== Node.js
const response = await fetch('https://your-domain.com/api/shop/products', {
method: 'POST',
headers: {
'Content-Type': 'application/json',
'Authorization': 'Bearer YOUR_ADMIN_TOKEN'
},
body: JSON.stringify({
sku: 'NEW-PRODUCT-001',
name: 'New Product',
description: 'Product description',
price: '99.99',
cost: '50.00',
status: true
})
});
const product = await response.json();
console.log(product);== Python
import requests
response = requests.post(
'https://your-domain.com/api/shop/products',
headers={
'Content-Type': 'application/json',
'Authorization': 'Bearer YOUR_ADMIN_TOKEN'
},
json={
'sku': 'NEW-PRODUCT-001',
'name': 'New Product',
'description': 'Product description',
'price': '99.99',
'cost': '50.00',
'status': True
}
)
product = response.json()
print(product):::
Response (201 Created):
{
"@context": "/api/contexts/Product",
"@id": "/api/shop/products/100",
"@type": "Product",
"id": 100,
"sku": "NEW-PRODUCT-001",
"name": "New Product",
"price": "99.99",
"status": true
}Update Product
Modify an existing product (admin only).
Endpoint:
PATCH /api/shop/products/{id}:::tabs
== cURL
curl -X PATCH "https://your-domain.com/api/shop/products/1" \
-H "Content-Type: application/json" \
-H "Authorization: Bearer YOUR_ADMIN_TOKEN" \
-d '{
"name": "Updated Product Name",
"price": "249.99"
}'== Node.js
const response = await fetch('https://your-domain.com/api/shop/products/1', {
method: 'PATCH',
headers: {
'Content-Type': 'application/json',
'Authorization': 'Bearer YOUR_ADMIN_TOKEN'
},
body: JSON.stringify({
name: 'Updated Product Name',
price: '249.99'
})
});
const product = await response.json();
console.log(product);== Python
import requests
response = requests.patch(
'https://your-domain.com/api/shop/products/1',
headers={
'Content-Type': 'application/json',
'Authorization': 'Bearer YOUR_ADMIN_TOKEN'
},
json={
'name': 'Updated Product Name',
'price': '249.99'
}
)
product = response.json()
print(product):::
Categories
List Categories
Retrieve all product categories.
Endpoint:
GET /api/shop/categories:::tabs
== cURL
curl -X GET "https://your-domain.com/api/shop/categories" \
-H "Content-Type: application/json"== Node.js
const response = await fetch('https://your-domain.com/api/shop/categories', {
method: 'GET',
headers: {
'Content-Type': 'application/json'
}
});
const categories = await response.json();
console.log(categories);== Python
import requests
response = requests.get(
'https://your-domain.com/api/shop/categories',
headers={'Content-Type': 'application/json'}
)
categories = response.json()
print(categories):::
Response (200 OK):
{
"@context": "/api/contexts/Category",
"@id": "/api/shop/categories",
"@type": "hydra:Collection",
"hydra:member": [
{
"@id": "/api/shop/categories/1",
"@type": "Category",
"id": 1,
"name": "Electronics",
"status": true,
"url_key": "electronics"
}
],
"hydra:totalItems": 8
}Attributes
List Attributes
Retrieve all product attributes.
Endpoint:
GET /api/shop/attributes:::tabs
== cURL
curl -X GET "https://your-domain.com/api/shop/attributes" \
-H "Content-Type: application/json"== Node.js
const response = await fetch('https://your-domain.com/api/shop/attributes', {
method: 'GET',
headers: {
'Content-Type': 'application/json'
}
});
const attributes = await response.json();
console.log(attributes);== Python
import requests
response = requests.get(
'https://your-domain.com/api/shop/attributes',
headers={'Content-Type': 'application/json'}
)
attributes = response.json()
print(attributes):::
Attribute Options
List Attribute Options
Retrieve options for attributes.
Endpoint:
GET /api/shop/attribute-options:::tabs
== cURL
curl -X GET "https://your-domain.com/api/shop/attribute-options" \
-H "Content-Type: application/json"== Node.js
const response = await fetch('https://your-domain.com/api/shop/attribute-options', {
method: 'GET'
});
const options = await response.json();
console.log(options);:::
Channels
List Channels
Retrieve all available channels.
Endpoint:
GET /api/shop/channels:::tabs
== cURL
curl -X GET "https://your-domain.com/api/shop/channels" \
-H "Content-Type: application/json"== Node.js
const response = await fetch('https://your-domain.com/api/shop/channels');
const channels = await response.json();
console.log(channels);:::
Countries & States
List Countries
Retrieve all available countries.
Endpoint:
GET /api/shop/countries:::tabs
== cURL
curl -X GET "https://your-domain.com/api/shop/countries" \
-H "Content-Type: application/json"== Node.js
const response = await fetch('https://your-domain.com/api/shop/countries');
const countries = await response.json();
console.log(countries);:::
List Country States
Retrieve states for a specific country.
Endpoint:
GET /api/shop/countries/{country_id}/states:::tabs
== cURL
curl -X GET "https://your-domain.com/api/shop/countries/1/states" \
-H "Content-Type: application/json"== Node.js
const countryId = 1;
const response = await fetch(`https://your-domain.com/api/shop/countries/${countryId}/states`);
const states = await response.json();
console.log(states);:::
Locales
List Locales
Retrieve all available locales.
Endpoint:
GET /api/shop/locales:::tabs
== cURL
curl -X GET "https://your-domain.com/api/shop/locales" \
-H "Content-Type: application/json"== Node.js
const response = await fetch('https://your-domain.com/api/shop/locales');
const locales = await response.json();
console.log(locales);:::
Related Resources
Products
The Product resource represents items in your store catalog.
List Products
Retrieve a collection of products with optional filtering and pagination.
Endpoint:
GET /api/shop/productsQuery Parameters:
page: Page number (default: 1)itemsPerPage: Items per page (default: 30, max: 100)name: Filter by product namestatus: Filter by status (true/false)order[name]: Sort by name (asc/desc)order[price]: Sort by price (asc/desc)
Request:
curl -X GET "https://your-domain.com/api/shop/products?page=1&itemsPerPage=10" \
-H "Content-Type: application/json"Response (200 OK):
{
"@context": "/api/contexts/Product",
"@id": "/api/shop/products",
"@type": "hydra:Collection",
"hydra:member": [
{
"@id": "/api/shop/products/1",
"@type": "Product",
"id": 1,
"name": "Premium Wireless Headphones",
"description": "High-quality wireless headphones with noise cancellation",
"price": "199.99",
"status": true,
"url_key": "premium-wireless-headphones",
"short_description": "Best in class wireless audio"
}
],
"hydra:totalItems": 150,
"hydra:view": {
"@id": "/api/shop/products?page=1&itemsPerPage=10",
"@type": "hydra:PartialCollectionView",
"hydra:first": "/api/shop/products?page=1&itemsPerPage=10",
"hydra:next": "/api/shop/products?page=2&itemsPerPage=10",
"hydra:last": "/api/shop/products?page=15&itemsPerPage=10"
}
}Get Product Details
Retrieve detailed information about a specific product.
Endpoint:
GET /api/shop/products/{id}Path Parameters:
id: Product ID (required)
Request:
curl -X GET "https://your-domain.com/api/shop/products/1" \
-H "Content-Type: application/json"Response (200 OK):
{
"@context": "/api/contexts/Product",
"@id": "/api/shop/products/1",
"@type": "Product",
"id": 1,
"name": "Premium Wireless Headphones",
"description": "High-quality wireless headphones with noise cancellation",
"price": "199.99",
"status": true,
"url_key": "premium-wireless-headphones",
"short_description": "Best in class wireless audio",
"attribute_family_id": 1,
"created_at": "2024-01-15T10:30:00Z",
"updated_at": "2024-01-20T15:45:00Z"
}Create Product
Create a new product in the catalog.
Endpoint:
POST /api/shop/productsRequest Body:
{
"name": "New Smartphone",
"description": "Latest model smartphone with advanced features",
"short_description": "Premium smartphone",
"price": "899.99",
"status": true,
"url_key": "new-smartphone"
}Request:
curl -X POST "https://your-domain.com/api/shop/products" \
-H "Content-Type: application/json" \
-H "Authorization: Bearer YOUR_ADMIN_TOKEN" \
-d '{
"name": "New Smartphone",
"description": "Latest model smartphone",
"price": "899.99",
"status": true,
"url_key": "new-smartphone"
}'Response (201 Created):
{
"@context": "/api/contexts/Product",
"@id": "/api/shop/products/5",
"@type": "Product",
"id": 5,
"name": "New Smartphone",
"description": "Latest model smartphone with advanced features",
"price": "899.99",
"status": true,
"url_key": "new-smartphone"
}Update Product
Update an existing product.
Endpoint:
PUT /api/shop/products/{id}
PATCH /api/shop/products/{id}Request:
curl -X PATCH "https://your-domain.com/api/shop/products/1" \
-H "Content-Type: application/json" \
-H "Authorization: Bearer YOUR_ADMIN_TOKEN" \
-d '{
"name": "Updated Product Name",
"price": "249.99"
}'Response (200 OK):
{
"@context": "/api/contexts/Product",
"@id": "/api/shop/products/1",
"@type": "Product",
"id": 1,
"name": "Updated Product Name",
"price": "249.99",
"status": true
}Categories
The Category resource represents product categories for organizing your catalog.
List Categories
Retrieve all product categories.
Endpoint:
GET /api/shop/categoriesRequest:
curl -X GET "https://your-domain.com/api/shop/categories" \
-H "Content-Type: application/json"Response (200 OK):
{
"@context": "/api/contexts/Category",
"@id": "/api/shop/categories",
"@type": "hydra:Collection",
"hydra:member": [
{
"@id": "/api/shop/categories/1",
"@type": "Category",
"id": 1,
"name": "Electronics",
"description": "Electronic devices and accessories",
"status": true,
"url_key": "electronics"
},
{
"@id": "/api/shop/categories/2",
"@type": "Category",
"id": 2,
"name": "Clothing",
"description": "Fashion and apparel",
"status": true,
"url_key": "clothing"
}
],
"hydra:totalItems": 8
}Get Category Details
Retrieve detailed information about a specific category.
Endpoint:
GET /api/shop/categories/{id}Request:
curl -X GET "https://your-domain.com/api/shop/categories/1" \
-H "Content-Type: application/json"Response (200 OK):
{
"@context": "/api/contexts/Category",
"@id": "/api/shop/categories/1",
"@type": "Category",
"id": 1,
"name": "Electronics",
"description": "Electronic devices and accessories",
"status": true,
"url_key": "electronics",
"parent_id": null,
"created_at": "2024-01-01T10:00:00Z"
}Attributes
The Attribute resource represents product attributes for filtering and product characteristics.
List Attributes
Retrieve all product attributes.
Endpoint:
GET /api/shop/attributesRequest:
curl -X GET "https://your-domain.com/api/shop/attributes?page=1&itemsPerPage=20" \
-H "Content-Type: application/json"Response (200 OK):
{
"@context": "/api/contexts/Attribute",
"@id": "/api/shop/attributes",
"@type": "hydra:Collection",
"hydra:member": [
{
"@id": "/api/shop/attributes/1",
"@type": "Attribute",
"id": 1,
"name": "Color",
"code": "color",
"type": "select",
"is_filterable": true,
"is_searchable": true
},
{
"@id": "/api/shop/attributes/2",
"@type": "Attribute",
"id": 2,
"name": "Size",
"code": "size",
"type": "select",
"is_filterable": true
}
],
"hydra:totalItems": 12
}Get Attribute Details
Retrieve a specific attribute with its options.
Endpoint:
GET /api/shop/attributes/{id}Request:
curl -X GET "https://your-domain.com/api/shop/attributes/1" \
-H "Content-Type: application/json"Response (200 OK):
{
"@context": "/api/contexts/Attribute",
"@id": "/api/shop/attributes/1",
"@type": "Attribute",
"id": 1,
"name": "Color",
"code": "color",
"type": "select",
"is_filterable": true,
"is_searchable": true,
"is_comparable": false,
"is_visible_on_front": true
}Attribute Options
The AttributeOption resource represents available values for attributes.
List Attribute Options
Retrieve options for all attributes or a specific attribute.
Endpoint:
GET /api/shop/attribute-options
GET /api/shop/attributes/{attribute_id}/optionsRequest:
# All attribute options
curl -X GET "https://your-domain.com/api/shop/attribute-options" \
-H "Content-Type: application/json"
# Options for specific attribute
curl -X GET "https://your-domain.com/api/shop/attributes/1/options" \
-H "Content-Type: application/json"Response (200 OK):
{
"@context": "/api/contexts/AttributeOption",
"@id": "/api/shop/attribute-options",
"@type": "hydra:Collection",
"hydra:member": [
{
"@id": "/api/shop/attribute-options/1",
"@type": "AttributeOption",
"id": 1,
"attribute_id": 1,
"label": "Red",
"code": "red",
"position": 1
},
{
"@id": "/api/shop/attribute-options/2",
"@type": "AttributeOption",
"id": 2,
"attribute_id": 1,
"label": "Blue",
"code": "blue",
"position": 2
}
],
"hydra:totalItems": 5
}Channels
The Channel resource represents different sales channels (e.g., desktop, mobile).
List Channels
Retrieve all available channels.
Endpoint:
GET /api/shop/channelsRequest:
curl -X GET "https://your-domain.com/api/shop/channels" \
-H "Content-Type: application/json"Response (200 OK):
{
"@context": "/api/contexts/Channel",
"@id": "/api/shop/channels",
"@type": "hydra:Collection",
"hydra:member": [
{
"@id": "/api/shop/channels/1",
"@type": "Channel",
"id": 1,
"name": "Default Channel",
"code": "default",
"description": "Default sales channel",
"is_active": true,
"base_currency_code": "USD"
}
],
"hydra:totalItems": 1
}Get Channel Details
Retrieve specific channel configuration.
Endpoint:
GET /api/shop/channels/{id}Request:
curl -X GET "https://your-domain.com/api/shop/channels/1" \
-H "Content-Type: application/json"Response (200 OK):
{
"@context": "/api/contexts/Channel",
"@id": "/api/shop/channels/1",
"@type": "Channel",
"id": 1,
"name": "Default Channel",
"code": "default",
"description": "Default sales channel",
"is_active": true,
"base_currency_code": "USD",
"base_url": "https://your-domain.com",
"hostname": "your-domain.com"
}Countries & States
The Country resource represents available countries for shipping and billing.
List Countries
Retrieve all available countries.
Endpoint:
GET /api/shop/countriesRequest:
curl -X GET "https://your-domain.com/api/shop/countries" \
-H "Content-Type: application/json"Response (200 OK):
{
"@context": "/api/contexts/Country",
"@id": "/api/shop/countries",
"@type": "hydra:Collection",
"hydra:member": [
{
"@id": "/api/shop/countries/1",
"@type": "Country",
"id": 1,
"name": "United States",
"code": "US"
},
{
"@id": "/api/shop/countries/2",
"@type": "Country",
"id": 2,
"name": "Canada",
"code": "CA"
}
],
"hydra:totalItems": 195
}Get Country Details
Retrieve a specific country.
Endpoint:
GET /api/shop/countries/{id}Request:
curl -X GET "https://your-domain.com/api/shop/countries/1" \
-H "Content-Type: application/json"Response (200 OK):
{
"@context": "/api/contexts/Country",
"@id": "/api/shop/countries/1",
"@type": "Country",
"id": 1,
"name": "United States",
"code": "US"
}List Country States
Retrieve states for a specific country.
Endpoint:
GET /api/shop/country-states
GET /api/shop/countries/{country_id}/statesRequest:
# All country states
curl -X GET "https://your-domain.com/api/shop/country-states" \
-H "Content-Type: application/json"
# States for specific country
curl -X GET "https://your-domain.com/api/shop/countries/1/states" \
-H "Content-Type: application/json"Response (200 OK):
{
"@context": "/api/contexts/CountryState",
"@id": "/api/shop/country-states",
"@type": "hydra:Collection",
"hydra:member": [
{
"@id": "/api/shop/country-states/1",
"@type": "CountryState",
"id": 1,
"country_id": 1,
"name": "California",
"code": "CA"
},
{
"@id": "/api/shop/country-states/2",
"@type": "CountryState",
"id": 2,
"country_id": 1,
"name": "Texas",
"code": "TX"
}
],
"hydra:totalItems": 50
}Locales
The Locale resource represents available languages and locales.
List Locales
Retrieve all available locales.
Endpoint:
GET /api/shop/localesRequest:
curl -X GET "https://your-domain.com/api/shop/locales" \
-H "Content-Type: application/json"Response (200 OK):
{
"@context": "/api/contexts/Locale",
"@id": "/api/shop/locales",
"@type": "hydra:Collection",
"hydra:member": [
{
"@id": "/api/shop/locales/1",
"@type": "Locale",
"id": 1,
"name": "English",
"code": "en",
"language": "English",
"script": "Latn"
},
{
"@id": "/api/shop/locales/2",
"@type": "Locale",
"id": 2,
"name": "French",
"code": "fr",
"language": "French",
"script": "Latn"
}
],
"hydra:totalItems": 10
}Error Handling
404 Not Found
{
"@context": "/api/contexts/Error",
"@type": "hydra:Error",
"hydra:title": "An error occurred",
"hydra:description": "Not Found",
"status": 404
}400 Bad Request
{
"@context": "/api/contexts/Error",
"@type": "hydra:Error",
"hydra:title": "An error occurred",
"hydra:description": "Invalid request",
"status": 400
}
