API reference / Products

Create a new product

POST/open/v1/productsScope: catalog:write

Service Endpoint Seller token required

EnvironmentBase URL + Path
Productionhttps://open.mallplus.ph/open/v1/products
Sandboxhttps://sandbox.open.mallplus.ph/open/v1/products
Common Signing and Seller Headers
HeaderTypeRequiredRulesDescription
X-MallPlus-Partner-IdstringYesIssued client ID for the calling app.Identifies the partner app whose secret signs the request.
X-MallPlus-TimestampintegerYesUnix timestamp in seconds; default acceptance window is 90 seconds.Prevents replay outside the allowed signing window.
X-MallPlus-Signature-VersionstringYesUse 3 for HMAC v3.Selects the request signing algorithm.
X-MallPlus-NoncestringYes32-64 lowercase hexadecimal characters, unique per request.Replay-protection nonce included in the v3 signing base string.
X-MallPlus-SignaturestringYesHMAC-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-TokenstringYesRequired when the operation says seller token required.Seller OAuth access token returned by the authorization flow.
X-MallPlus-Seller-IdstringYesRequired when X-MallPlus-Access-Token is required.Seller ID bound to the seller OAuth token.

Parameters

This operation does not define path or query parameters in OpenAPI.

Request Body required

FieldTypeRequiredRulesDescription
titlestringYesMin length: 8; Max length: 100Product title, 8-100 characters.
descriptionstringNoMax length: 10000Human-readable description.
categorystringYesMin length: 1; Max length: 120Category id. Must be a LEAF category (one with no active children) — a parent category is rejected. The mandatory attributes for the chosen category are discoverable via GET /open/v1/categories/{id}/attributes.
imagesarray<string<uri>>YesMin items: 1; Max items: 20Product image URLs. At least one HTTPS URL is required.
images[]string<uri>NoFormat: uri; Max length: 2048; Pattern: ^https://-
weightnumberNo-Shipping weight in GRAMS. Required unless use_variant_dimensions is true.
lengthnumberNo-Parcel length in CENTIMETRES. Required unless use_variant_dimensions is true.
widthnumberNo-Parcel width in CENTIMETRES. Required unless use_variant_dimensions is true.
heightnumberNo-Parcel height in CENTIMETRES. Required unless use_variant_dimensions is true.
use_variant_dimensionsbooleanNo-Ship by variant. When true, weight and dimensions are required on EVERY variant instead of on the product, and the product-level figures are derived from them.
attribute_valuesarray<object>NoMax items: 50Category-mapped attribute values. Which attributes are mandatory, and the allowed values for SELECT/MULTIVALUE types, come from the category — fetch them from GET /open/v1/categories/{id}/attributes.
attribute_values[]objectNoNo additional properties-
attribute_values[].attribute_idstringYesMin length: 1; Max length: 255Attribute id value.
attribute_values[].valueoneOfYes-Value details.
variantsarray<ProductVariantCreateRequest>YesMin items: 1; Max items: 100Product variants.
variants[]ProductVariantCreateRequestNoNo additional propertiesA product variant to create with its price, stock, and option values. Supply options as the variant axis values (for example {"Colour":"Red","Size":"M"}); the option groups they belong to are what the product detail page renders its selectors from, so a variant set with no option values renders as a single un-selectable listing. Physical attributes are required on each variant only when the product sets use_variant_dimensions: true.
variants[].titlestringNoMin length: 1; Max length: 200Partner-visible title.
variants[].skustringNoMin length: 1; Max length: 100Seller SKU.
variants[].priceintegerYesMinimum: 0; Maximum: 99999999Integer amount in PHP centavos.
variants[].stockintegerYesMinimum: 0; Maximum: 1000000000Stock count for the primary variant.
variants[].optionsobjectNo-Variant axis values keyed by option-group name. Required for correct PDP rendering when the product has more than one variant.
variants[].imagesarray<string<uri>>NoMax items: 20Variant-specific image URLs. Falls back to the product images when omitted.
variants[].images[]string<uri>NoFormat: uri; Max length: 2048; Pattern: ^https://-
variants[].weightnumberNo-Variant weight in GRAMS. Required when the product sets use_variant_dimensions: true.
variants[].lengthnumberNo-Variant length in CENTIMETRES. Required when the product sets use_variant_dimensions: true.
variants[].widthnumberNo-Variant width in CENTIMETRES. Required when the product sets use_variant_dimensions: true.
variants[].heightnumberNo-Variant height in CENTIMETRES. Required when the product sets use_variant_dimensions: true.

Response Parameters

FieldTypeRulesDescription
successboolean-Whether the request completed successfully.
dataProductNo additional propertiesResponse or event payload for this schema.
data.product_idstring-Product ID associated with this value.
data.short_idstring-Human-friendly alternate product identifier
data.namestring-Partner-visible name.
data.descriptionstring-Human-readable description.
data.statusenumAllowed: live, unlisted, delisted, proposed, under_review, archivedCurrent 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). Every value here is also accepted by GET /open/v1/products?status=.
data.skustring-SKU of the primary variant
data.priceinteger-Integer amount in PHP centavos.
data.stockinteger-Stock of the primary variant
data.categorystring-Product category.
data.thumbnailstring-Product thumbnail image URL.
data.imagesarray<string>-Product image URLs, in display order.
data.images[]string-Publicly reachable https image URL.
data.weightnumber-Weight in grams
data.dimensionsobjectNo additional propertiesPackage dimensions in centimetres.
data.dimensions.lengthnumber-Package length in centimetres.
data.dimensions.widthnumber-Package width in centimetres.
data.dimensions.heightnumber-Package height in centimetres.
data.variantsarray<ProductVariant>-Product variants.
data.variants[]ProductVariantNo additional propertiesA single purchasable variant of a product.
data.variants[].variant_idstring-Product variant ID associated with this value.
data.variants[].skustringNullableSeller SKU.
data.variants[].priceintegerNullableInteger amount in PHP centavos.
data.variants[].stock_quantityintegerNullableAvailable stock on hand at the default location
data.variants[].optionsarray<object>-Variant option values (e.g. Size=M, Color=Black).
data.variants[].options[]objectNo additional propertiesOne option of the variant, as a name/value pair.
data.variants[].options[].namestringNullableOption name, for example Size.
data.variants[].options[].valuestringNullableOption value, for example M.
data.variants[].dimensionsobjectNo additional propertiesPackage dimensions in centimetres.
data.variants[].dimensions.lengthnumber-Package length in centimetres.
data.variants[].dimensions.widthnumber-Package width in centimetres.
data.variants[].dimensions.heightnumber-Package height in centimetres.
data.variants[].weightnumber-Weight in grams
data.variants[].imagesarray<string>-Variant image URLs, in display order.
data.variants[].images[]string-Publicly reachable https image URL.
data.options_orderarray<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[]objectNo additional properties-
data.options_order[].titlestring-Option group name, e.g. Colour.
data.options_order[].valuesarray<string>-The group's values, in display order.
data.options_order[].values[]string--
data.created_atstring<date-time>Format: date-timeCreated at as an ISO-8601 timestamp.
data.updated_atstring<date-time>Format: date-timeUpdated at as an ISO-8601 timestamp.

Error Codes

HTTP StatusSchemaDescription
400ErrorResponseValidation error, or a missing/malformed required signing header (BAD_REQUEST)
401ErrorResponseUnauthorized — invalid credentials, invalid signature, or expired timestamp (TIMESTAMP_EXPIRED)
403ErrorResponseForbidden — insufficient scope
409ErrorResponseThe request conflicts with the current resource state or reuses an idempotency key
413ErrorResponseThe request body exceeds the endpoint payload limit
429ErrorResponseThe partner or endpoint rate limit has been exceeded
502ErrorResponseThe upstream commerce service rejected the request or returned an invalid response
503ErrorResponseA required platform or upstream dependency is temporarily unavailable
504ErrorResponseThe upstream commerce service did not respond before the platform timeout

Machine-readable codes are returned in error.code: ACCOUNT_LOCKED, APPROVE_FAILED, APP_LIMIT_REACHED, APP_NOT_FOUND, AUTHORIZATION_CODE_EXPIRED, AUTHORIZATION_REVOKED, AUTH_CODE_EXPIRED, AUTH_CODE_USED, BAD_REQUEST, CANCELLATION_ALREADY_PROCESSED, CANCELLATION_DEADLINE_EXCEEDED, CANCEL_FAILED, CANNOT_DELETE_ACCOUNT_WITH_APPS, CONCURRENT_MODIFICATION, CONFLICT, CREATE_FAILED, DISPUTE_FAILED, DUPLICATE, EMAIL_ALREADY_EXISTS, EMAIL_NOT_VERIFIED, FILE_TOO_LARGE, FORBIDDEN, HMAC_VERSION_DEPRECATED, IDEMPOTENCY_KEY_IN_PROGRESS, IDEMPOTENCY_KEY_REQUIRED, IDEMPOTENCY_KEY_REUSED, INTERNAL_ERROR, INVALID_AUTHORIZATION_CODE, INVALID_CREDENTIALS, INVALID_DEVELOPER_TYPE, INVALID_FILE_CONTENT, INVALID_FILE_TYPE, INVALID_JSON, INVALID_NONCE, INVALID_PATH, INVALID_PICKUP_DATE, INVALID_REFRESH_TOKEN, INVALID_REQUEST, INVALID_SIGNATURE, INVALID_STATE, INVALID_TRANSITION, INVALID_VERIFICATION_TOKEN, MAINTENANCE, MEMBER_PERMISSION_DENIED, MISSING_NONCE, NONCE_REUSED, NOT_FOUND, NOT_IMPLEMENTED, ORDER_NOT_CANCELLABLE, PAYLOAD_TOO_LARGE, PICKUP_DATES_UNAVAILABLE, PRODUCT_HAS_ACTIVE_ORDERS, PRODUCT_UNDER_REVIEW, PROFILE_ALREADY_SUBMITTED, PROFILE_TYPE_MISMATCH, PROXY_ERROR, RATE_LIMITED, REDIRECT_URL_MISMATCH, REFRESH_TOKEN_EXPIRED, REFRESH_TOKEN_REUSED, REJECT_FAILED, RETURN_ALREADY_PROCESSED, RETURN_DEADLINE_EXCEEDED, RE_AUTHORIZATION_REQUIRED, SANDBOX_LIMIT_REACHED, SELLER_TOKEN_REQUIRED, SERVICE_UNAVAILABLE, SESSION_EXPIRED, SHIPMENT_ALREADY_ARRANGED, SHIPMENT_NOT_ARRANGED, SHIPPING_LABEL_UNAVAILABLE, SHIP_FAILED, SIGNATURE_REPLAYED, SSRF_CHECK_FAILED, TEST_SHOP_LIMIT_REACHED, TIMESTAMP_EXPIRED, TOKEN_REVOKED, TOO_MANY_REQUESTS, UNAUTHORIZED, UPLOAD_ERROR, UPLOAD_NOT_CONFIGURED, UPSTREAM_ERROR, UPSTREAM_TIMEOUT, VALIDATION_ERROR, VERIFICATION_LINK_USED, VERIFICATION_TOKEN_EXPIRED, WEBHOOK_SUBSCRIPTION_EXISTS

Request Example

curl -X POST "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" \
  -H "Content-Type: application/json" \
  --data '{
  "title": "example_title",
  "description": "example_description",
  "category": "example_category",
  "images": [
    "https://example.com/resource"
  ],
  "weight": 1,
  "length": 1,
  "width": 1,
  "height": 1,
  "use_variant_dimensions": true,
  "attribute_values": [
    {
      "attribute_id": "attribute_id_123",
      "value": "example_value"
    }
  ],
  "variants": [
    {
      "title": "example_title",
      "sku": "example_sku",
      "price": 0,
      "stock": 0,
      "options": {},
      "images": [
        "https://example.com/resource"
      ],
      "weight": 1,
      "length": 1,
      "width": 1,
      "height": 1
    }
  ]
}'

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",
    "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": [
          {
            "name": "string",
            "value": "string"
          }
        ],
        "dimensions": {
          "length": 1,
          "width": 1,
          "height": 1
        },
        "weight": 1,
        "images": [
          "example_images"
        ]
      }
    ],
    "options_order": [
      {
        "title": "example_title",
        "values": [
          "example_values"
        ]
      }
    ],
    "created_at": "2026-08-17T00:00:00Z",
    "updated_at": "2026-08-17T00:00:00Z"
  }
}