Skip to main content

Listing Management

The three listing types​

TypeEndpointWhat it meansCancellable via API
AskPOST /partner/list/askYou hold the item and ship it when it sellsYes, while pending
Pre-orderPOST /partner/list/preorderYou commit to sourcing it; quota units availableYes, while pending
R2SPOST /partner/batch/r2sItem is sent to the SASOM warehouse up front and ships from thereNo

GET /partner/live/listings/{type} reads them back, where {type} is ask, pre-order or r2s. Any other value returns 400 with the valid list.

Creating an ask listing​

curl -sS -X POST https://partners.sasomapi.com/partner/list/ask \
-u "$SASOM_API_KEY:$SASOM_API_SECRET" \
-H 'Content-Type: application/json' \
-d '{
"sku": "FZ5246-100",
"size": "10",
"price": 5500
}'
FieldTypeRequiredNotes
skustringYesMust exist in the SASOM catalog
sizestringNoMust be a valid size for the SKU. Defaults to ONE_SIZE
pricenumberYesTHB. Values below 50 are clamped to 50, not rejected
detailsobjectNoOverrides system-generated product details

Response, 201:

{ "status": "created", "order_id": "kR3mQp7xY2nB8vLc4dFg" }

There is no quantity field. One call creates one sellable unit. For several units of the same SKU + size, create several listings and keep all the order_id values, or use a pre-order with a quota.

Four ways this bites​

  1. Vacation mode returns 201 and creates nothing.

    { "status": "user is in vacation mode" }

    No order_id. Branch on order_id, not on the status code.

  2. Low prices are clamped silently. "price": 10 produces a 201 and a live listing at 50 THB. No warning, no error. Validate before sending.

  3. price is not type-checked. Send it as a number. A missing or non-numeric price is not rejected and produces an unusable listing that support has to clean up.

  4. Creates are not idempotent. A retry after a timeout creates a second listing. Before retrying, check GET /partner/live/listings/ask.

Getting the size right​

The valid sizes for a SKU are the keys of size_map from GET /partner/lowest/{sku}:

{
"size_map": {
"size_type": "US",
"9": { "ask": { "price": 4500 } },
"10": { "ask": { "price": 5200 } }
}
}

size_type is metadata (the size system), not a size. An invalid size returns:

{
"statusCode": 400,
"message": "Invalid size \"10.7\" for FZ5246-100. Valid sizes: 8, 8.5, 9, 9.5, 10, 10.5, 11"
}

That message is the authoritative list — cache it per SKU rather than guessing.

Creating a pre-order listing​

curl -sS -X POST https://partners.sasomapi.com/partner/list/preorder \
-u "$SASOM_API_KEY:$SASOM_API_SECRET" \
-H 'Content-Type: application/json' \
-d '{
"sku": "FZ5246-100",
"size": "10",
"price": 5500,
"quota": 5
}'

quota is the number of units you commit to sourcing. Same clamping and same vacation-mode behaviour as an ask listing.

Pre-order listings need your account's delivery duration configured. If it is not, every create fails with:

{ "statusCode": 400, "message": "Seller delivery duration is not configured" }

That is an account-provisioning issue, not a payload problem — contact your account manager. It is not something you can fix by changing the request.

Repricing​

# Ask listing
curl -sS -X PUT https://partners.sasomapi.com/partner/edit/listing \
-u "$SASOM_API_KEY:$SASOM_API_SECRET" \
-H 'Content-Type: application/json' \
-d '{"order_id": "kR3mQp7xY2nB8vLc4dFg", "price": 5200}'
{ "status": "success" }

Editable statuses: pending, r2s-processing, r2s-price-processing. Anything else returns {"statusCode":400,"message":"status not allowed status: matched"} — once an order is matched the price is fixed.

The edit floor is 100 THB, not 50. Below that it clamps to 100.

For pre-orders use PUT /partner/edit/preorder, which also takes size and quota, and requires status pending and type pre-order. Editing the price of a pre-order also updates its deposit amount.

Prices that are locked​

Two cases return 400 and are not payload errors — do not retry them:

{ "statusCode": 400, "message": "SMP enabled on: kR3mQp7xY2nB8vLc4dFg" }

Smart Market Price is managing this listing's price. Turn SMP off for the listing if you want manual control.

{
"statusCode": 400,
"message": "price edit not allowed: MR530SG is a Smart Price pilot SKU, R2S price is managed by Smart Price"
}

Your account is enrolled in the Smart Price programme and this SKU + size is in scope, so Smart Price owns the R2S price. This lock is scoped to the enrolled size — other sizes of the same SKU stay manually editable, and sellers outside the programme are unaffected. Treat it as a permanent "not yours to set" for that size, not a transient failure.

Cancelling​

curl -sS -X PUT https://partners.sasomapi.com/partner/cancel/listing \
-u "$SASOM_API_KEY:$SASOM_API_SECRET" \
-H 'Content-Type: application/json' \
-d '{"order_id": "kR3mQp7xY2nB8vLc4dFg"}'
{ "status": "success" }

Only pending and vacation listings can be cancelled. Two refusals:

{ "statusCode": 400, "message": "cannot cancel pre-verified listing" }

R2S listings cannot be cancelled through the API — the item is already in, or on its way to, the warehouse. Contact your account manager.

{ "statusCode": 400, "message": "status not allowed status: matched" }

The listing has sold. It is now an order — see Order Management.

R2S batches​

POST /partner/batch/r2s registers a shipment of items into the SASOM warehouse:

curl -sS -X POST https://partners.sasomapi.com/partner/batch/r2s \
-u "$SASOM_API_KEY:$SASOM_API_SECRET" \
-H 'Content-Type: application/json' \
-d '{
"parcel_quantity": 2,
"listings": [
{ "sku": "FZ5246-100", "size": "10", "price": 5500, "quantity": 1 },
{ "sku": "DZ5485-612", "size": "9", "price": 4200, "quantity": 1, "year": "2024" }
]
}'

The response echoes the batch, and every entry carries the batch_id you quote to the warehouse:

{
"status": "success",
"requested": [
{
"id": "...",
"sku": "FZ5246-100",
"size": "10",
"size_text": "US 10",
"price": 5500,
"quantity": 1,
"batch_id": "SMBB-partn-1757308800000",
"product": { "sku": "FZ5246-100", "brand": "Nike", "category": "sneakers", "name": "...", "thumbnail": "..." },
"year": ""
}
]
}

Store the batch_id. There is no endpoint to list your batches.

This endpoint trusts your payload

price, quantity and size are stored as sent — they are not validated against the product, and there is no upper bound on the size of listings. A wrong value becomes a warehouse intake record that has to be corrected by hand. Validate before sending:

  • price a positive THB number, quantity a positive integer
  • size present in the SKU's size_map from GET /partner/lowest/{sku}
  • a few hundred items per batch at most — a very large listings array fails the whole request with a 500 after the catalog lookups have already run

Two more things:

  • items_quantity counts entries, not units. The batch's expected item count is listings.length, ignoring each entry's quantity. Send one entry per physical unit if you want the warehouse's count to match what you ship.
  • No idempotency, no cancel. A retry creates a second batch. To void one, contact your account manager.

Rejections:

{ "success": false, "message": "sku not found" }
{ "success": false, "message": "sku: FZ5246-100 is not allowed for storage" }

The second means the SKU is on the storage blocklist. This is the only endpoint in the API whose error body has a success field.

Practices worth following​

  1. Persist order_id and batch_id. There is no lookup by SKU + size, and no way to list your batches. Lose the ID and you need support.
  2. Validate before sending. Prices clamp, R2S fields are not checked. Your validation is the only validation for those.
  3. Check order_id on every create. A 201 without one means nothing was created.
  4. Reprice from bulk data. Pull prices with POST /partner/lowest/bulk (100 SKUs per request), then issue only the edits that change something — at 200 requests/minute, one edit per listing per cycle is the budget you have to spend carefully.
  5. Treat the SMP and pilot-SKU locks as permanent. Retrying them wastes rate limit and never succeeds.