Loading...
Loading...
Consume SCAPI Admin APIs for backend integrations and data management. Use when building inventory sync, order management, catalog updates, or customer data integrations. Covers Account Manager OAuth, admin scopes, and common integration patterns.
npx skill4agent add salesforcecommercecloud/b2c-developer-tooling b2c-scapi-adminNote: For shopper-facing APIs (products, baskets, checkout), see b2c-scapi-shopper. This skill focuses on admin/backend operations.
https://{shortCode}.api.commercecloud.salesforce.com/{apiFamily}/{apiName}/v1/organizations/{organizationId}/{resource}https://kv7kzm78.api.commercecloud.salesforce.com/product/products/v1/organizations/f_ecom_zzte_053/products/25518823MsiteId# Get admin token (uses clientId/clientSecret from dw.json)
b2c auth token
# Get token with specific scopes
b2c auth token --auth-scope sfcc.orders --auth-scope sfcc.products
# Get token as JSON (includes expiration)
b2c auth token --jsoncurl "https://account.demandware.com/dwsso/oauth2/access_token" \
--request 'POST' \
--user "${CLIENT_ID}:${CLIENT_SECRET}" \
--header 'Content-Type: application/x-www-form-urlencoded' \
--data "grant_type=client_credentials" \
--data-urlencode "scope=SALESFORCE_COMMERCE_API:${TENANT_ID} ${SCOPES}"CLIENT_ID="your-client-id"
CLIENT_SECRET="your-client-secret"
TENANT_ID="zzte_053"
SCOPES="sfcc.orders sfcc.products"
TOKEN=$(curl -s "https://account.demandware.com/dwsso/oauth2/access_token" \
-u "$CLIENT_ID:$CLIENT_SECRET" \
-d "grant_type=client_credentials" \
--data-urlencode "scope=SALESFORCE_COMMERCE_API:$TENANT_ID $SCOPES" \
| jq -r '.access_token')SALESFORCE_COMMERCE_API:{tenant_id}sfcc.catalogssfcc.orders.rwscope=SALESFORCE_COMMERCE_API:zzte_053 sfcc.catalogs sfcc.products.rwclient_secret_postJWT// Get product
const product = await fetch(
`https://${shortCode}.api.commercecloud.salesforce.com/product/products/v1/organizations/${orgId}/products/${productId}`,
{
headers: { 'Authorization': `Bearer ${adminToken}` }
}
).then(r => r.json());
// Update product
await fetch(
`https://${shortCode}.api.commercecloud.salesforce.com/product/products/v1/organizations/${orgId}/products/${productId}`,
{
method: 'PATCH',
headers: {
'Authorization': `Bearer ${adminToken}`,
'Content-Type': 'application/json'
},
body: JSON.stringify({
name: { default: 'Updated Product Name' },
shortDescription: { default: 'New description' }
})
}
);sfcc.productssfcc.products.rw// List catalogs
const catalogs = await fetch(
`https://${shortCode}.api.commercecloud.salesforce.com/product/catalogs/v1/organizations/${orgId}/catalogs`,
{
headers: { 'Authorization': `Bearer ${adminToken}` }
}
).then(r => r.json());
// Get catalog details
const catalog = await fetch(
`https://${shortCode}.api.commercecloud.salesforce.com/product/catalogs/v1/organizations/${orgId}/catalogs/${catalogId}`,
{
headers: { 'Authorization': `Bearer ${adminToken}` }
}
).then(r => r.json());sfcc.catalogssfcc.catalogs.rw// Get order by number
const order = await fetch(
`https://${shortCode}.api.commercecloud.salesforce.com/checkout/orders/v1/organizations/${orgId}/orders/${orderNo}?siteId=${siteId}`,
{
headers: { 'Authorization': `Bearer ${adminToken}` }
}
).then(r => r.json());
// Update order status
await fetch(
`https://${shortCode}.api.commercecloud.salesforce.com/checkout/orders/v1/organizations/${orgId}/orders/${orderNo}?siteId=${siteId}`,
{
method: 'PATCH',
headers: {
'Authorization': `Bearer ${adminToken}`,
'Content-Type': 'application/json'
},
body: JSON.stringify({
status: 'completed',
shippingStatus: 'shipped'
})
}
);sfcc.orderssfcc.orders.rw// Get inventory for a product
const availability = await fetch(
`https://${shortCode}.api.commercecloud.salesforce.com/inventory/availability/v1/organizations/${orgId}/availability-records/search`,
{
method: 'POST',
headers: {
'Authorization': `Bearer ${adminToken}`,
'Content-Type': 'application/json'
},
body: JSON.stringify({
skus: ['SKU001', 'SKU002'],
locationIds: ['warehouse-1']
})
}
).then(r => r.json());
// Update inventory
await fetch(
`https://${shortCode}.api.commercecloud.salesforce.com/inventory/availability/v1/organizations/${orgId}/availability-records`,
{
method: 'PATCH',
headers: {
'Authorization': `Bearer ${adminToken}`,
'Content-Type': 'application/json'
},
body: JSON.stringify({
records: [{
sku: 'SKU001',
locationId: 'warehouse-1',
onHand: 100,
effectiveDate: new Date().toISOString()
}]
})
}
);sfcc.inventory.availabilitysfcc.inventory.availability.rw// Step 1: Initiate import
const importJob = await fetch(
`https://${shortCode}.api.commercecloud.salesforce.com/inventory/impex/v1/organizations/${orgId}/availability-records/imports`,
{
method: 'POST',
headers: {
'Authorization': `Bearer ${adminToken}`,
'Content-Type': 'application/json'
},
body: JSON.stringify({})
}
).then(r => r.json());
// Step 2: Prepare newline-delimited JSON
const ndjsonData = inventoryRecords
.map(r => JSON.stringify({
recordId: r.recordId || crypto.randomUUID(),
sku: r.sku,
locationId: r.locationId,
onHand: r.quantity,
effectiveDate: new Date().toISOString()
}))
.join('\n');
// Step 3: Upload data to the uploadLink
await fetch(importJob.uploadLink, {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: ndjsonData
});
// Step 4: Monitor status
const status = await fetch(importJob.importStatusLink, {
headers: { 'Authorization': `Bearer ${adminToken}` }
}).then(r => r.json());sfcc.inventory.impex-inventory// Search customers
const customers = await fetch(
`https://${shortCode}.api.commercecloud.salesforce.com/customer/customers/v1/organizations/${orgId}/customer-search?siteId=${siteId}`,
{
method: 'POST',
headers: {
'Authorization': `Bearer ${adminToken}`,
'Content-Type': 'application/json'
},
body: JSON.stringify({
query: {
textQuery: { fields: ['email'], searchPhrase: 'john@example.com' }
}
})
}
).then(r => r.json());sfcc.shopper-customerssfcc.shopper-customers.rw// Get promotion
const promotion = await fetch(
`https://${shortCode}.api.commercecloud.salesforce.com/pricing/promotions/v1/organizations/${orgId}/promotions/${promotionId}?siteId=${siteId}`,
{
headers: { 'Authorization': `Bearer ${adminToken}` }
}
).then(r => r.json());
// Update promotion
await fetch(
`https://${shortCode}.api.commercecloud.salesforce.com/pricing/promotions/v1/organizations/${orgId}/promotions/${promotionId}?siteId=${siteId}`,
{
method: 'PATCH',
headers: {
'Authorization': `Bearer ${adminToken}`,
'Content-Type': 'application/json'
},
body: JSON.stringify({
enabled: true,
startDate: '2024-06-01T00:00:00Z',
endDate: '2024-06-30T23:59:59Z'
})
}
);sfcc.promotionssfcc.promotions.rwconst correlationId = crypto.randomUUID();
const response = await fetch(url, {
headers: {
'Authorization': `Bearer ${adminToken}`,
'correlation-id': correlationId
}
});
console.log(`Request ${correlationId} completed`);
// Search Log Center: externalID:({correlationId})const response = await fetch(url, {
headers: {
'Authorization': `Bearer ${adminToken}`,
'sfdc_verbose': 'true'
}
});scapi.verbose| Status | Meaning | Action |
|---|---|---|
| 400 | Bad Request | Check request body/parameters |
| 401 | Unauthorized | Token expired - get new token |
| 403 | Forbidden | Missing scope or tenant access |
| 404 | Not Found | Resource doesn't exist |
| 429 | Rate Limited | Implement backoff |
| 500 | Server Error | Retry with backoff |
| 504 | Timeout | Request took > 60 seconds |