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.
- Base URL:
https://api.softstore.app/api/v2 - Default currency:
RUB - Service categories starting with
700are blocked for reseller API. - Seller API v1 remains unchanged and available from the switcher.
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
- 401 for missing or invalid token.
- 403 for self-purchase, blocked service categories, private orders/chats or H2H disabled.
- 404 for missing product, order or chat.
- 409 for inactive product, insufficient balance, insufficient stock or unavailable purchase state.
- 422 for validation errors.
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
| Name | In | Type | Required | Description |
|---|---|---|---|---|
X-API-KEY | header | string | yes | Existing 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": {}
}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": {}
}Search public marketplace products available to resellers with filters, sorting and pagination.
Search public marketplace products available to resellers with filters, sorting and pagination.
Parameters
| Name | In | Type | Required | Description |
|---|---|---|---|---|
q | query | string | no | Search phrase by product title and description. |
category_id | query | integer | no | Filter by public category id. |
seller_id | query | integer | no | Filter by seller id. |
min_price / max_price | query | number | no | Price range in RUB. |
availability | query | string | no | Availability filter, for example in_stock. |
sort | query | string | no | Sort mode, for example price or newest. |
page / limit | query | integer | no | Pagination controls. Keep limit conservative for stable responses. |
Request Example
curl "https://api.softstore.app/api/v2/search?q=license&limit=50" \
-H "Authorization: Bearer ACCESS_TOKEN"<?php
$token = 'ACCESS_TOKEN';
$ch = curl_init('https://api.softstore.app/api/v2/search?q=license&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/search?q=license&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": "Windows 11 Pro Key", "price": 500, "currency": "RUB" }],
"meta": { "page": 1, "limit": 50, "total": 1 }
}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
| Name | In | Type | Required | Description |
|---|---|---|---|---|
seller_id | path | integer | yes | Public seller identifier. |
page / limit | query | integer | no | Pagination 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 }
}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
| Name | In | Type | Required | Description |
|---|---|---|---|---|
product_id | path | string | yes | SoftStore 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": {}
}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
| Name | In | Type | Required | Description |
|---|---|---|---|---|
product_id | body | string | yes | Product identifier to buy. |
quantity | body | integer | yes | Units to purchase. Must be positive and available in stock. |
comment | body | string | conditional | Buyer 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": {}
}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
| Name | In | Type | Required | Description |
|---|---|---|---|---|
product_id | body | string | yes | Product identifier linked to the Gift. |
quantity / count | body | integer | no | Must 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": {}
}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
| Name | In | Type | Required | Description |
|---|---|---|---|---|
status | query | string | no | Order status filter, for example paid, unpaid, dispute. |
seller_id | query | integer | no | Filter by seller. |
product_id | query | string | no | Filter by product. |
date_from / date_to | query | date | no | Date interval in YYYY-MM-DD format. |
page / limit | query | integer | no | Pagination 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 }
}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
| Name | In | Type | Required | Description |
|---|---|---|---|---|
order_id | path | string | yes | Order 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": {}
}Lists reseller favorites.
Lists reseller favorites. Use POST on the same endpoint to add, remove or toggle a product in favorites.
Parameters
| Name | In | Type | Required | Description |
|---|---|---|---|---|
product_id | body | string | POST only | Product identifier. |
action | body | string | POST only | One 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": {}
}Returns moderated public comments for a product.
Returns moderated public comments for a product. Useful before purchase and for storefront product detail pages.
Parameters
| Name | In | Type | Required | Description |
|---|---|---|---|---|
product_id | path | string | yes | Product 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": {}
}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
| Name | In | Type | Required | Description |
|---|---|---|---|---|
chat_id | path | string | yes | Chat 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": {}
}Sends a buyer-side message to a reseller-owned order chat.
Sends a buyer-side message to a reseller-owned order chat.
Parameters
| Name | In | Type | Required | Description |
|---|---|---|---|---|
chat_id | path | string | yes | Chat identifier. |
message | body | string | yes | Message 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": {}
}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
| Name | In | Type | Required | Description |
|---|---|---|---|---|
order_id | body | string | yes | Order identifier. |
action | body | string | yes | open or close. |
message | body | string | no | Reason 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": {}
}