Open Application Platform Docs

A deposit, end to end

From the delivery task to the pickup by the recipient.

1. Create the task

Create the task with your own idempotency key for the order. The answer carries delivery_no, the access_code for the driver and the pickup_code for the recipient. The same key with the same content answers the original task (replayed: true). The same key with different content answers 409 IDEMPOTENCY_CONFLICT.

// JavaScript / TypeScript
const created = await sl.api.createPartnerLockerDelivery({
  idempotencyKey: 'FOOD-20260714-1001-v1',                    // your own, the same for this order on every retry
  body: {
    external_order_id: 'FOOD-20260714-1001',
    platform_scope_group_id: 12,
    recipient: { phone: '+14165550123' },
    package_count: 2,
  },
});
const { delivery_no, access_code } = created.data;

2. Open the doors

At the cabinet the driver enters the code on the screen, or your app opens the doors remotely with the access code. The answer carries a claim_token and the compartments that opened. A code that is valid at several locations needs location_id.

const opened = await sl.api.openPartnerLockerDelivery({ body: { location_id: 101, access_code } });
const { claim_token, attempt } = opened.data;

3. Confirm

Confirm with the claim token: confirm_all, or accept_partial when some packages did not fit. After a remote opening the cabinet completes the deposit when every opened door reports closed. A confirmation after that answers the same result.

if (attempt.can_confirm) {
  await sl.api.confirmPartnerLockerDelivery({ body: { claim_token, decision: 'confirm_all' } });   // or 'accept_partial'
}
const task = await sl.api.partnerLockerDelivery({ deliveryNo: delivery_no });

4. Follow the pickup

The webhooks report the next steps: the doors opened, the deposit with the pickup code and the compartments, and the pickup by the recipient.

partner_locker.delivery.doors_opened → partner_locker.delivery.delivered → partner_locker.pickup.completed

Webhooks

Python

from slocker import SLockerClient, SLockerError

sl = SLockerClient(provider_id=4611)
sl.login('api-partner@example.com', password)
created = sl.create_partner_locker_delivery(
    idempotency_key='FOOD-20260714-1001-v1',
    body={'external_order_id': 'FOOD-20260714-1001', 'platform_scope_group_id': 12,
          'recipient': {'phone': '+14165550123'}, 'package_count': 2})
try:
    opened = sl.open_partner_locker_delivery(body={'location_id': 101, 'access_code': created['data']['access_code']})
    sl.confirm_partner_locker_delivery(body={'claim_token': opened['data']['claim_token'], 'decision': 'confirm_all'})
except SLockerError as e:
    if e.code == 'LOCKER_DELIVERY_IN_USE':
        ...  # another attempt is in progress
    raise

Corrections

Abort an attempt, move a package to another compartment, cancel the placement, or reopen the doors within 60 seconds after the confirmation. Each is a separate call for a separate case.

After a timeout on a change, read the task before the next step. Give your own idempotency key, one per order and the same on every retry, so that a retry after a crash finds the original task.

Error codes to handle

Code Meaning
409 LOCKER_DELIVERY_IN_USE Another attempt is in progress. Wait, or use its claim token.
409 / 422 IDEMPOTENCY_CONFLICT The key was used with different content, or no key was sent.
429 LOCKER_RATE_LIMITED Over the rate limit. Wait as long as Retry-After asks.
409 LOCKER_NO_CABINET_FOR_MODE The location has no cabinet in the mode of the task.
403 LOCKER_PERMISSION_DENIED The provider is not allowed this call.