Salla added the actual_picked_up_at string to Update Shipment Details on October 14, 2026. The field gives shipping integrations a documented place to report when the carrier actually collected a shipment. That sounds small, but it closes an important operational gap: “ready for pickup,” “carrier assigned,” and “picked up” are different facts. Merchants, warehouses, carriers and customer-support teams need the last one to measure handoff delay and investigate missing parcels.
This is a practical documentation explainer, not a claim that Salla launched a major product today. The field and endpoint contract come from Salla’s official changelog and shipment documentation, verified on October 25, 2026. The event ledger, validation rules and reconciliation workflow below are engineering recommendations.
The answer first
Treat actual_picked_up_at as a carrier-observed business event, not as the time your worker sent an API request. Persist the pickup observation before calling Salla, normalize its timezone, submit it with the required shipment status, and read the shipment back before marking the synchronization complete. Never invent the timestamp from label creation, a scheduled pickup window or a local status transition.
| Timestamp | What it should mean | What it must not mean |
|---|---|---|
label_created_at | A label or AWB was generated | The parcel left the warehouse |
pickup_scheduled_at | A carrier visit was planned | The carrier arrived or accepted custody |
actual_picked_up_at | Carrier custody was actually observed | Your sync job ran successfully |
actual_delivered_at | Delivery was actually observed | The order was merely marked completed |
Salla’s Update Shipment Details example includes both actual_picked_up_at and actual_delivered_at. It also documents status as required and uses the shipping.read_write scope. These are vendor facts. How you capture evidence and prevent conflicting writes remains your integration’s responsibility.
Where the new field belongs
Model a shipment as three layers:
- Observations are immutable facts received from a carrier, warehouse scan, driver application or approved operator action.
- Projection is your current best shipment state, derived from accepted observations.
- Commands are attempts to update Salla or another remote system.
The pickup timestamp belongs first in an observation. If a carrier webhook reports collection at 14:08, store the raw provider event, provider shipment identifier, observed time, receipt time, source, payload hash and verification outcome. Then derive the local projection and enqueue a Salla update. This preserves evidence if the remote call times out or is retried.
A minimal ledger can look like this:
create table shipment_observations (
merchant_id bigint not null,
shipment_id bigint not null,
source text not null,
source_event_id text not null,
event_type text not null,
occurred_at timestamptz not null,
received_at timestamptz not null default now(),
payload_hash text not null,
verification_state text not null,
primary key (merchant_id, source, source_event_id)
);The uniqueness boundary is scoped by merchant and source. A carrier event identifier may be unique only inside one carrier account. If a provider has no stable event ID, build a reviewed fingerprint from the merchant, provider shipment ID, event type, normalized occurred time and payload hash; keep the raw observation for audit.
Define the source-of-truth hierarchy
Not every timestamp deserves equal trust. Use an explicit precedence policy:
| Source | Typical evidence | Default trust |
|---|---|---|
| Carrier signed webhook or API | Provider event ID and carrier time | Highest automated evidence |
| Warehouse scan | Device, operator, dock and package scan | Strong custody evidence when the process is controlled |
| Driver application | Driver identity, route and device time | Useful, but validate clock and assignment |
| Manual merchant action | User, reason and audit trail | Allowed exception, not silent overwrite |
| Integration job clock | Only when processing happened | Never a pickup fact |
If two accepted sources disagree, do not silently keep the latest value. Record a conflict with both observations and a resolution reason. A later-arriving event can describe an earlier pickup, so arrival order is not business order.
Normalize time before writing
Salla documents the field as a string and shows a datetime-shaped example. The page does not state that a timezone offset is included in that request value. Therefore, keep your authoritative value internally as timestamptz or an equivalent UTC instant plus the original provider representation. Format the outgoing value exactly as the current Salla contract and your verified test store accept; do not infer undocumented offset handling.
Apply these checks before dispatch:
- the pickup time is not after an already confirmed delivery time;
- it is not implausibly before shipment creation;
- a future value beyond a small clock-skew allowance is quarantined;
- the carrier or warehouse identity matches the shipment mapping;
- the timestamp is not replaced by a lower-trust source without review;
- the original timezone and raw value remain available for investigation.
Daylight-saving and local-time ambiguity matter for cross-border carriers. Saudi Arabia is UTC+3 year-round, but the provider system that emitted the event may not be. Normalize from the source’s declared timezone, not from the merchant’s storefront timezone by assumption.
Use an idempotent update command
Create a command record before calling PUT /shipments/{shipment_id}. A practical business key is merchant, Salla shipment ID, operation type and accepted pickup observation ID. The command moves through pending, dispatching, observed_succeeded, observed_failed or outcome_unknown.
verified pickup observation
-> derive shipment projection
-> create one update command
-> PUT shipment with required status + actual_picked_up_at
-> read shipment back
-> close command only after observed convergenceIf the PUT returns a documented success, still retain the command and response correlation. If the connection drops after sending the request, do not immediately create a second business operation. Read Shipment Details first. Retry the same command only when the observed remote state proves the desired value was not accepted and the API contract permits the retry.
Salla’s endpoint requires status. Do not let a pickup-timestamp sync accidentally invent or regress shipment state. Build the request from a fresh, authorized shipment projection and an allowed transition. If your integration does not own status, coordinate ownership explicitly rather than copying a stale cached value.
Keep pickup, fulfillment and customer promises separate
Pickup evidence answers “when did custody move to the carrier?” It does not prove:
- that the parcel entered the carrier’s first hub;
- that tracking is publicly available;
- that delivery will meet the checkout promise;
- that cash-on-delivery was collected;
- that inventory or accounting reconciliation is complete.
Use the timestamp to measure warehouse-to-carrier handoff and to start the correct operational timers. For example, alert when a shipment remains ready but has no verified pickup observation beyond the merchant’s policy. After pickup, use carrier tracking and shipment status for in-transit monitoring. Do not send “your order has shipped” merely because a label exists.
Reconciliation catches missed events
Webhooks and scans can be delayed, duplicated or absent. Run a bounded reconciliation job that compares:
- local accepted pickup observations;
- local commands and unknown outcomes;
- Salla Shipment Details for the mapped shipment;
- carrier tracking or pickup evidence;
- the warehouse dispatch ledger.
Classify mismatches instead of overwriting them:
| Mismatch | Safe response |
|---|---|
| Local pickup exists, Salla missing | Read back, then retry the same command if safe |
| Salla pickup exists, local missing | Import as an external observation and investigate ownership |
| Both exist, same instant | Mark converged |
| Both exist, different instants | Quarantine for precedence and evidence review |
| Delivered exists, pickup missing | Backfill only from real evidence; never manufacture a time |
Pagination, rate limits and tenant fairness matter when reconciling many merchants. Give each merchant a bounded budget, checkpoint progress and prioritize stale unknown outcomes over recent healthy shipments.
Observability that helps operators
Expose shipment ID, order reference, carrier reference, source event ID, pickup instant, source timezone, command state, attempt count and last read-back result. Track:
- ready-to-pickup age;
- verified pickup lag from warehouse-ready time;
- pickup updates awaiting read-back;
- unknown remote outcomes;
- timestamp conflicts by source;
- shipments delivered without pickup evidence;
- reconciliation backlog age.
Avoid logging customer phone numbers, complete addresses, bearer tokens, labels or raw payloads in unrestricted logs. Link operators to access-controlled evidence instead.
Best practices and anti-patterns
Best practices
- Capture the pickup at the physical or carrier custody boundary.
- Preserve the original event, timezone and verification result.
- Use one durable command per accepted pickup observation.
- Send
statusfrom a fresh, owned state transition. - Read the shipment back after writes and after unknown outcomes.
- Reconcile Salla, carrier and warehouse evidence on a schedule.
- Record manual corrections with actor, reason and previous value.
Anti-patterns
- Setting pickup time to
now()when the synchronization job runs. - Treating label creation or pickup scheduling as actual custody.
- Letting a duplicate webhook create another remote mutation.
- Overwriting a trusted carrier time with a later manual timestamp.
- Retrying a timed-out PUT blindly.
- Assuming every datetime string carries an offset when the contract does not say so.
- Using pickup as proof of delivery, settlement or inventory completion.
Implementation checklist
- Add an immutable pickup-observation type and source precedence policy.
- Normalize provider time to UTC while retaining the raw value and timezone.
- Validate shipment mapping and temporal invariants.
- Create an idempotent Salla update command.
- Submit
actual_picked_up_atwith the required shipmentstatusundershipping.read_write. - Read Shipment Details and close only on observed convergence.
- Reconcile missing, conflicting and unknown outcomes.
- Monitor handoff lag without exposing customer or credential data.
Related reading: Recoverable Salla shipment state machines, Reliable Salla delivery promises, Salla and Zid webhook recovery, and the e-commerce engineering hub.
Primary references
- Salla Merchant API changelog
- Salla — Update Shipment Details
- Salla — Shipment Details
- Salla — List Shipments
- Wikimedia Commons — Loading palletized cargo inside a shipping container
- Creative Commons Attribution 4.0
Official references
These references document the tools discussed. Examples and design decisions are illustrative and should be adapted to the project and its versions.
Prepared by: Noor Yasser
Working through a similar engineering challenge?
I help teams turn architecture decisions into a clear scope and dependable, reviewable implementation.




