Skip to content

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 (Delivery by Seller) is a fulfillment model where sellers handle:

  1. Storage: Products stored at seller's warehouse
  2. Delivery: Seller delivers directly to customer's address

Key DBS Features

FeatureDescription
Direct DeliveryDeliver to customer's home, not pickup points
Customer ContactAccess to phone number and full address
GPS CoordinatesLongitude/latitude for route planning
Delivery WindowsSpecific date and time slots
Required MetadataProduct marking codes (IMEI, SGTIN, etc.)

DBS vs FBS vs FBW

AspectDBSFBSFBW
StorageSellerSellerWildberries
DeliverySellerWildberriesWildberries
Customer AddressFull address + GPSPickup pointPickup point
Customer PhoneAvailableNot availableNot available
Delivery TimeSpecific windowsStandardStandard

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

bash
npm install daytona-wildberries-typescript-sdk

Basic Setup

typescript
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:

bash
WB_API_KEY=your_api_key_here

Available Methods

Order Retrieval

MethodDescriptionRate Tier
getNewOrders()Get new orders awaiting processingT1 (300 rpm)
getOrders(params)Get completed orders with paginationT1 (300 rpm)
getClientInfo(orderIds)Get customer contact informationT1 (300 rpm)
getB2BInfo(orderIds)Get B2B buyer detailsT1 (300 rpm)
getGroupsInfo(request)Get paid delivery group informationT1 (300 rpm)
getDeliveryDates(request)Get delivery dates for ordersT1 (300 rpm)

Bulk Status Operations

MethodDescriptionRate Tier
getStatusesBulk(orderIds)Get statuses for multiple ordersT1 (300 rpm)
confirmBulk(orderIds)Confirm multiple ordersT2 (60 rpm)
deliverBulk(orderIds)Mark multiple orders as deliveredT2 (60 rpm)
receiveBulk(orders)Complete handover for multiple ordersT2 (60 rpm)
rejectBulk(orders)Reject multiple ordersT2 (60 rpm)
cancelBulk(orderIds)Cancel multiple ordersT2 (60 rpm)

Bulk Metadata Operations

MethodDescriptionRate Tier
getMetaBulk(request)Get metadata for multiple ordersT3 (150 rpm)
deleteMetaBulk(request)Delete metadata for multiple ordersT3 (150 rpm)
setSgtinBulk(request)Set SGTIN codes for multiple ordersT4 (500 rpm)
setUinBulk(request)Set UIN codes for multiple ordersT4 (500 rpm)
setImeiBulk(request)Set IMEI codes for multiple ordersT4 (500 rpm)
setGtinBulk(request)Set GTIN codes for multiple ordersT4 (500 rpm)
setCustomsDeclarationBulk(request)Set customs declarations for multiple ordersT4 (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 MethodReplacementDeadline
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

typescript
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

typescript
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

typescript
// 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)

typescript
// 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)

typescript
// 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

typescript
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

typescript
// 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

typescript
// 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

typescript
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

typescript
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)

typescript
// 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

typescript
if (order.comment) {
  console.log(`Customer note: ${order.comment}`);
  // Handle special delivery instructions
}

Metadata and Compliance

Required Metadata Types

TypeDescriptionFormat
sgtinMarking codes16-135 chars, max 24
imeiMobile device IDExactly 15 chars
uinUnique ID numberExactly 16 chars
gtinGlobal trade itemExactly 13 chars
customsDeclarationCustoms number1-50 chars

Use the bulk metadata methods to set metadata for multiple orders in a single API call:

typescript
// 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)

typescript
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)

typescript
// 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

typescript
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:

  1. Invoice with organization details
  2. INN and KPP in accounting documents
  3. Universal Transfer Document (UPD) if required
typescript
// 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

TierNameRequests/MinIntervalBurstApplies To
T1Assembly Read300200ms20getNewOrders, getOrders, getClientInfo, getStatusesBulk, getB2BInfo, getGroupsInfo, getDeliveryDates
T2Status Write601s10confirmBulk, deliverBulk, receiveBulk, rejectBulk, cancelBulk
T3Meta Read/Delete150400ms20getMetaBulk, deleteMetaBulk (and deprecated getMeta, deleteMeta)
T4Meta Set500120ms20setSgtinBulk, 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.
typescript
// 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

typescript
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

typescript
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

typescript
// 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

typescript
// 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

typescript
// 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

typescript
// 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

typescript
// 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

typescript
// 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"

typescript
// 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"

typescript
// 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"

typescript
// 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 }]
});

Next Steps

Made with ❤️ for the Wildberries developer community