Arceto Marketplace API
Programmatic access to your Arceto seller account. Sync inventory, manage prices, fetch orders and submit shipments — all from your existing OMS or ERP.
Introduction
The Arceto Marketplace API is a JSON-over-HTTPS interface scoped to a single seller account. Every request is authenticated against your Client ID / Client Secret pair, and authorized via a short-lived bearer token. All endpoints return application/json.
Base URL:
https://www.arceto.com/api
Quick start
- Generate a Client ID and Client Secret in Seller Central → Settings → API Keys.
- Exchange them for an access token via
POST /api/token.php. - Send your token in the
AccessTokenheader to any other endpoint.
Authentication
Every API call (other than token.php) requires three request headers:
| Header | Required | Description |
|---|---|---|
SellerID | YES | Your numeric seller ID (vendor ID). |
Authorization | YES | Basic + base64(clientId:clientSecret). |
AccessToken | YES | The token returned by POST /api/token.php. |
Content-Type | YES | application/json for JSON bodies, or application/x-www-form-urlencoded for legacy form bodies. |
Exchange Basic credentials for an access token. Tokens are tied to a single seller and rotate on every request — store the latest one and re-issue when your client gets UNAUTHORIZED.
curl -X POST https://www.arceto.com/api/token.php \ -H "SellerID: 12345" \ -H "Authorization: Basic $(echo -n 'YOUR_CLIENT_ID:YOUR_CLIENT_SECRET' | base64)" \ -H "Content-Type: application/x-www-form-urlencoded"
<?php
$basic = base64_encode("YOUR_CLIENT_ID:YOUR_CLIENT_SECRET");
$ch = curl_init("https://www.arceto.com/api/token.php");
curl_setopt_array($ch, [
CURLOPT_POST => true,
CURLOPT_RETURNTRANSFER => true,
CURLOPT_HTTPHEADER => [
"SellerID: 12345",
"Authorization: Basic $basic",
"Content-Type: application/x-www-form-urlencoded",
],
]);
$resp = json_decode(curl_exec($ch), true);
$token = $resp['access_token'];
import base64, requests
basic = base64.b64encode(b"YOUR_CLIENT_ID:YOUR_CLIENT_SECRET").decode()
r = requests.post(
"https://www.arceto.com/api/token.php",
headers={
"SellerID": "12345",
"Authorization": f"Basic {basic}",
"Content-Type": "application/x-www-form-urlencoded",
},
)
token = r.json()["access_token"]
const basic = Buffer.from("YOUR_CLIENT_ID:YOUR_CLIENT_SECRET").toString("base64");
const r = await fetch("https://www.arceto.com/api/token.php", {
method: "POST",
headers: {
"SellerID": "12345",
"Authorization": `Basic ${basic}`,
"Content-Type": "application/x-www-form-urlencoded",
},
});
const { access_token: token } = await r.json();
Response
{
"access_token": "xWlZz*zEsi3HWg9t3Rz1u5CelAMGvPf7GE85qLWVAhrBRB&...",
"token_type": "Bearer",
"expires_in": 900
}token.php rotates your active token — older tokens stop working immediately. Cache the latest token and only re-issue when you hit a 401.
Errors
All errors are returned as JSON with the same shape:
{
"status": "Error",
"error_reason": "INVALID_REQUEST_PARAM",
"error_description": "SellerID is missing or invalid."
}| error_reason | When it happens |
|---|---|
METHOD_NOT_ALLOWED | Wrong HTTP verb (e.g. GET on a write endpoint). |
INVALID_REQUEST_HEADER | Missing or wrong Content-Type. |
INVALID_REQUEST_PARAM | Required parameter missing or malformed. |
UNAUTHORIZED | Bad Client ID / Client Secret pair. |
CONTENT_NOT_FOUND | Resource doesn't exist or isn't owned by this seller. |
Bulk endpoints (price, qty, shipping) return per-item results — you'll get HTTP 200 with a mixed summary + items array, not a top-level error.
Condition IDs
Several endpoints take a conditionId field. Each (BSIN, conditionId) pair on your account is a distinct row — the same product in New and Open Box conditions are listed separately.
| conditionId | Display name |
|---|---|
1 | New |
2 | Open Box |
3 | Refurbished |
4 | Seller Refurbished |
5 | Used |
List products v1
Return your seller-scoped product feed. Supports search, filtering and pagination. Use this to bootstrap your local mirror of BSINs, then call /price and /qty to push updates.
Query parameters
| Param | Type | Description |
|---|---|---|
bsin | string | Filter by exact Arceto BSIN. |
itemId | int | Filter by Arceto numeric item id. |
upc | string | Filter by GTIN / UPC. |
conditionId | int | Restrict to one condition (1–5, see above). |
q | string | Substring match on title or manufacturer part #. |
changedSince | datetime | Only return rows updated after YYYY-MM-DD HH:MM:SS (UTC). |
page | int | 1-indexed page number. Default 1. |
limit | int | Items per page. Default 50, max 200. |
curl "https://www.arceto.com/api/products.php?changedSince=2026-04-26+00:00:00&limit=100" \ -H "SellerID: 12345" \ -H "Authorization: Basic $BASIC" \ -H "AccessToken: $TOKEN" \ -H "Content-Type: application/x-www-form-urlencoded"
<?php
$ch = curl_init("https://www.arceto.com/api/products.php?changedSince=2026-04-26+00:00:00&limit=100");
curl_setopt_array($ch, [
CURLOPT_RETURNTRANSFER => true,
CURLOPT_HTTPHEADER => [
"SellerID: 12345",
"Authorization: Basic $basic",
"AccessToken: $token",
"Content-Type: application/x-www-form-urlencoded",
],
]);
$result = json_decode(curl_exec($ch), true);
foreach ($result['products'] as $p) {
echo "{$p['bsin']} qty={$p['qty']} cost={$p['cost']}\n";
}
r = requests.get(
"https://www.arceto.com/api/products.php",
headers={
"SellerID": "12345",
"Authorization": f"Basic {basic}",
"AccessToken": token,
"Content-Type": "application/x-www-form-urlencoded",
},
params={"changedSince": "2026-04-26 00:00:00", "limit": 100},
)
for p in r.json()["products"]:
print(p["bsin"], p["qty"], p["cost"])
const r = await fetch(
"https://www.arceto.com/api/products.php?changedSince=2026-04-26+00:00:00&limit=100",
{
headers: {
"SellerID": "12345",
"Authorization": `Basic ${basic}`,
"AccessToken": token,
"Content-Type": "application/x-www-form-urlencoded",
},
},
);
const { products } = await r.json();
for (const p of products) console.log(p.bsin, p.qty, p.cost);
Response
{
"meta": { "page": 1, "limit": 50, "total": 1, "pages": 1 },
"products": [
{
"bsin": "ZUGKSHHKHO",
"itemId": 238724478,
"title": "YAMAHA YVC-330 USB MICROPHONE & SPEAKER SYSTEM",
"mfg": "Yamaha",
"mfgPart": "10-YVC330",
"productId": "889025128698",
"productIdType": "UPC",
"conditionId": 1,
"condition": "New",
"cost": 367.72,
"mapEnabled": true,
"mapPrice": 410.29,
"qty": 2,
"markup": 9,
"discount": 0,
"imageUrl": "https://img.arceto.com/product_images/2026/04/4/08/ZUGKSHHKHO-0.webp",
"active": true,
"lastUpdated": "2026-04-26 23:24:44"
}
]
}Update price v1
Bulk-update cost (your selling price in USD) and optional mapPrice (Minimum Advertised Price floor) for one or more (BSIN, conditionId) pairs you own. Up to 500 items per request.
Request body
Send either raw JSON with Content-Type: application/json, or form-encoded with Data=<json-string> and Content-Type: application/x-www-form-urlencoded.
| Field | Type | Description |
|---|---|---|
items[].bsin | string · required | Arceto BSIN. |
items[].conditionId | int · required | 1–5 (see Condition IDs). |
items[].cost | number · required | Selling price in USD. Must be ≥ 0. |
items[].mapPrice | number · optional | MAP floor. Set to 0 to disable MAP. |
curl -X POST https://www.arceto.com/api/price.php \
-H "SellerID: 12345" \
-H "Authorization: Basic $BASIC" \
-H "AccessToken: $TOKEN" \
-H "Content-Type: application/json" \
-d '{
"items": [
{"bsin": "ZUGKSHHKHO", "conditionId": 1, "cost": 367.72, "mapPrice": 410.29},
{"bsin": "ZYNTWY7P9R", "conditionId": 1, "cost": 27.73}
]
}'
<?php
$payload = json_encode([
"items" => [
["bsin" => "ZUGKSHHKHO", "conditionId" => 1, "cost" => 367.72, "mapPrice" => 410.29],
["bsin" => "ZYNTWY7P9R", "conditionId" => 1, "cost" => 27.73],
],
]);
$ch = curl_init("https://www.arceto.com/api/price.php");
curl_setopt_array($ch, [
CURLOPT_POST => true,
CURLOPT_POSTFIELDS => $payload,
CURLOPT_RETURNTRANSFER => true,
CURLOPT_HTTPHEADER => [
"SellerID: 12345",
"Authorization: Basic $basic",
"AccessToken: $token",
"Content-Type: application/json",
],
]);
$result = json_decode(curl_exec($ch), true);
r = requests.post(
"https://www.arceto.com/api/price.php",
headers={
"SellerID": "12345",
"Authorization": f"Basic {basic}",
"AccessToken": token,
"Content-Type": "application/json",
},
json={
"items": [
{"bsin": "ZUGKSHHKHO", "conditionId": 1, "cost": 367.72, "mapPrice": 410.29},
{"bsin": "ZYNTWY7P9R", "conditionId": 1, "cost": 27.73},
]
},
)
print(r.json()["summary"])
const r = await fetch("https://www.arceto.com/api/price.php", {
method: "POST",
headers: {
"SellerID": "12345",
"Authorization": `Basic ${basic}`,
"AccessToken": token,
"Content-Type": "application/json",
},
body: JSON.stringify({
items: [
{ bsin: "ZUGKSHHKHO", conditionId: 1, cost: 367.72, mapPrice: 410.29 },
{ bsin: "ZYNTWY7P9R", conditionId: 1, cost: 27.73 },
],
}),
});
const result = await r.json();
console.log(result.summary);
Response
{
"summary": { "accepted": 2, "rejected": 0, "total": 2 },
"items": [
{ "bsin": "ZUGKSHHKHO", "conditionId": 1, "status": "Success", "description": "Price updated.", "cost": 367.72, "mapPrice": 410.29 },
{ "bsin": "ZYNTWY7P9R", "conditionId": 1, "status": "Success", "description": "Price updated.", "cost": 27.73, "mapPrice": null }
]
}summary.rejected and the per-row status field. Common reasons: BSIN doesn't belong to your seller account, missing conditionId, or negative cost.
Update quantity v1
Bulk-update on-hand quantity for (BSIN, conditionId) pairs. Same shape, same 500-item cap as /price. Set qty: 0 to deactivate a listing without retiring it.
Request body
| Field | Type | Description |
|---|---|---|
items[].bsin | string · required | Arceto BSIN. |
items[].conditionId | int · required | 1–5. |
items[].qty | int · required | On-hand units, ≥ 0. |
curl -X POST https://www.arceto.com/api/qty.php \
-H "SellerID: 12345" \
-H "Authorization: Basic $BASIC" \
-H "AccessToken: $TOKEN" \
-H "Content-Type: application/json" \
-d '{
"items": [
{"bsin": "ZUGKSHHKHO", "conditionId": 1, "qty": 5},
{"bsin": "ZYNTWY7P9R", "conditionId": 1, "qty": 0}
]
}'
<?php
$payload = json_encode([
"items" => [
["bsin" => "ZUGKSHHKHO", "conditionId" => 1, "qty" => 5],
["bsin" => "ZYNTWY7P9R", "conditionId" => 1, "qty" => 0],
],
]);
$ch = curl_init("https://www.arceto.com/api/qty.php");
curl_setopt_array($ch, [
CURLOPT_POST => true,
CURLOPT_POSTFIELDS => $payload,
CURLOPT_RETURNTRANSFER => true,
CURLOPT_HTTPHEADER => [
"SellerID: 12345",
"Authorization: Basic $basic",
"AccessToken: $token",
"Content-Type: application/json",
],
]);
$result = json_decode(curl_exec($ch), true);
r = requests.post(
"https://www.arceto.com/api/qty.php",
headers={
"SellerID": "12345",
"Authorization": f"Basic {basic}",
"AccessToken": token,
"Content-Type": "application/json",
},
json={
"items": [
{"bsin": "ZUGKSHHKHO", "conditionId": 1, "qty": 5},
{"bsin": "ZYNTWY7P9R", "conditionId": 1, "qty": 0},
]
},
)
print(r.json()["summary"])
const r = await fetch("https://www.arceto.com/api/qty.php", {
method: "POST",
headers: {
"SellerID": "12345",
"Authorization": `Basic ${basic}`,
"AccessToken": token,
"Content-Type": "application/json",
},
body: JSON.stringify({
items: [
{ bsin: "ZUGKSHHKHO", conditionId: 1, qty: 5 },
{ bsin: "ZYNTWY7P9R", conditionId: 1, qty: 0 },
],
}),
});
const result = await r.json();
console.log(result.summary);
Response
{
"summary": { "accepted": 2, "rejected": 0, "total": 2 },
"items": [
{ "bsin": "ZUGKSHHKHO", "conditionId": 1, "status": "Success", "description": "Quantity updated.", "qty": 5 },
{ "bsin": "ZYNTWY7P9R", "conditionId": 1, "status": "Success", "description": "Quantity updated.", "qty": 0 }
]
}List orders
Return up to 20 unshipped orders created after the given timestamp. Each order includes its lines, shipping/billing address and totals.
Query parameters
| Param | Type | Description |
|---|---|---|
createdAfter | datetime · required | SQL datetime, e.g. 2026-04-26 00:00:00. |
curl "https://www.arceto.com/api/orders.php?createdAfter=2026-04-26+00:00:00" \ -H "SellerID: 12345" \ -H "Authorization: Basic $BASIC" \ -H "AccessToken: $TOKEN" \ -H "Content-Type: application/x-www-form-urlencoded"
r = requests.get(
"https://www.arceto.com/api/orders.php",
headers={
"SellerID": "12345",
"Authorization": f"Basic {basic}",
"AccessToken": token,
"Content-Type": "application/x-www-form-urlencoded",
},
params={"createdAfter": "2026-04-26 00:00:00"},
)
for o in r.json()["orders"]:
print(o["orderId"], o["orderTotal"])
Get a single order
Fetch one order by its orderId (the value returned by /orders). Same response shape as a single entry in the orders list.
Submit shipment
Mark order lines as shipped and submit carrier + tracking. Carriers accepted include UPS, USPS, FedEx, DHL, OnTrac, Lasership, plus most LTL freight providers.
Request body
| Field | Type | Description |
|---|---|---|
orderShipment.orderId | string · required | The orderId from /orders. |
orderLines.orderLine[].item.id | int · required | The line's item id. |
orderLines.orderLine[].item.qty | int · required | Quantity shipped. |
orderLines.orderLine[].item.status | string · required | Set to "1" for shipped. |
orderLines.orderLine[].item.carrier | string · required | e.g. UPS, FedEx, USPS. |
orderLines.orderLine[].item.service | string | Service level, e.g. Ground. |
orderLines.orderLine[].item.trackingNumber | string · required | Carrier tracking number. |
orderLines.orderLine[].item.shipDate | date · required | YYYY-MM-DD. |
DATA='{"orderShipment":{"orderId":"a1b2c3-91234","orderLines":{"orderLine":[
{"item":{"id":12345,"qty":1,"status":"1","carrier":"UPS","service":"Ground","trackingNumber":"1Z999AA10123456784","shipDate":"2026-04-26"}}
]}}}'
curl -X POST https://www.arceto.com/api/shipping.php \
-H "SellerID: 12345" \
-H "Authorization: Basic $BASIC" \
-H "AccessToken: $TOKEN" \
-H "Content-Type: application/x-www-form-urlencoded" \
--data-urlencode "Data=$DATA"
Changelog
| Date | Change |
|---|---|
| 2026-04-26 | Added /products, /price, /qty. Modernized the developer portal. |
| 2024-12-07 | Initial launch: /token, /orders, /getOrder, /shipping. |
Support
Hit a snag? Email developer@arceto.com with your SellerID, the request URL and the response body. We typically respond within one business day.
For account / payout / catalog questions, head to Seller Central instead.