API integration for a logistics operation

Case study. Systems that didn't talk to each other, connected with an API layer and webhooks so data is entered once. Client details withheld for confidentiality.

At a glance

  • Client: a logistics operation running on several systems, internal and partner-owned
  • What they needed: orders, bookings, status updates and invoices flowing between systems automatically, instead of staff re-keying them
  • Result: 40% less manual data entry, faster order processing
  • My role: lead developer, contractor

The brief

Orders arrived in one system, were booked with a carrier in another, tracked in a third and invoiced in a fourth. At each hop someone copied the details across by hand. Each copy was a chance for a typo, and each queue of copying was a delay in getting orders moving.

The job was to make the systems talk to each other directly, and to make that connection dependable: if a partner's system is down for an hour, nothing should be lost, and someone should be able to see exactly what happened.

See it in action

A live illustration with sample data. The names, figures and addresses are invented, and these are not the client's screens.

Event flowlive events per minute 1,2841,2851,286 today · 99.6% first time RECEIVEDMAPPEDSENTCONFIRMEDATTENTION · 0ATTENTION · 1 nothing needs attention order.createdSO-20483 · from internal system shipment.bookedSO-20480 · carrier webhook status.updatedSO-20466 · carrier webhook invoice.readySO-20441 · nightly batch order.created · SO-20479from internal system400 · address line too longresent · confirmed Today1,276 confirmed first time · 7 retried automatically · 1 needed a person · 0 lost Operator fixes the addressResend Each row is one event on its way through the integration. It is received, translated into the partner's format, sent, and confirmed. If a partner rejects it, it waits in Attention with the reason; an operator fixes the field and resends, and it rejoins the flow. Nothing is lost, and the audit log keeps every attempt. Event flowlive events per minute 1,2841,2851,286 today · 99.6% first time the view follows the rejected event → RECEIVEDMAPPEDSENTCONFIRMEDATTENTION · 0ATTENTION · 1 nothing needs attention order.createdSO-20483 · from internal system shipment.bookedSO-20480 · carrier webhook status.updatedSO-20466 · carrier webhook invoice.readySO-20441 · nightly batch order.created · SO-20479from internal system400 · address line too longresent · confirmed All events flowingnothing needs attention SO-20479 rejected by the carrieroperator fixes the address and resendsResend Today1,276 confirmed first time · 7 retried · 1 needed a person · 0 lost
Live: events glide along their lanes from received to confirmed. One is rejected by a partner, an operator fixes the field and resends it, and it rejoins the flow. Sample data.

What I built

REST API layer

One API in front of the internal system that partners and other tools talk to, so no partner needs to know how the internal system works.

Webhook handlers

Partners push changes the moment they happen (a booking confirmed, a shipment scanned) and the update shows up in the other systems in seconds.

Data mapping and validation

Each system has its own idea of an order. The layer translates between them and rejects anything malformed before it can cause trouble downstream.

Retries and error handling

If a destination is down, the event waits and is retried with increasing gaps. Nothing is lost; a partner outage becomes a delay instead of a missing order.

Audit log and monitor

Every event is recorded with its attempts and outcome, and the few that exhaust their retries are surfaced for a person to resend or resolve.

Serverless, so it scales and sleeps

Running on Cloudflare Workers with Supabase for storage, the layer handles bursts without provisioning and costs almost nothing when quiet.

Technology

TypeScriptCloudflare WorkersSupabaseREST & webhooks

Outcome

Manual data entry fell by 40% and orders move faster, because the hand-offs between systems happen in seconds rather than when someone gets to them. When something does go wrong at a partner, the team sees it on the monitor instead of discovering it from a customer.

Need something similar?

If your team re-keys the same information into more than one system, that is exactly the problem an integration layer removes. Get in touch.