For logistics

Every parcel speaks for itself.

Your system already knows when a parcel is picked up, out for delivery, attempted or delivered. One API call per event turns that into a WhatsApp, SMS or email message to the consignee — and hands you back a delivery status you can store against the consignment.

One endpoint, three channelsDelivery status back per messageRetries that never double-send
The QuickGrow API reference open in the product: the endpoint list beside the request and response for a send.

The status exists. It just never leaves your system.

A courier operation is already full of events: a scan at pickup, a bag assigned to a hub, a rider out on a route, an attempt that failed, a delivery signed for. Every one of those is a moment the consignee wants to hear about, and almost none of them reach anybody outside the operations screen.

The hotline

Your call centre is the tracking system

People phone because nothing told them. Every agent-minute spent reading a status off a screen is a minute the same screen could have sent by itself, for a fraction of the cost.

The rider

The rider is doing your messaging

Calls from a personal number before every drop. Nothing is recorded, the merchant cannot see what was said, and the customer has no thread to look back at.

Failed attempts

A second attempt costs you twice

A parcel goes out, nobody is home, it comes back. A message before the rider arrives — and one asking for a better time after a failed attempt — is the cheapest way to stop paying for the same delivery again.

One call per parcel event.

There is one send endpoint for all three channels. You choose the channel per event, address the consignee, and either write the message inline or point at a stored template and pass the values. Nobody on your side opens a dashboard.

  1. Create a key

    Settings → Developer API issues a key with its own scopes: sending, reading messages, contacts, templates, delivery statistics. Grant only what your integration uses, and issue a fresh key and revoke the old one whenever you like.

  2. Post the event

    Your system sends one request per parcel event — channel, phone number or email, and the content or the template id with its values. Attach your consignment number and the request comes back carrying it.

  3. Read the answer

    The response carries a message id and a status straight away. Email completes on the call itself; SMS and WhatsApp come back queued and move on from there. You can ask for that id again any time.

  4. Get told when it lands

    Register your own endpoint and QuickGrow calls you back when the message is sent, delivered, bounced or failed, so the consignment record updates without anybody polling.

POST /api/v1/messages
X-API-Key: mk_...

{
  "channel": "whatsapp",
  "to": "+8801700000000",
  "templateId": "out-for-delivery",
  "variables": {
    "name": "Rahim",
    "parcel": "CN-884213",
    "window": "2pm - 5pm"
  },
  "tags": ["out_for_delivery"],
  "metadata": { "consignmentId": "CN-884213" }
}
201 Created
{
  "data": {
    "id": "9f2a...",
    "channel": "whatsapp",
    "status": "queued",
    "to": "+8801700000000",
    "tags": ["out_for_delivery"],
    "metadata": { "consignmentId": "CN-884213" },
    "createdAt": "2026-08-23T09:00:00.000Z",
    "sentAt": null,
    "deliveredAt": null,
    "failedAt": null,
    "failureReason": null
  }
}

Anything you put in metadata comes back untouched — on the response, on a later status read, and on every callback. Put the consignment number there and you never have to keep a second table mapping message ids to parcels.

A different event wants a different channel.

All three run off the same endpoint and the same key, so choosing per event costs you one field. WhatsApp comes through the official Meta Cloud API from your business profile; SMS goes out under a branded sender name if you buy Masking volume; email carries the paperwork.

Utility is the WhatsApp category order and delivery updates fall under. Meta bills you directly per message, at Meta's own rate, with no markup from QuickGrow.
WhatsAppSMSEmail
Fits these eventsOut for delivery, rider assigned, delivered, failed attemptPickup confirmed, delivery window, any event that must land on a basic handsetMerchant manifests, invoices, proof of delivery, weekly summaries
Arrives without mobile internetNoYesNo
Consignee can reply, and someone can answerYesYesYes
Shows your brand as the senderYour WhatsApp business profileA branded sender name with Masking SMSYour own verified domain
Needs a template approved by Meta firstYesNoNo
Can carry a fileNoNoUp to 10 attachments, 7 MB in total
Sold asBilled by Meta directly, per category: Utility, Authentication and MarketingMasking and Non-Masking, each on its own volume sliderBulk and transactional — your own mail server or ours

You find out whether it arrived.

A send is not the same as a delivery, and a courier of all businesses knows the difference. Every message keeps its own status, and the timestamps that go with it.

A report comparing email, WhatsApp and SMS delivery results side by side over the same period.
Per message, and in total

Queued, sent, delivered — or failed, with a reason

Ask for one message by its id and you get its current status with the moment it was sent, the moment it was delivered, and — if it went wrong — the reason and the code the provider gave. Ask for the list instead and filter it by channel, by status, or by date.

  • Statuses you will actually see: queued, sending, sent, delivered, opened, clicked, bounced, failed
  • A failed message carries a reason and a code, not just a red mark
  • One call returns delivery statistics per channel over a date range, so you can compare WhatsApp against SMS on the same window
POST https://ops.yourcourier.com/hooks/quickgrow
{
  "id": "evt_5c1d...",
  "event": "message.delivered",
  "createdAt": "2026-08-23T09:00:31.412Z",
  "data": {
    "message": {
      "id": "9f2a...",
      "channel": "whatsapp",
      "status": "delivered",
      "to": "+8801700000000",
      "metadata": { "consignmentId": "CN-884213" },
      "deliveredAt": "2026-08-23T09:00:31.106Z"
    }
  }
}

Four callbacks, and nothing else

Register an endpoint in the portal and subscribe it to the events you want: the message was sent, it was delivered, it bounced, it failed. Only messages sent through the API raise them, so a marketing campaign never floods your operations system.

  • Every callback is signed with a secret only you and QuickGrow hold, so your endpoint can prove where it came from
  • A callback your server misses is retried five times over roughly half an hour
  • Every attempt is logged in the portal with the response your endpoint gave, and you can fire a test one whenever you like
  • If you would rather not take callbacks at all, ask for the message id again and read the same status

Retries that never double-send.

A sorting-hub integration will fire the same event twice sooner or later — a timeout, a replayed queue, a retried job. Put your own key on the request and a repeat within 24 hours replays the first response instead of sending a second message. The consignee gets told once.

Duplicates

Repeat calls replay

Use the consignment number and the event name as your key. Send it again and you get the original message id back, marked as a replay, with nothing new going out.

Errors

Failures you can branch on

Every error comes back with a stable code — a bad phone number, a template that does not exist, not enough balance, the rate allowance exhausted — so your retry logic reads the code, not the wording.

Rate

A per-minute allowance

Each key carries its own request limit per minute, and every response reports the limit, what is left, and when the window resets. A peak-hour burst tells you to slow down instead of failing silently.

Access

Scoped keys

A key that only sends cannot read your contacts. Issue one per system — hub scanner, rider app, merchant portal — and switch one off without touching the others.

The reply comes back to a person, not a dead number.

An update the customer cannot answer just moves the call to a different hour. When a consignee replies to a WhatsApp or SMS update, the reply opens a thread your team can actually work.

A WhatsApp thread about a parcel open in the shared inbox, with the contact record, tags and assignee alongside it.
Shared inbox

One inbox for all three channels

WhatsApp, SMS and email threads land in the same place, next to the contact record and its tags. Anyone rostered can pick a thread up, assign it, answer it and resolve it — instead of the whole thing depending on whoever holds the phone.

  • A reschedule request becomes a thread with a name on it, not a call nobody logged
  • When someone messages you on WhatsApp, you have 24 hours to answer in your own words before you need an approved template again
  • A chatbot can take the routine question first and hand over to a person when it cannot

The rest of the endpoints, while you are here.

Sending

  • One send endpoint for email, SMS and WhatsApp
  • Write the message inline, or store a template and pass values into it
  • Placeholders filled per parcel — name, consignment number, delivery window

Reading

  • Ask for one message by id and get its status and timestamps
  • List messages filtered by channel, status or date range, a page at a time
  • Delivery statistics per channel over any window you ask for

Running it in production

  • Keys created, scoped, revoked and deleted in the portal, sent as a header
  • Errors in one shape, with a stable code and a link to the reference
  • Callbacks with a signing secret, delivery logs and a test send

What it costs to start.

Two parts: a platform fee, and the messages you send. Buying managed volume on SMS and email waives part of the platform fee, and buying enough waives it entirely. WhatsApp carries no fee of ours at all — Meta bills you directly for it, at Meta's own rate. Already have an SMS account or a mail server of your own? Bring it and pay the platform fee only. A longer billing term discounts both, on separate ladders.

The prepaid wallet card in billing settings, showing the balance in taka and the top-up control.
Prepaid wallet

Top up in taka, cover the overflow

Before you know your real SMS and email volume, set the sliders low and let the wallet catch the rest: sends beyond what you bought are billed at the base rate from the balance. Move the sliders up once the parcel count settles. WhatsApp has no slider and no wallet — Meta bills you directly for it, at Meta's own rate, with no markup from QuickGrow. Volume and prices for SMS and email are in BDT throughout.

  • Start on one channel and add the others when the integration is ready
  • An SMS or email send with no balance behind it fails with a clear code rather than disappearing
  • Refer another operator to QuickGrow and you both earn credit

Before you wire anything up.

How much do we have to build?

One HTTPS request per parcel event, with your key in a header. There is one send endpoint for all three channels, so the difference between an SMS and a WhatsApp update is a single field. If you want the delivery outcome pushed back to you, add an endpoint of your own and subscribe it in the portal — otherwise you can ask for the message id again whenever you need the status.

What happens if our system fires the same event twice?

Put a key of your own on the request — the consignment number and the event name work well. A repeat of that key within 24 hours replays the original response and marks it as a replay, so no second message goes out. Reuse the same key against a different endpoint and you get a clear conflict error rather than a surprise send.

How do we know a message actually reached the consignee?

Each message keeps its own status: queued, sending, sent, delivered, opened, clicked, bounced or failed, with the timestamp for each step it reached. A failure carries the reason and the provider code. You can read that by message id, list messages filtered by channel and status, or have QuickGrow call your endpoint when a message is sent, delivered, bounced or failed.

Let the parcel do the talking.

Create a key, send one message from your staging hub, and watch the delivery status come back before you touch the production integration.