List Products
The canonical admin product listing — a paginated, filterable, and sortable product list that mirrors the Bagisto admin Catalog → Products datagrid 1:1. Same columns, same filters, and the same sort options used by the admin screen. This is the listing you want for product-management screens.
How this menu works
For the product types, the two-step create flow, status vs. visibleIndividually, and the per-product sub-resources, see the Products overview.
Not the Create-Order search
GET /api/admin/catalog/products (this endpoint) is the full product listing.
A separate slim search — GET /api/admin/products — powers the admin Create-Order "Add Product" modal only. Use this page for the actual product listing.
Endpoint
| Endpoint | Method | Authentication |
|---|---|---|
/api/admin/catalog/products | GET | Admin Bearer token |
Authentication
Every request requires:
Authorization: Bearer <token>Obtain the Bearer token via Authentication.
Query Parameters
| Parameter | Type | Description | Example |
|---|---|---|---|
page | integer | Page number (1-based, default 1) | 1 |
per_page | integer | Items per page (default 10, max 50) | 10 |
product_id | string | Filter by product ID — single integer or comma-separated list | 142 or 1,2,3 |
sku | string | Partial SKU match (SQL LIKE %value%) | SP-001 |
name | string | Partial product name match (SQL LIKE %value%) | Classic Watch |
type | string | Filter by product type | simple |
status | integer | Filter by status: 0 = disabled, 1 = enabled | 1 |
attribute_family | integer | Filter by attribute family ID | 1 |
channel | string | Channel code for locale/price resolution (default: current channel) | default |
locale | string | Locale code for name/category resolution (default: app locale) | en |
price_from | number | Minimum price filter (inclusive) | 10.00 |
price_to | number | Maximum price filter (inclusive) | 500.00 |
price | string | Price range shorthand — "min,max". Overridden by price_from/price_to when both are present | 10,500 |
sort | string | Column to sort by (see Sorting section below) | product_id |
order | string | Sort direction: asc or desc (default desc) | desc |
Valid type values
simple, configurable, bundle, grouped, downloadable, virtual, booking
Response Shape
Responses use the standard admin { data, meta } envelope.
meta object
| Field | Type | Description |
|---|---|---|
currentPage | integer | Current page number (1-based) |
perPage | integer | Number of items on this page |
lastPage | integer | Total number of pages |
total | integer | Total matching products |
from | integer | 1-based index of the first item on this page |
to | integer | 1-based index of the last item on this page |
Row fields (data[])
| Field | Type | Description |
|---|---|---|
id | integer | Product ID |
sku | string|null | Product SKU |
name | string|null | Product name (resolved via locale and channel) |
type | string|null | Product type (e.g. simple, configurable) |
status | integer|null | 1 = enabled, 0 = disabled |
price | string|null | Raw price value (decimal string, e.g. "3000.0000") |
formattedPrice | string|null | Locale-formatted price (e.g. "$3,000.00") |
specialPrice | string|null | Raw special (sale) price as a decimal string; null if none |
formattedSpecialPrice | string|null | Locale-formatted special price; null if none |
specialPriceFrom | string|null | Start of the special-price window; null unless a dated window is set |
specialPriceTo | string|null | End of the special-price window; null unless a dated window is set |
quantity | integer | Sum of inventory qty across all inventory sources |
baseImageUrl | string|null | Storage URL of the product's first image; null if no images |
imagesCount | integer | Total number of images attached to the product |
categoryId | integer|null | ID of the first category this product belongs to; null if uncategorized |
categoryName | string|null | Translated name of that category (resolved via locale); null if uncategorized |
channel | string|null | Channel code used for resolution |
locale | string|null | Locale code used for resolution |
attributeFamilyId | integer|null | Attribute family ID |
attributeFamilyName | string|null | Attribute family name |
urlKey | string|null | URL slug (e.g. acme-drawstring-bag) |
visibleIndividually | boolean|null | Whether the product appears in category/search listings |
shortDescription | string|null | Short description |
metaTitle | string|null | SEO meta title (empty string when unset) |
metaDescription | string|null | SEO meta description (empty string when unset) |
metaKeywords | string|null | SEO meta keywords (empty string when unset) |
weight | number|null | Product weight |
featured | boolean | Whether the product is flagged as featured |
new | boolean | Whether the product is flagged as "new" |
createdAt | string | Creation timestamp |
updatedAt | string | Last-update timestamp |
Notes on the listing values:
price,specialPriceare decimal strings, not numbers.specialPriceFrom/specialPriceToarenullunless a dated special-price window is configured.quantityis the summed inventory across all sources.
The following fields are detail-only and always come back null on the listing — fetch them from the single-product endpoint GET /api/admin/catalog/products/{id}:
taxCategoryId,manageStock,inStock- the relation blocks:
translations,images,categories,inventories,customerGroupPrices,superAttributes,variants,bundleOptions,linkedProducts,downloadableLinks,downloadableSamples,videos,channels,relatedProducts,upSells,crossSells.
Example Request
curl -X GET "https://your-domain.com/api/admin/catalog/products?per_page=10&page=1&type=simple&status=1" \
-H "Authorization: Bearer <token>" \
-H "Accept: application/json"Example Response
{
"data": [
{
"id": 22,
"sku": "bagistoNGRY3424234KJCKJK",
"name": "Acme Drawstring Bag",
"type": "simple",
"status": 1,
"price": "3000.0000",
"formattedPrice": "$3,000.00",
"specialPrice": "2700.0000",
"formattedSpecialPrice": "$2,700.00",
"specialPriceFrom": null,
"specialPriceTo": null,
"quantity": 98,
"baseImageUrl": "http://localhost:8000/storage/product/22/1qfyoglc5BP46kofrxYrkJ2MXRxu9lAVG3BDFlTZ.webp",
"imagesCount": 1,
"categoryId": null,
"categoryName": null,
"channel": "default",
"locale": "en",
"attributeFamilyId": 1,
"attributeFamilyName": "Default",
"urlKey": "acme-drawstring-bag",
"visibleIndividually": true,
"shortDescription": "Many desktop publishing packages and web page editors now use",
"metaTitle": "",
"metaDescription": "",
"metaKeywords": "",
"weight": 32,
"featured": true,
"new": true,
"createdAt": "2024-04-19 11:56:43",
"updatedAt": "2026-04-23 16:36:14"
}
],
"meta": {
"currentPage": 1,
"perPage": 10,
"lastPage": 27,
"total": 265,
"from": 1,
"to": 10
}
}Sorting
Two forms are accepted — choose whichever suits your client:
| Form | Example |
|---|---|
Compound sort param | ?sort=name-asc |
Separate sort + order params | ?sort=name&order=asc |
When both order and a compound sort value are present, the explicit order param takes precedence.
Sortable columns:
sort value | Sorts by |
|---|---|
product_id | Product ID (default) |
name | Product name |
sku | SKU |
price | Price |
quantity | Inventory quantity (SUM across sources) |
status | Enabled/disabled status |
type | Product type |
attribute_family | Attribute family ID |
channel | Channel code |
Pagination
- Default page size: 10 items
- Maximum page size: 50 items
- Use
?page=Nfor page navigation and?per_page=Nto control page size
Errors
| HTTP Status | Cause |
|---|---|
401 Unauthorized | Missing, expired, or revoked admin Bearer token |
401 Unauthorized | Missing or invalid admin Bearer token |
Unknown filter parameters (e.g. a misspelled ?tpye=simple) are silently ignored — no error is returned. Invalid status or type values outside their documented ranges are also silently dropped (the filter is not applied).
Notes
- Elasticsearch is not yet supported. Even when the Bagisto admin panel is configured to use Elasticsearch for catalog search, this endpoint always uses the database query path.
- No automatic status filter. Unlike
GET /api/shop/productswhich only returnsstatus = 1products, this endpoint returns all statuses by default. Admin operators need to see disabled and draft products. Pass?status=1to restrict to enabled products. - Multi-category products — only the first associated category's
categoryIdandcategoryNameare included in the row (matching the datagrid display). - Products with no inventory return
quantity: 0. - Products with no images return
baseImageUrl: nullandimagesCount: 0.

