SoftStore Reseller API v2

Buyer/reseller REST API

Reseller API v2 is separate from Seller API v1. Use it to search public SoftStore products, buy from reseller balance, read buyer-side history, chats, favorites and order delivery status.

Authentication

Exchange an existing SoftStore seller API key for a Bearer token.

curl -X POST https://api.softstore.app/api/v2/auth/api-key/create \
  -H "X-API-KEY: YOUR_API_KEY"

Use protected methods with Authorization: Bearer ACCESS_TOKEN.

JSON Response Format

Success
{
  "ok": true,
  "data": {},
  "meta": {}
}
Error
{
  "ok": false,
  "code": "invalid_request",
  "message": "Human readable message",
  "error": {
    "code": "invalid_request",
    "details": {}
  }
}

API v2 returns one human-readable error message in the top-level message field. The nested error object is kept only for structured fields such as code and details. PHP SDK methods return this error as a regular array and Node.js SDK methods return it as a regular object, so 4xx API responses do not become fatal runtime errors.

Security Rules and Errors

POST/auth/api-key/create

Exchange the existing Seller API key for a short-lived Bearer token used by every protected Reseller API v2 method.

›

Exchange the existing Seller API key for a short-lived Bearer token used by every protected Reseller API v2 method.

Parameters

NameInTypeRequiredDescription
X-API-KEYheaderstringyesExisting SoftStore Seller API key.

Request Example

curl -X POST https://api.softstore.app/api/v2/auth/api-key/create \
  -H "X-API-KEY: YOUR_API_KEY"
<?php
$ch = curl_init('https://api.softstore.app/api/v2/auth/api-key/create');
curl_setopt_array($ch, [CURLOPT_RETURNTRANSFER => true, CURLOPT_POST => true, CURLOPT_HTTPHEADER => ['X-API-KEY: YOUR_API_KEY']]);
echo curl_exec($ch);
const res = await fetch('https://api.softstore.app/api/v2/auth/api-key/create', { method: 'POST', headers: { 'X-API-KEY': 'YOUR_API_KEY' } });
console.log(await res.json());

Response Example

{
  "ok": true,
  "data": { "access_token": "ACCESS_TOKEN", "token_type": "Bearer" },
  "meta": {}
}
GET/balance

Returns the current reseller balance and default currency.

›

Returns the current reseller balance and default currency. Use it before buy requests to prevent insufficient-balance errors.

Request Example

curl "https://api.softstore.app/api/v2/balance" \
  -H "Authorization: Bearer ACCESS_TOKEN"
<?php
$token = 'ACCESS_TOKEN';
$ch = curl_init('https://api.softstore.app/api/v2/balance');
curl_setopt_array($ch, [
    CURLOPT_RETURNTRANSFER => true,
    CURLOPT_CUSTOMREQUEST => 'GET',
    CURLOPT_HTTPHEADER => ['Authorization: Bearer ' . $token],
]);
echo curl_exec($ch);
const token = 'ACCESS_TOKEN';
const res = await fetch('https://api.softstore.app/api/v2/balance', {
  method: 'GET',
  headers: { Authorization: `Bearer ${token}` }
});
const data = await res.json();
console.log(data);

Response Example

{
  "ok": true,
  "data": { "balance": 7200, "currency": "RUB" },
  "meta": {}
}
GET/products/123

Returns a paginated public catalog for one seller.

›

Returns a paginated public catalog for one seller. Use this for storefront sync and seller-specific product browsing.

Parameters

NameInTypeRequiredDescription
seller_idpathintegeryesPublic seller identifier.
page / limitqueryintegernoPagination controls.

Request Example

curl "https://api.softstore.app/api/v2/products/123?page=1&limit=50" \
  -H "Authorization: Bearer ACCESS_TOKEN"
<?php
$token = 'ACCESS_TOKEN';
$ch = curl_init('https://api.softstore.app/api/v2/products/123?page=1&limit=50');
curl_setopt_array($ch, [
    CURLOPT_RETURNTRANSFER => true,
    CURLOPT_CUSTOMREQUEST => 'GET',
    CURLOPT_HTTPHEADER => ['Authorization: Bearer ' . $token],
]);
echo curl_exec($ch);
const token = 'ACCESS_TOKEN';
const res = await fetch('https://api.softstore.app/api/v2/products/123?page=1&limit=50', {
  method: 'GET',
  headers: { Authorization: `Bearer ${token}` }
});
const data = await res.json();
console.log(data);

Response Example

{
  "ok": true,
  "data": [{ "product_id": "10001", "name": "Product", "count": 25 }],
  "meta": { "page": 1, "limit": 50 }
}
GET/product/PRODUCT_ID

Returns full public product data including price, stock, seller fields, text description, delivery flags and bulk discount data when available.

›

Returns full public product data including price, stock, seller fields, text description, delivery flags and bulk discount data when available.

Parameters

NameInTypeRequiredDescription
product_idpathstringyesSoftStore product identifier.

Request Example

curl "https://api.softstore.app/api/v2/product/PRODUCT_ID" \
  -H "Authorization: Bearer ACCESS_TOKEN"
<?php
$token = 'ACCESS_TOKEN';
$ch = curl_init('https://api.softstore.app/api/v2/product/PRODUCT_ID');
curl_setopt_array($ch, [
    CURLOPT_RETURNTRANSFER => true,
    CURLOPT_CUSTOMREQUEST => 'GET',
    CURLOPT_HTTPHEADER => ['Authorization: Bearer ' . $token],
]);
echo curl_exec($ch);
const token = 'ACCESS_TOKEN';
const res = await fetch('https://api.softstore.app/api/v2/product/PRODUCT_ID', {
  method: 'GET',
  headers: { Authorization: `Bearer ${token}` }
});
const data = await res.json();
console.log(data);

Response Example

{
  "ok": true,
  "data": { "product_id": "PRODUCT_ID", "name": "Product", "price": 999, "count": 10, "h2h": 1 },
  "meta": {}
}
POST/buy

Creates a buyer-side order from reseller balance.

›

Creates a buyer-side order from reseller balance. The method validates stock, H2H availability, seller restrictions and blocked categories before charging balance. If the product has comment_status=1, pass a valid comment. When product regex is configured, the complete comment must match it; otherwise API returns 422 comment_regex_mismatch.

Parameters

NameInTypeRequiredDescription
product_idbodystringyesProduct identifier to buy.
quantitybodyintegeryesUnits to purchase. Must be positive and available in stock.
commentbodystringconditionalBuyer activation data, max 200 chars. Required when product comment_status is enabled. HTML/script/control chars are rejected.

Request Example

curl -X POST "https://api.softstore.app/api/v2/buy" \
  -H "Authorization: Bearer ACCESS_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{"product_id":"PRODUCT_ID","quantity":1,"comment":"buyer_login@example.com"}'
<?php
$token = 'ACCESS_TOKEN';
$payload = ['product_id' => 'PRODUCT_ID', 'quantity' => 1, 'comment' => 'buyer_login@example.com'];
$ch = curl_init('https://api.softstore.app/api/v2/buy');
curl_setopt_array($ch, [
    CURLOPT_RETURNTRANSFER => true,
    CURLOPT_CUSTOMREQUEST => 'POST',
    CURLOPT_HTTPHEADER => [
        'Authorization: Bearer ' . $token,
        'Content-Type: application/json',
    ],
    CURLOPT_POSTFIELDS => json_encode($payload),
]);
echo curl_exec($ch);
const token = 'ACCESS_TOKEN';
const res = await fetch('https://api.softstore.app/api/v2/buy', {
  method: 'POST',
  headers: { Authorization: `Bearer ${token}`, 'Content-Type': 'application/json' },
  body: JSON.stringify({ product_id: 'PRODUCT_ID', quantity: 1, comment: 'buyer_login@example.com' })
});
const data = await res.json();
console.log(data);

Response Example

{
  "ok": true,
  "data": { "order_id": "123", "product_id": "PRODUCT_ID", "quantity": 1, "total": 999, "currency": "RUB", "h2h": 1 },
  "meta": {}
}
POST/gift

Creates a Gift code for a product from reseller balance.

›

Creates an H2H Gift purchase. The product must be active, moderated, in stock, H2H-deliverable and have gift_available=1. First release limitation: quantity/count must be 1. The successful response contains gift_code; the same code is sent to the order chat and buyer email.

Parameters

NameInTypeRequiredDescription
product_idbodystringyesProduct identifier linked to the Gift.
quantity / countbodyintegernoMust be 1 in the first release.

Request Example

curl -X POST "https://api.softstore.app/api/v2/gift" \
  -H "Authorization: Bearer ACCESS_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{"product_id":"PRODUCT_ID","quantity":1}'
<?php
$token = 'ACCESS_TOKEN';
$payload = ['product_id' => 'PRODUCT_ID', 'quantity' => 1];
$ch = curl_init('https://api.softstore.app/api/v2/gift');
curl_setopt_array($ch, [
    CURLOPT_RETURNTRANSFER => true,
    CURLOPT_CUSTOMREQUEST => 'POST',
    CURLOPT_HTTPHEADER => [
        'Authorization: Bearer ' . $token,
        'Content-Type: application/json',
    ],
    CURLOPT_POSTFIELDS => json_encode($payload),
]);
echo curl_exec($ch);
const token = 'ACCESS_TOKEN';
const res = await fetch('https://api.softstore.app/api/v2/gift', {
  method: 'POST',
  headers: { Authorization: `Bearer ${token}`, 'Content-Type': 'application/json' },
  body: JSON.stringify({ product_id: 'PRODUCT_ID', quantity: 1 })
});
const data = await res.json();
console.log(data);

Response Example

{
  "ok": true,
  "data": { "order_id": "ORDER_ID", "product_id": "PRODUCT_ID", "quantity": 1, "total": 999, "currency": "RUB", "h2h": 1, "gift": 1, "gift_code": "GIFT-0123456789ABCDEF" },
  "meta": {}
}
GET/history

Lists reseller buyer-side orders with filters for reconciliation, customer support and storefront order status sync.

›

Lists reseller buyer-side orders with filters for reconciliation, customer support and storefront order status sync.

Parameters

NameInTypeRequiredDescription
statusquerystringnoOrder status filter, for example paid, unpaid, dispute.
seller_idqueryintegernoFilter by seller.
product_idquerystringnoFilter by product.
date_from / date_toquerydatenoDate interval in YYYY-MM-DD format.
page / limitqueryintegernoPagination controls.

Request Example

curl "https://api.softstore.app/api/v2/history?status=paid&limit=50" \
  -H "Authorization: Bearer ACCESS_TOKEN"
<?php
$token = 'ACCESS_TOKEN';
$ch = curl_init('https://api.softstore.app/api/v2/history?status=paid&limit=50');
curl_setopt_array($ch, [
    CURLOPT_RETURNTRANSFER => true,
    CURLOPT_CUSTOMREQUEST => 'GET',
    CURLOPT_HTTPHEADER => ['Authorization: Bearer ' . $token],
]);
echo curl_exec($ch);
const token = 'ACCESS_TOKEN';
const res = await fetch('https://api.softstore.app/api/v2/history?status=paid&limit=50', {
  method: 'GET',
  headers: { Authorization: `Bearer ${token}` }
});
const data = await res.json();
console.log(data);

Response Example

{
  "ok": true,
  "data": [{ "order_id": "123", "status": "paid", "total": 999 }],
  "meta": { "page": 1, "limit": 50 }
}
GET/order/ORDER_ID

Returns one reseller-owned order with current status, delivery data, dispute fields and linked chat identifiers when available.

›

Returns one reseller-owned order with current status, delivery data, dispute fields and linked chat identifiers when available.

Parameters

NameInTypeRequiredDescription
order_idpathstringyesOrder identifier returned by /buy or /history.

Request Example

curl "https://api.softstore.app/api/v2/order/ORDER_ID" \
  -H "Authorization: Bearer ACCESS_TOKEN"
<?php
$token = 'ACCESS_TOKEN';
$ch = curl_init('https://api.softstore.app/api/v2/order/ORDER_ID');
curl_setopt_array($ch, [
    CURLOPT_RETURNTRANSFER => true,
    CURLOPT_CUSTOMREQUEST => 'GET',
    CURLOPT_HTTPHEADER => ['Authorization: Bearer ' . $token],
]);
echo curl_exec($ch);
const token = 'ACCESS_TOKEN';
const res = await fetch('https://api.softstore.app/api/v2/order/ORDER_ID', {
  method: 'GET',
  headers: { Authorization: `Bearer ${token}` }
});
const data = await res.json();
console.log(data);

Response Example

{
  "ok": true,
  "data": { "order_id": "ORDER_ID", "status": "paid", "delivery_text": "...", "chat_id": "CHAT_ID" },
  "meta": {}
}
GET/favorites

Lists reseller favorites.

›

Lists reseller favorites. Use POST on the same endpoint to add, remove or toggle a product in favorites.

Parameters

NameInTypeRequiredDescription
product_idbodystringPOST onlyProduct identifier.
actionbodystringPOST onlyOne of add, remove or toggle.

Request Example

curl "https://api.softstore.app/api/v2/favorites" \
  -H "Authorization: Bearer ACCESS_TOKEN"
<?php
$token = 'ACCESS_TOKEN';
$ch = curl_init('https://api.softstore.app/api/v2/favorites');
curl_setopt_array($ch, [
    CURLOPT_RETURNTRANSFER => true,
    CURLOPT_CUSTOMREQUEST => 'GET',
    CURLOPT_HTTPHEADER => ['Authorization: Bearer ' . $token],
]);
echo curl_exec($ch);
const token = 'ACCESS_TOKEN';
const res = await fetch('https://api.softstore.app/api/v2/favorites', {
  method: 'GET',
  headers: { Authorization: `Bearer ${token}` }
});
const data = await res.json();
console.log(data);

Response Example

{
  "ok": true,
  "data": [{ "product_id": "PRODUCT_ID", "name": "Product" }],
  "meta": {}
}
GET/comment/PRODUCT_ID

Returns moderated public comments for a product.

›

Returns moderated public comments for a product. Useful before purchase and for storefront product detail pages.

Parameters

NameInTypeRequiredDescription
product_idpathstringyesProduct identifier.

Request Example

curl "https://api.softstore.app/api/v2/comment/PRODUCT_ID" \
  -H "Authorization: Bearer ACCESS_TOKEN"
<?php
$token = 'ACCESS_TOKEN';
$ch = curl_init('https://api.softstore.app/api/v2/comment/PRODUCT_ID');
curl_setopt_array($ch, [
    CURLOPT_RETURNTRANSFER => true,
    CURLOPT_CUSTOMREQUEST => 'GET',
    CURLOPT_HTTPHEADER => ['Authorization: Bearer ' . $token],
]);
echo curl_exec($ch);
const token = 'ACCESS_TOKEN';
const res = await fetch('https://api.softstore.app/api/v2/comment/PRODUCT_ID', {
  method: 'GET',
  headers: { Authorization: `Bearer ${token}` }
});
const data = await res.json();
console.log(data);

Response Example

{
  "ok": true,
  "data": [{ "rating": 5, "text": "Fast delivery" }],
  "meta": {}
}
GET/chat/CHAT_ID

Reads messages for an order chat owned by the reseller.

›

Reads messages for an order chat owned by the reseller. Private chats for unrelated orders return forbidden or not found.

Parameters

NameInTypeRequiredDescription
chat_idpathstringyesChat identifier from order details.

Request Example

curl "https://api.softstore.app/api/v2/chat/CHAT_ID" \
  -H "Authorization: Bearer ACCESS_TOKEN"
<?php
$token = 'ACCESS_TOKEN';
$ch = curl_init('https://api.softstore.app/api/v2/chat/CHAT_ID');
curl_setopt_array($ch, [
    CURLOPT_RETURNTRANSFER => true,
    CURLOPT_CUSTOMREQUEST => 'GET',
    CURLOPT_HTTPHEADER => ['Authorization: Bearer ' . $token],
]);
echo curl_exec($ch);
const token = 'ACCESS_TOKEN';
const res = await fetch('https://api.softstore.app/api/v2/chat/CHAT_ID', {
  method: 'GET',
  headers: { Authorization: `Bearer ${token}` }
});
const data = await res.json();
console.log(data);

Response Example

{
  "ok": true,
  "data": [{ "message_id": "1", "from": "buyer", "message": "Hello" }],
  "meta": {}
}
POST/chat/CHAT_ID

Sends a buyer-side message to a reseller-owned order chat.

›

Sends a buyer-side message to a reseller-owned order chat.

Parameters

NameInTypeRequiredDescription
chat_idpathstringyesChat identifier.
messagebodystringyesMessage text.

Request Example

curl -X POST "https://api.softstore.app/api/v2/chat/CHAT_ID" \
  -H "Authorization: Bearer ACCESS_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{"message":"Hello"}'
<?php
$token = 'ACCESS_TOKEN';
$payload = ['message' => 'Hello'];
$ch = curl_init('https://api.softstore.app/api/v2/chat/CHAT_ID');
curl_setopt_array($ch, [
    CURLOPT_RETURNTRANSFER => true,
    CURLOPT_CUSTOMREQUEST => 'POST',
    CURLOPT_HTTPHEADER => [
        'Authorization: Bearer ' . $token,
        'Content-Type: application/json',
    ],
    CURLOPT_POSTFIELDS => json_encode($payload),
]);
echo curl_exec($ch);
const token = 'ACCESS_TOKEN';
const res = await fetch('https://api.softstore.app/api/v2/chat/CHAT_ID', {
  method: 'POST',
  headers: { Authorization: `Bearer ${token}`, 'Content-Type': 'application/json' },
  body: JSON.stringify({ message: 'Hello' })
});
const data = await res.json();
console.log(data);

Response Example

{
  "ok": true,
  "data": { "message_id": "2", "sent": true },
  "meta": {}
}
POST/dispute

Opens or closes a dispute for a reseller-owned order and attaches the message to the dispute workflow.

›

Opens or closes a dispute for a reseller-owned order and attaches the message to the dispute workflow.

Parameters

NameInTypeRequiredDescription
order_idbodystringyesOrder identifier.
actionbodystringyesopen or close.
messagebodystringnoReason or comment for the dispute.

Request Example

curl -X POST "https://api.softstore.app/api/v2/dispute" \
  -H "Authorization: Bearer ACCESS_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{"order_id":"ORDER_ID","action":"open","message":"Delivery issue"}'
<?php
$token = 'ACCESS_TOKEN';
$payload = ['order_id' => 'ORDER_ID', 'action' => 'open', 'message' => 'Delivery issue'];
$ch = curl_init('https://api.softstore.app/api/v2/dispute');
curl_setopt_array($ch, [
    CURLOPT_RETURNTRANSFER => true,
    CURLOPT_CUSTOMREQUEST => 'POST',
    CURLOPT_HTTPHEADER => [
        'Authorization: Bearer ' . $token,
        'Content-Type: application/json',
    ],
    CURLOPT_POSTFIELDS => json_encode($payload),
]);
echo curl_exec($ch);
const token = 'ACCESS_TOKEN';
const res = await fetch('https://api.softstore.app/api/v2/dispute', {
  method: 'POST',
  headers: { Authorization: `Bearer ${token}`, 'Content-Type': 'application/json' },
  body: JSON.stringify({ order_id: 'ORDER_ID', action: 'open', message: 'Delivery issue' })
});
const data = await res.json();
console.log(data);

Response Example

{
  "ok": true,
  "data": { "order_id": "ORDER_ID", "dispute": true, "status": "dispute" },
  "meta": {}
}