Orders DBS Getting Started Guide
This guide covers everything you need to know to work with DBS (Delivery by Seller) orders in the Wildberries TypeScript SDK.
Migration Notice: Legacy single-order status and metadata methods are deprecated and will be disabled on April 13, 2026. Use the bulk methods described in this guide. See the Migration Guide for details.
Table of Contents
- What is DBS?
- DBS vs FBS vs FBW
- Quick Start
- Available Methods
- Complete Order Workflow
- Working with Customer Data
- Metadata and Compliance
- B2B Orders
- Rate Limits
- Error Handling
- Best Practices
What is DBS?
DBS (Delivery by Seller) is a fulfillment model where sellers handle:
- Storage: Products stored at seller's warehouse
- Delivery: Seller delivers directly to customer's address
Key DBS Features
| Feature | Description |
|---|---|
| Direct Delivery | Deliver to customer's home, not pickup points |
| Customer Contact | Access to phone number and full address |
| GPS Coordinates | Longitude/latitude for route planning |
| Delivery Windows | Specific date and time slots |
| Required Metadata | Product marking codes (IMEI, SGTIN, etc.) |
DBS vs FBS vs FBW
| Aspect | DBS | FBS | FBW |
|---|---|---|---|
| Storage | Seller | Seller | Wildberries |
| Delivery | Seller | Wildberries | Wildberries |
| Customer Address | Full address + GPS | Pickup point | Pickup point |
| Customer Phone | Available | Not available | Not available |
| Delivery Time | Specific windows | Standard | Standard |
Choose DBS when:
- You can deliver directly to customers
- You need delivery time flexibility
- Your products require special handling
- You want direct customer contact
Quick Start
Installation
npm install daytona-wildberries-typescript-sdkBasic Setup
import { WildberriesSDK } from 'daytona-wildberries-typescript-sdk';
const sdk = new WildberriesSDK({
apiKey: process.env.WB_API_KEY!
});
// Check for new orders
const newOrders = await sdk.ordersDBS.getNewOrders();
console.log(`Found ${newOrders.orders?.length ?? 0} new orders`);Environment Setup
Create a .env file:
WB_API_KEY=your_api_key_hereAvailable Methods
Order Retrieval
| Method | Description | Rate Tier |
|---|---|---|
getNewOrders() | Get new orders awaiting processing | T1 (300 rpm) |
getOrders(params) | Get completed orders with pagination | T1 (300 rpm) |
getClientInfo(orderIds) | Get customer contact information | T1 (300 rpm) |
getB2BInfo(orderIds) | Get B2B buyer details | T1 (300 rpm) |
getGroupsInfo(request) | Get paid delivery group information | T1 (300 rpm) |
getDeliveryDates(request) | Get delivery dates for orders | T1 (300 rpm) |
Bulk Status Operations
| Method | Description | Rate Tier |
|---|---|---|
getStatusesBulk(orderIds) | Get statuses for multiple orders | T1 (300 rpm) |
confirmBulk(orderIds) | Confirm multiple orders | T2 (60 rpm) |
deliverBulk(orderIds) | Mark multiple orders as delivered | T2 (60 rpm) |
receiveBulk(orders) | Complete handover for multiple orders | T2 (60 rpm) |
rejectBulk(orders) | Reject multiple orders | T2 (60 rpm) |
cancelBulk(orderIds) | Cancel multiple orders | T2 (60 rpm) |
Bulk Metadata Operations
| Method | Description | Rate Tier |
|---|---|---|
getMetaBulk(request) | Get metadata for multiple orders | T3 (150 rpm) |
deleteMetaBulk(request) | Delete metadata for multiple orders | T3 (150 rpm) |
setSgtinBulk(request) | Set SGTIN codes for multiple orders | T4 (500 rpm) |
setUinBulk(request) | Set UIN codes for multiple orders | T4 (500 rpm) |
setImeiBulk(request) | Set IMEI codes for multiple orders | T4 (500 rpm) |
setGtinBulk(request) | Set GTIN codes for multiple orders | T4 (500 rpm) |
setCustomsDeclarationBulk(request) | Set customs declarations for multiple orders | T4 (500 rpm) |
Deprecated Methods (Removed April 13, 2026)
The following legacy single-order methods are deprecated. Migrate to their bulk replacements before the deadline.
| Deprecated Method | Replacement | Deadline |
|---|---|---|
getMeta(orderId) | getMetaBulk(request) | April 13, 2026 |
deleteMeta(orderId, key) | deleteMetaBulk(request) | April 13, 2026 |
setSgtin(orderId, sgtins) | setSgtinBulk(request) | April 13, 2026 |
setUin(orderId, uin) | setUinBulk(request) | April 13, 2026 |
setImei(orderId, imei) | setImeiBulk(request) | April 13, 2026 |
setGtin(orderId, gtin) | setGtinBulk(request) | April 13, 2026 |
setCustomsDeclaration(orderId, cd) | setCustomsDeclarationBulk(request) | April 13, 2026 |
getStatuses(orderIds) | getStatusesBulk(orderIds) | April 13, 2026 |
confirm(orderId) | confirmBulk([orderId]) | April 13, 2026 |
deliver(orderId) | deliverBulk([orderId]) | April 13, 2026 |
receive(orderId, code) | receiveBulk([{orderId, code}]) | April 13, 2026 |
reject(orderId, code) | rejectBulk([{orderId, code}]) | April 13, 2026 |
cancel(orderId) | cancelBulk([orderId]) | April 13, 2026 |
Complete Order Workflow
Step 1: Fetch New Orders
const newOrders = await sdk.ordersDBS.getNewOrders();
for (const order of newOrders.orders ?? []) {
console.log(`Order ${order.id}:`);
console.log(` Article: ${order.article}`);
console.log(` Address: ${order.address?.fullAddress}`);
console.log(` Delivery: ${order.ddate} ${order.dTimeFrom}-${order.dTimeTo}`);
// Check for required metadata
if (order.requiredMeta?.length) {
console.log(` Required metadata: ${order.requiredMeta.join(', ')}`);
}
}Step 2: Get Customer Contact
const orderIds = newOrders.orders?.map(o => o.id!).filter(Boolean) ?? [];
if (orderIds.length > 0) {
const clientInfo = await sdk.ordersDBS.getClientInfo(orderIds);
for (const client of clientInfo.orders ?? []) {
console.log(`Order ${client.orderID}:`);
console.log(` Name: ${client.fullName}`);
console.log(` Phone: +${client.phoneCode}${client.phone}`);
}
}Step 3: Get Delivery Group and Date Info
// Get paid delivery group information
const groups = await sdk.ordersDBS.getGroupsInfo({ orders: orderIds });
for (const group of groups.groups ?? []) {
console.log(`Group ${group.id} "${group.name}": orders ${group.orders.join(', ')}`);
}
// Get delivery date details
const dates = await sdk.ordersDBS.getDeliveryDates({ orders: orderIds });
for (const dateInfo of dates.orders ?? []) {
console.log(`Order ${dateInfo.orderId}: deliver by ${dateInfo.deliveryDate}`);
}Step 4: Add Required Metadata (Bulk)
// Set IMEI for multiple orders at once
const imeiOrders = newOrders.orders
?.filter(o => o.requiredMeta?.includes('imei'))
?? [];
if (imeiOrders.length > 0) {
const result = await sdk.ordersDBS.setImeiBulk({
orders: imeiOrders.map(o => ({
orderId: o.id!,
imei: getImeiFromInventory(o.id!) // your inventory lookup
}))
});
for (const r of result.orders ?? []) {
if (r.error) {
console.error(`IMEI failed for order ${r.orderId}: ${r.error}`);
}
}
}
// Set SGTIN for multiple orders at once
const sgtinOrders = newOrders.orders
?.filter(o => o.requiredMeta?.includes('sgtin'))
?? [];
if (sgtinOrders.length > 0) {
const result = await sdk.ordersDBS.setSgtinBulk({
orders: sgtinOrders.map(o => ({
orderId: o.id!,
sgtins: getSgtinsFromInventory(o.id!) // your inventory lookup
}))
});
}Step 5: Verify Metadata (Bulk)
// Verify metadata was set correctly for all orders
const meta = await sdk.ordersDBS.getMetaBulk({ orders: orderIds });
for (const orderMeta of meta.orders ?? []) {
console.log(`Order ${orderMeta.orderId}:`);
if (orderMeta.imei) {
console.log(` IMEI: ${orderMeta.imei}`);
}
if (orderMeta.sgtins?.length) {
console.log(` SGTINs: ${orderMeta.sgtins.length} codes`);
}
}Step 6: Confirm Order
const confirmResult = await sdk.ordersDBS.confirmBulk(orderIds);
for (const r of confirmResult.results ?? []) {
if (r.isError) {
console.error(`Confirmation failed for ${r.orderId}:`, r.errors);
} else {
console.log(`Order ${r.orderId} confirmed`);
}
}Step 7: Deliver Order
// After physical delivery
const deliverResult = await sdk.ordersDBS.deliverBulk(orderIds);
for (const r of deliverResult.results ?? []) {
if (!r.isError) {
console.log(`Order ${r.orderId} marked as delivered`);
}
}Step 8: Complete Handover
// Customer provides verification code from WB app
const receiveResult = await sdk.ordersDBS.receiveBulk([
{ orderId: orderIds[0], code: '1234' },
{ orderId: orderIds[1], code: '5678' }
]);
for (const r of receiveResult.results ?? []) {
if (!r.isError) {
console.log(`Handover completed for order ${r.orderId}`);
}
}Working with Customer Data
Address and GPS
const orders = await sdk.ordersDBS.getNewOrders();
for (const order of orders.orders ?? []) {
const addr = order.address;
if (addr) {
console.log(`Delivery to: ${addr.fullAddress}`);
// Use GPS for route planning
if (addr.latitude && addr.longitude) {
console.log(`GPS: ${addr.latitude}, ${addr.longitude}`);
// Example: Open in Google Maps
const mapsUrl = `https://maps.google.com/?q=${addr.latitude},${addr.longitude}`;
console.log(`Maps: ${mapsUrl}`);
}
}
}Delivery Windows
const order = orders.orders?.[0];
if (order) {
const deliveryDate = order.ddate; // "2024-01-15"
const timeFrom = order.dTimeFrom; // "09:00"
const timeTo = order.dTimeTo; // "12:00"
console.log(`Deliver on ${deliveryDate} between ${timeFrom} and ${timeTo}`);
}Delivery Dates (Bulk Lookup)
// Get delivery date details for multiple orders at once
const orderIds = orders.orders?.map(o => o.id!).filter(Boolean) ?? [];
const dates = await sdk.ordersDBS.getDeliveryDates({ orders: orderIds });
for (const dateInfo of dates.orders ?? []) {
console.log(`Order ${dateInfo.orderId}:`);
console.log(` Delivery date: ${dateInfo.deliveryDate}`);
console.log(` Max delivery date: ${dateInfo.maxDeliveryDate}`);
}Customer Comments
if (order.comment) {
console.log(`Customer note: ${order.comment}`);
// Handle special delivery instructions
}Metadata and Compliance
Required Metadata Types
| Type | Description | Format |
|---|---|---|
sgtin | Marking codes | 16-135 chars, max 24 |
imei | Mobile device ID | Exactly 15 chars |
uin | Unique ID number | Exactly 16 chars |
gtin | Global trade item | Exactly 13 chars |
customsDeclaration | Customs number | 1-50 chars |
Setting Metadata (Bulk -- Recommended)
Use the bulk metadata methods to set metadata for multiple orders in a single API call:
// Set IMEI for multiple orders
const imeiResult = await sdk.ordersDBS.setImeiBulk({
orders: [
{ orderId: 111, imei: '123456789012345' },
{ orderId: 222, imei: '543210987654321' }
]
});
// Set SGTIN for multiple orders
const sgtinResult = await sdk.ordersDBS.setSgtinBulk({
orders: [
{ orderId: 333, sgtins: ['01046012345678900421abc123'] },
{ orderId: 444, sgtins: ['01046012345678900421abc456', '01046012345678900421abc789'] }
]
});
// Set customs declaration for multiple orders
const cdResult = await sdk.ordersDBS.setCustomsDeclarationBulk({
orders: [
{ orderId: 555, customsDeclaration: '10130030/010123/0000001' }
]
});Verifying Metadata (Bulk)
const meta = await sdk.ordersDBS.getMetaBulk({
orders: [111, 222, 333, 444, 555]
});
for (const orderMeta of meta.orders ?? []) {
console.log(`Order ${orderMeta.orderId}:`);
if (orderMeta.imei) {
console.log(` IMEI: ${orderMeta.imei}`);
}
if (orderMeta.sgtins?.length) {
console.log(` SGTIN codes: ${orderMeta.sgtins.length}`);
}
if (orderMeta.customsDeclaration) {
console.log(` Customs: ${orderMeta.customsDeclaration}`);
}
}Deleting Metadata (Bulk)
// If you need to correct metadata for multiple orders
const deleteResult = await sdk.ordersDBS.deleteMetaBulk({
orders: [111, 222],
key: 'imei'
});
// Then set corrected values
await sdk.ordersDBS.setImeiBulk({
orders: [
{ orderId: 111, imei: 'corrected150000' },
{ orderId: 222, imei: 'corrected250000' }
]
});B2B Orders
Identifying B2B Orders
const b2bInfo = await sdk.ordersDBS.getB2BInfo(orderIds);
for (const result of b2bInfo.results ?? []) {
if (result.isError) {
// This is an individual (B2C) order
console.log(`Order ${result.orderId}: Individual buyer`);
} else if (result.data) {
// This is a B2B order
console.log(`Order ${result.orderId}: B2B`);
console.log(` Organization: ${result.data.orgName}`);
console.log(` INN: ${result.data.inn}`);
console.log(` KPP: ${result.data.kpp || 'N/A'}`);
}
}B2B Documentation
For B2B orders, you typically need:
- Invoice with organization details
- INN and KPP in accounting documents
- Universal Transfer Document (UPD) if required
// Example: Generate invoice data
const b2bOrder = b2bInfo.results?.find(r => !r.isError && r.data);
if (b2bOrder?.data) {
const invoiceData = {
buyer: b2bOrder.data.orgName,
inn: b2bOrder.data.inn,
kpp: b2bOrder.data.kpp || '',
orderRef: `WB-DBS-${b2bOrder.orderId}`
};
// Use invoiceData for your accounting system
}Rate Limits
The DBS API uses a 4-tier rate limit system. The SDK enforces these limits automatically, but understanding them helps you design efficient integrations.
Rate Limit Tiers
| Tier | Name | Requests/Min | Interval | Burst | Applies To |
|---|---|---|---|---|---|
| T1 | Assembly Read | 300 | 200ms | 20 | getNewOrders, getOrders, getClientInfo, getStatusesBulk, getB2BInfo, getGroupsInfo, getDeliveryDates |
| T2 | Status Write | 60 | 1s | 10 | confirmBulk, deliverBulk, receiveBulk, rejectBulk, cancelBulk |
| T3 | Meta Read/Delete | 150 | 400ms | 20 | getMetaBulk, deleteMetaBulk (and deprecated getMeta, deleteMeta) |
| T4 | Meta Set | 500 | 120ms | 20 | setSgtinBulk, setUinBulk, setImeiBulk, setGtinBulk, setCustomsDeclarationBulk |
Penalty Multiplier (409 Responses)
All DBS endpoints use a penalty multiplier of 10. If the API returns a 409 Conflict response (e.g., due to an invalid state transition), that single request counts as 10 requests toward your rate limit budget. This means a few 409 errors can quickly exhaust your rate limit allowance.
Avoid 409 errors by:
- Checking order status with
getStatusesBulk()before attempting state transitions - Not confirming already-confirmed orders
- Ensuring metadata is set before confirming orders that require it
Rate Limit Tips
- T2 (Status Write) is the most restrictive at 60 requests/minute. Batch order IDs into
confirmBulk([...])calls instead of confirming one at a time. - T4 (Meta Set) is the most generous at 500 requests/minute. Metadata set operations are fast but still benefit from bulk calls for fewer round-trips.
- The SDK handles rate limiting automatically. If a limit is hit, the request is queued and retried after the required interval.
- Watch for 409 errors: Each 409 response counts as 10 requests toward the rate limit (penalty multiplier), so invalid state transitions are costly.
// Efficient: one API call for 500 orders
const result = await sdk.ordersDBS.confirmBulk(orderIds); // 1 T2 call
// Inefficient: 500 API calls (would exhaust T2 limit in ~8 minutes)
// for (const id of orderIds) {
// await sdk.ordersDBS.confirm(id); // 500 T2 calls -- DON'T DO THIS
// }Error Handling
Comprehensive Error Handling
import {
WildberriesSDK,
RateLimitError,
AuthenticationError,
ValidationError,
NetworkError,
WBAPIError
} from 'daytona-wildberries-typescript-sdk';
async function processOrders() {
try {
const orders = await sdk.ordersDBS.getNewOrders();
// Process orders...
} catch (error) {
if (error instanceof RateLimitError) {
console.error('Rate limit exceeded');
console.error(`Retry after: ${error.retryAfter}ms`);
// SDK handles retry automatically, but you can add logging
} else if (error instanceof AuthenticationError) {
console.error('Invalid API key');
// Check your API key configuration
} else if (error instanceof ValidationError) {
console.error('Validation error:', error.message);
// Fix request parameters
} else if (error instanceof NetworkError) {
console.error('Network error:', error.message);
// Check connectivity
} else if (error instanceof WBAPIError) {
console.error(`API error ${error.statusCode}: ${error.message}`);
}
}
}Handling Bulk Operation Errors
const result = await sdk.ordersDBS.confirmBulk(orderIds);
// Check each order's result
const successful = [];
const failed = [];
for (const orderResult of result.results ?? []) {
if (orderResult.isError) {
failed.push({
orderId: orderResult.orderId,
errors: orderResult.errors
});
} else {
successful.push(orderResult.orderId);
}
}
console.log(`Confirmed: ${successful.length}`);
console.log(`Failed: ${failed.length}`);
// Handle failures
for (const failure of failed) {
console.error(`Order ${failure.orderId}:`, failure.errors);
}Best Practices
1. Use Bulk Methods for Metadata
// Preferred: Set metadata for all orders in one call
const result = await sdk.ordersDBS.setImeiBulk({
orders: [
{ orderId: 111, imei: '123456789012345' },
{ orderId: 222, imei: '543210987654321' }
]
});
// Avoid: Setting metadata one order at a time (deprecated, removed April 13, 2026)
// await sdk.ordersDBS.setImei(111, '123456789012345');
// await sdk.ordersDBS.setImei(222, '543210987654321');2. Check Metadata Before Confirming
// Always add required metadata before confirming
const order = newOrders.orders?.[0];
if (order?.requiredMeta?.length) {
// Set all required metadata first using bulk methods
// Then confirm
}
await sdk.ordersDBS.confirmBulk([order.id!]);3. Batch Operations
// Process multiple orders efficiently
const orderIds = orders.orders?.map(o => o.id!).filter(Boolean) ?? [];
// Single API call for all orders
const statuses = await sdk.ordersDBS.getStatusesBulk(orderIds);4. Handle Pagination
// Fetch all completed orders with pagination
const now = Math.floor(Date.now() / 1000);
const thirtyDaysAgo = now - 30 * 24 * 60 * 60;
let allOrders = [];
let next = 0;
do {
const result = await sdk.ordersDBS.getOrders({
limit: 1000,
next,
dateFrom: thirtyDaysAgo,
dateTo: now
});
allOrders.push(...(result.orders ?? []));
next = result.next ?? 0;
} while (next > 0);5. Rate Limit Awareness
// DBS API has a 4-tier rate limit system.
// The SDK handles limits automatically, but for high-volume operations
// batch your order IDs to reduce API call count.
const BATCH_SIZE = 1000; // Max items per bulk request
const orderBatches = chunkArray(orderIds, BATCH_SIZE);
for (const batch of orderBatches) {
const result = await sdk.ordersDBS.confirmBulk(batch);
// Process result...
}
function chunkArray<T>(array: T[], size: number): T[][] {
const chunks = [];
for (let i = 0; i < array.length; i += size) {
chunks.push(array.slice(i, i + size));
}
return chunks;
}6. Logging and Monitoring
// Log important operations for debugging
async function confirmOrderWithLogging(orderId: number) {
console.log(`[DBS] Confirming order ${orderId}`);
const result = await sdk.ordersDBS.confirmBulk([orderId]);
const orderResult = result.results?.[0];
if (orderResult?.isError) {
console.error(`[DBS] Order ${orderId} confirmation failed:`, orderResult.errors);
throw new Error(`Confirmation failed: ${orderResult.errors?.[0]?.detail}`);
}
console.log(`[DBS] Order ${orderId} confirmed successfully`);
return result;
}Common Issues
"Date range exceeds 30 days"
// Wrong
const result = await sdk.ordersDBS.getOrders({
limit: 100,
next: 0,
dateFrom: now - 60 * 24 * 60 * 60, // 60 days ago
dateTo: now
});
// Correct - split into 30-day chunks
const chunks = splitDateRange(startDate, endDate, 30);
for (const chunk of chunks) {
const result = await sdk.ordersDBS.getOrders({
limit: 100,
next: 0,
dateFrom: chunk.from,
dateTo: chunk.to
});
}"orderIds array cannot be empty"
// Always check before calling
const orderIds = orders.orders?.map(o => o.id!).filter(Boolean) ?? [];
if (orderIds.length > 0) {
const clientInfo = await sdk.ordersDBS.getClientInfo(orderIds);
}"IMEI must be exactly 15 characters"
// Validate before calling
const imei = '123456789012345';
if (imei.length !== 15) {
throw new Error(`Invalid IMEI length: ${imei.length}, expected 15`);
}
await sdk.ordersDBS.setImeiBulk({
orders: [{ orderId: orderId, imei }]
});