API reference / Products
List products with pagination
q is a case-insensitive partial match on product title only. It does not search SKU, description, or other fields — a SKU fragment can return meta.total: 0. Use GET /open/v1/inventory?sku= for an exact SKU.
Limited. This endpoint can be called, with the limitation described here. About availability tiers
Product listing is available with limited support for deep cursor traversal.
Workaround: Use returned pages as-is; contact MallPlus before relying on deep cursor traversal for high-volume sync.
Service Endpoint Seller token required
| Environment | Base URL + Path |
|---|---|
| Production | https://open.mallplus.ph/open/v1/products |
| Sandbox | https://sandbox.open.mallplus.ph/open/v1/products |
Common Signing and Seller Headers
| Header | Type | Required | Rules | Description |
|---|---|---|---|---|
| X-MallPlus-Partner-Id | string | Yes | Issued client ID for the calling app. | Identifies the partner app whose secret signs the request. |
| X-MallPlus-Timestamp | integer | Yes | Unix timestamp in seconds; default acceptance window is 90 seconds. | Prevents replay outside the allowed signing window. |
| X-MallPlus-Signature-Version | string | Yes | Use 3 for HMAC v3. | Selects the request signing algorithm. |
| X-MallPlus-Nonce | string | Yes | 32-64 lowercase hexadecimal characters, unique per request. | Replay-protection nonce included in the v3 signing base string. |
| X-MallPlus-Signature | string | Yes | HMAC-SHA256 over timestamp, client ID, method, path, canonical query, body hash, and nonce. | Cryptographic proof that the request was signed with the app secret. |
| X-MallPlus-Access-Token | string | Yes | Required when the operation says seller token required. | Seller OAuth access token returned by the authorization flow. |
| X-MallPlus-Seller-Id | string | Yes | Required when X-MallPlus-Access-Token is required. | Seller ID bound to the seller OAuth token. |
Parameters
| Name | In | Type | Required | Rules | Description |
|---|---|---|---|---|---|
| page | query | integer | No | Minimum: 1; Default: 1 | 1-based page number to return. |
| limit | query | integer | No | Minimum: 1; Maximum: 100; Default: 20 | Maximum number of records to return. |
| page_size | query | integer | No | Minimum: 1; Maximum: 100 | Requested page size. When omitted, the endpoint uses the standard limit value. |
| q | query | string | No | - | Case-insensitive partial match on product title only. Does not search SKU, description, or other fields — a SKU fragment can return meta.total: 0. Exact SKU lookup is GET /open/v1/inventory?sku=. |
| status | query | enum | No | Allowed: live, unlisted, delisted, proposed, under_review, archived, published, draft | Product status to include in the list. Accepts every status a product can be observed in — settable by the partner: live, unlisted, delisted; read-only, set by the platform: proposed, under_review, archived. Deprecated aliases accepted for compatibility: published (= live), draft (= unlisted). archived returns the products you deleted; on production it also returns products removed by MallPlus moderation, which read archived too but can still be edited. Without status, deleted products are left out. |
| category | query | string | No | - | Product category ID or category slug used to filter products. |
| sort | query | enum | No | Allowed: created_at_asc, created_at_desc, price_asc, price_desc | Product sort order. Supported values sort by creation time or price. |
| cursor | query | string | No | - | Pagination cursor returned by a previous response page as meta.nextCursor. |
Request Body
This operation has no JSON request body.
Response Parameters
Success status: HTTP 200
| Field | Type | Rules | Description |
|---|---|---|---|
| success | boolean | - | Whether the request completed successfully. |
| data | array<Product> | - | Response or event payload for this schema. |
| data[] | Product | No additional properties | Partner-safe product view. Supplier-internal fields are stripped at the API boundary. |
| data[].product_id | string | - | Product ID associated with this value. |
| data[].short_id | string | - | Human-friendly alternate product identifier |
| data[].name | string | - | Partner-visible name. |
| data[].description | string | - | Human-readable description. |
| data[].status | enum | Allowed: live, unlisted, delisted, proposed, under_review, archived | Current product status. This is the complete set — settable by the partner via POST /open/v1/products/{id}/status: live, unlisted, delisted; read-only, set by the platform: proposed, under_review, archived (proposed after create, under_review while in review, archived after delete; on production archived also marks a product removed by moderation). Every value here is also accepted by GET /open/v1/products?status=. |
| data[].sku | string | - | SKU of the primary variant |
| data[].price | integer | - | Integer amount in PHP centavos. |
| data[].stock | integer | - | Stock of the primary variant |
| data[].category | string | - | Display name of the category the product is filed under, or Other when it has none. Send category_id, not this name, on create and update. |
| data[].category_id | string | - | Id of the category the product is filed under — the value create and update take. Omitted when the product has no category. |
| data[].attribute_values | array<object> | - | Category attribute values stored on the product. Omitted when the product has none. name is present on the product detail read. |
| data[].attribute_values[] | object | - | - |
| data[].attribute_values[].attribute_id | string | - | Attribute id, as sent in the create attribute_values. |
| data[].attribute_values[].name | string | - | Attribute display name, e.g. Condition. |
| data[].attribute_values[].value | string | - | Stored value. |
| data[].thumbnail | string | - | Product thumbnail image URL. |
| data[].images | array<string> | - | Product image URLs, in display order. |
| data[].images[] | string | - | Publicly reachable https image URL. |
| data[].weight | number | - | Weight in grams |
| data[].dimensions | object | No additional properties | Package dimensions in centimetres. |
| data[].dimensions.length | number | - | Package length in centimetres. |
| data[].dimensions.width | number | - | Package width in centimetres. |
| data[].dimensions.height | number | - | Package height in centimetres. |
| data[].variants | array<ProductVariant> | - | Product variants. |
| data[].variants[] | ProductVariant | No additional properties | A single purchasable variant of a product. |
| data[].variants[].variant_id | string | - | Product variant ID associated with this value. |
| data[].variants[].sku | string | Nullable | Seller SKU. |
| data[].variants[].price | integer | Nullable | Integer amount in PHP centavos. |
| data[].variants[].stock_quantity | integer | Nullable | Available stock on hand at the default location |
| data[].variants[].options | array<object> | - | Variant option values (e.g. Size=M, Color=Black). |
| data[].variants[].options[] | object | No additional properties | One option of the variant, as a name/value pair. |
| data[].variants[].options[].name | string | Nullable | Option name, for example Size. |
| data[].variants[].options[].value | string | Nullable | Option value, for example M. |
| data[].variants[].dimensions | object | No additional properties | Package dimensions in centimetres. |
| data[].variants[].dimensions.length | number | - | Package length in centimetres. |
| data[].variants[].dimensions.width | number | - | Package width in centimetres. |
| data[].variants[].dimensions.height | number | - | Package height in centimetres. |
| data[].variants[].weight | number | - | Weight in grams |
| data[].variants[].images | array<string> | - | Variant image URLs, in display order. |
| data[].variants[].images[] | string | - | Publicly reachable https image URL. |
| data[].options_order | array<object> | - | Variant option groups in display order, each with its values in order — the order a storefront renders the variant picker in. Derived at create time from the order the options were submitted in; absent on products with no option groups. |
| data[].options_order[] | object | No additional properties | - |
| data[].options_order[].title | string | - | Option group name, e.g. Colour. |
| data[].options_order[].values | array<string> | - | The group's values, in display order. |
| data[].options_order[].values[] | string | - | - |
| data[].created_at | string<date-time> | Format: date-time | Created at as an ISO-8601 timestamp. |
| data[].updated_at | string<date-time> | Format: date-time | Updated at as an ISO-8601 timestamp. |
| meta | PaginationMeta | - | Response metadata, including pagination when the endpoint returns a list. |
| meta.page | integer | - | 1-based page number represented by this response page. Offset paging only — omitted during a cursor walk. |
| meta.limit | integer | - | Maximum number of records returned in this response page. |
| meta.total | integer | - | Total number of records matching the request filters. Offset paging only — omitted during a cursor walk, where no total is computed. |
| meta.nextCursor | string | - | Opaque cursor for the next page of a keyset walk. Present only while walking by cursor and only while more rows may remain; its absence ends the walk. Pass it back unchanged as cursor. |
Error Codes
| HTTP Status | Schema | Description |
|---|---|---|
| 400 | PlatformError400Response | Validation error, or a missing/malformed required signing header (BAD_REQUEST) |
| 401 | PlatformError401Response | Unauthorized — invalid credentials, invalid signature, or expired timestamp (TIMESTAMP_EXPIRED) |
| 403 | PlatformError403Response | Forbidden — insufficient scope |
| 429 | PlatformError429Response | The partner or endpoint rate limit has been exceeded |
| 502 | PlatformError502Response | The upstream commerce service rejected the request or returned an invalid response |
| 503 | PlatformError503Response | A required platform or upstream dependency is temporarily unavailable |
| 504 | PlatformError504Response | The upstream commerce service did not respond before the platform timeout |
This operation can return these codes in error.code: VALIDATION_ERROR
Any operation can also return the authentication, signing, scope, rate-limit and system codes listed in the Error code reference.
Request Example
# Sandbox: https://sandbox.open.mallplus.ph/open/v1/products
curl -X GET "https://open.mallplus.ph/open/v1/products" \
-H "X-MallPlus-Partner-Id: mp_partner_123" \
-H "X-MallPlus-Timestamp: 1786924800" \
-H "X-MallPlus-Signature-Version: 3" \
-H "X-MallPlus-Nonce: 4f8b9a0c4d5e6f708192a3b4c5d6e7f8" \
-H "X-MallPlus-Signature: <hex_hmac_sha256>" \
-H "X-MallPlus-Access-Token: seller_access_token" \
-H "X-MallPlus-Seller-Id: seller_123"Response Example
{
"success": true,
"data": [
{
"product_id": "product_id_123",
"short_id": "short_id_123",
"name": "example_name",
"description": "example_description",
"status": "live",
"sku": "example_sku",
"price": 1,
"stock": 1,
"category": "example_category",
"category_id": "category_id_123",
"attribute_values": [
{
"attribute_id": "attribute_id_123",
"name": "example_name",
"value": "example_value"
}
],
"thumbnail": "example_thumbnail",
"images": [
"example_images"
],
"weight": 1,
"dimensions": {
"length": 1,
"width": 1,
"height": 1
},
"variants": [
{
"variant_id": "variant_id_123",
"sku": "example_sku",
"price": 1,
"stock_quantity": 1,
"options": [
"object"
],
"dimensions": {
"length": "number",
"width": "number",
"height": "number"
},
"weight": 1,
"images": [
"string"
]
}
],
"options_order": [
{
"title": "example_title",
"values": [
"string"
]
}
],
"created_at": "2026-08-17T00:00:00Z",
"updated_at": "2026-08-17T00:00:00Z"
}
],
"meta": {
"page": 1,
"limit": 20,
"total": 150,
"nextCursor": "eyJ0cyI6IjIwMjYtMDgtMTVUMDk6MzA6MDAuMDAwWiIsImlkIjoicGNhdF8xIn0"
}
}