(Fulfilment? Fulfillment?)
Anyways, since I started with Shopify clients, I have observed many of them fulfill orders the same way:
- They log into the dashboard
- Check the order
- Manually copy the address into a separate shipping portal like Shippo
- Generate a shipping label
- Download it
- Print it
- Finally, manually send a confirmation email to the customer
Repeat for every order.
It works, until it doesn't. When you're doing 50 orders a day, one person can't keep up, and mistakes start to cost you real money.
Here's how you can automate the whole thing with 3 APIs.
The workflow
Order placed on Shopify → Shippo generates the shipping label automatically → Resend sends the customer a confirmation email with tracking info.
Log in once or twice a day to review your dashboard. Everything else has already been done for you.
API #1 — Shopify (your system of record)
Shopify is where the order lives.
Rather than polling for new orders, you subscribe to the orders/create webhook topic, which fires a POST to your endpoint the moment a customer checks out.
POST https://{shop}.myshopify.com/admin/api/2025-01/webhooks.json
{
"webhook": {
"topic": "orders/create",
"address": "https://your-app.com/webhooks/orders",
"format": "json"
}
}
The payload gives you everything: customer name, shipping address, line items, order ID.
That's the input for the next step.
Tips: As of April 2025, Shopify requires new public apps to use the GraphQL Admin API. If you're building a private or custom app, the REST endpoint above still works fine.
API #2 — Shippo (shipping label generation)
Shippo connects to 85+ carriers and gives you a single API to generate labels across all of them.
Pricing is pay-as-you-go, labels start at around $0.05 per label fee on top of the carrier rate.
You call it in two steps: create a shipment object (which returns available rates), then purchase the label against your chosen rate.
Step 1 — Create shipment, get rates
POST https://api.goshippo.com/shipments/
{
"address_from": { ...from Shopify store settings },
"address_to": { ...from Shopify order payload },
"parcels": [{ "length": "10", "width": "8", "height": "4",
"distance_unit": "in", "weight": "2", "mass_unit": "lb" }]
}
Step 2 — Purchase label
POST https://api.goshippo.com/transactions/
{
"rate": "<rate_object_id from step 1>",
"label_file_type": "PDF",
"async": false
}
The response gives you label_url (the printable PDF) and tracking_number. Both go into the next step.
API #3 — Resend (customer notification)
Resend is a developer-first transactional email API. Free tier covers 3,000 emails/month, no daily cap on paid plans, and the API is genuinely one of the cleanest out there right now.
You fire a single POST once you have the tracking number from Shippo:
POST https://api.resend.com/emails
{
"from": "orders@yourstore.com",
"to": ["customer@email.com"],
"subject": "Your order is on its way 📦",
"html": "<p>Hi [name], your order has shipped. Track it here: [tracking_url]</p>"
}
Tips: Using the same endpoint, you can fire a second email asking for a review 48–72 hours later.
How Everything Works Together
Your app listens on a webhook endpoint.
When a customer creates a new order, Shopify fires orders/create, where you extract the shipping address, call Shippo to generate a label, then call Resend with the tracking number.
The whole chain runs in a few seconds.
A quick note on LLMs: if your catalog has inconsistent product weights or dimensions (common with handmade or variable goods), an LLM can sit between Shopify and Shippo to infer parcel specs from product descriptions — removing the last bit of manual input. Worth knowing, but not required to get started.
How about Shopify's built-in tools?
Shopify does have native shipping and email notification features, they work fine for the average merchants who are just getting started.
Once your order volume hits a certain threshold, you will need to customize the logic, rate-shop across carriers programmatically, or plug in your own notification timing and content.
All of these cannot be done easily without an app or a paid plan upgrade.
Building it yourself with these three APIs gives you full control and costs less at volume.
Final note: What this doesn't cover
Admittedly, inventory sync, returns, and international customs are separate problems that are not covered here.

Top comments (1)
Really nice example of breaking a Shopify workflow into separate API-driven steps. I like that each service has a clear responsibility instead of putting the entire process inside Shopify.
The same pattern can be useful beyond order fulfilment. For example, a custom Shopify form can act as the starting point, with the submission sent to an external API and then passed through whatever business logic is needed, CRM updates, email notifications, data storage, or internal processing.
I also like the webhook approach here. Having Shopify trigger the workflow when an event happens is much cleaner than constantly polling for changes. Once multiple services are involved, keeping those responsibilities separated can make the overall system much easier to extend and maintain.
The interesting part is that the same API-first architecture can support quite a few Shopify workflows, not just fulfilment.