Akedly

Utilities

Send one-way transactional messages — order confirmations, shipping updates, appointment reminders — from your backend. Utilities run on your own connections: WhatsApp goes out over your own WhatsApp Business Account, and SMS over your own BYO SMS provider.


Get set up

Utilities is configured once in the dashboard, then driven by a single API call. Five one-time steps — connect at least one channel — then you send.

1. Connect your WhatsApp Business Account

Utility WhatsApp messages go out from your own WABA — never a shared Akedly number — so recipients see your brand. Connecting uses Meta's Embedded Signup and takes about two minutes; the full guide is under Channels.

Skip this only if you will send over SMS exclusively.

View in dashboardChannels → Setup → WhatsApp Setup

Connect your WhatsApp Business Account.

2. Connect your own SMS provider (BYO SMS)

Utility SMS dispatches exclusively through your own SMS provider. If you are building the integration yourself, add and test one under Channels → Setup → BYO SMS Setup, then set the per-country routing that decides which destinations SMS can reach — per-country chains, or an ALL catch-all. If Akedly operates a managed Vodafone integration for you, the request chain is built for you and its coverage is fixed to Egypt — there is no routing for you to set, but three setup steps are still yours — its credentials, its approved sender name, and acknowledging that Vodafone has whitelisted Akedly's outbound IPs — and it must then pass its activation test before it sends. See BYO SMS for how an integration is built, tested and routed.

Skip this only if you will send over WhatsApp exclusively. Without an active, tested BYO integration, SMS cannot be enabled on a template or a pipeline and no number is reachable over SMS.

View in dashboardChannels → Setup → BYO SMS Setup

Connect your SMS provider and set its per-country routing. Not on a managed Vodafone integration — its provider and Egypt-only routing are fixed and cannot be edited.

3. Create a utility pipeline

A pipeline is your sending policy — channels, allowed destination countries, rate limits, and a spend cap. Create one under Utilities → Pipelines. Its pipelineID is what every API call references. Utility pipelines are separate from OTP pipelines.

Once created, configure the pipeline's Basic details, Request signing, Sending config and Webhooks sections.

Sending config is where channels, their order, the WhatsApp→SMS fallback, the Allowed countries (WhatsApp) list and your daily spend cap live. SMS stays disabled until BYO SMS routing resolves on for that pipeline — a connected and tested integration is necessary but not sufficient. Enabling SMS without it returns UTILITY_SMS_REQUIRES_BYO. See Enable on pipelines & cloning.

Webhooks is where you set the callback URL and reveal the whsec_ signing secret.

4. Create and approve a template

Write your message once as a template with {{variable}} placeholders, then submit it. Every template needs Akedly approval; WhatsApp additionally needs Meta approval. A template you can send with right now is a sendable template — see Templates and dual approval.

5. Reveal your request-signing secret

Reveal the request-signing secret once from the pipeline's settings and store it like a password. Your backend uses it to sign every API call; see Request Signing.

6. Send your first message

With a sendable template, send a single signed POST to /utilities/send.


Utilities vs OTP

A utility message is one-way: Akedly sends it and reports as much of the outcome as the channel gives us — WhatsApp reports the whole post-send stream (sent, delivered, read and failed — a failure carries a reason when Meta supplies one, and null when it does not); a BYO SMS send is final once your provider accepts it. There is no verify step.

AspectUtilitiesOTP
PurposeNotify — confirmations, updates, remindersVerify — the user proves possession of the number
FlowOne call: sendCreate, send, verify
ChannelsWhatsApp (your own WABA), SMS (your own BYO provider)WhatsApp, Telegram, SMS, Email with fallback
Who can receiveAny valid number, subject to channel and suppression checksAny number the user submits
ContentApproved templates (free text on SMS)OTP codes
BillingPer message; WhatsApp billed on deliveryPer message, or PPSA on V2.0

Utility pipelines and OTP pipelines are separate. A utility send must reference a utility pipeline — calls against an OTP pipeline are rejected with NOT_A_UTILITY_PIPELINE.


How a send works

Every send is a single POST to https://api.akedly.io/api/v1/utilities/send, authenticated by your API key and pipeline ID in the body and signed with your pipeline's request-signing secret. Akedly then:

  1. Verifies the request signature and applies your pipeline's rate limits.
  2. Resolves the channel — the first feasible channel in the pipeline's channel order (WhatsApp first by default): WhatsApp over your own WABA when the template and destination allow it, SMS over your own BYO integration when its routing resolves for the destination.
  3. Sends, records the message, and bills it. WhatsApp delivery and billing settle asynchronously when Meta reports the delivery outcome.

The response carries a transactionID you can track in the dashboard's Send History.


Opt-out and suppression

Every utility WhatsApp template automatically carries a "Stop receiving these" quick-reply button — you do not add it, and you cannot remove it.

When a recipient taps it, that number is suppressed account-wide: across every pipeline and both channels, not just the pipeline that sent the message.


Channels

Both channels run on connections you own. Setting them up is documented under Channelsyour WhatsApp Business Account and your own SMS provider. This section is what a utility send needs from each of them.

WhatsApp — primary

Sent over your own WhatsApp Business Account, nationally and internationally. A WhatsApp send requires:

  • WhatsApp enabled on the pipeline
  • A Meta-approved, WhatsApp-usable template
  • An active connected WABA
  • The destination country in the pipeline's allowed-countries list

Delivery is confirmed asynchronously by Meta, and billing settles on the delivery outcome.

SMS — your own provider

Utility SMS dispatches exclusively through your own BYO SMS integration (Channels → Setup → BYO SMS Setup); the send response reports provider: "own-sms". An SMS send requires:

  • SMS enabled on the pipeline and the template
  • An active, tested BYO SMS integration
  • The destination covered by your BYO country routing — a per-country chain, or an ALL catch-all

For an integration you build yourself there is no Egypt restriction and no Akedly-operated SMS route: coverage is whatever your own routing covers. (A managed Vodafone integration is fixed to Egypt.) This is also the only channel that accepts free-text sends (a text body instead of a template).

Note the two channels gate geography differently. WhatsApp is checked against the pipeline's allowed-countries list (default-deny); SMS is not — its reach is decided purely by your BYO country routing. Adding a country to the allowlist therefore does nothing for SMS, and a country absent from it can still be reachable over SMS.

The two routing failures you will hit most return 409: no usable BYO integration at all gives UTILITY_SMS_REQUIRES_BYO, while an integration that exists but has no chain for the destination gives UTILITY_SMS_COUNTRY_NOT_ROUTED. The second is the one to expect when you expand into a new market — on an integration you built, add a country chain or an ALL catch-all to clear it; a managed Vodafone integration is fixed to Egypt and cannot be widened. These are not the only ways an SMS send can be refused: SMS must also be enabled on both the pipeline and the template, and a managed provider that is selected but not ready returns UTILITY_SMS_PROVIDER_NOT_READY rather than silently falling through to another provider. The channel errors table lists the codes you are most likely to hit.

The channel is resolved before sending, and by default a send goes out on exactly one channel with no cross-channel retry. A pipeline can opt in to a WhatsApp → SMS fallback (utilityConfig.smsFallback, off by default): with it on, an eligible failed WhatsApp delivery is re-rendered as SMS and dispatched over your BYO chain. Eligibility is narrower than “any failure”: the first error Meta reports on the failed delivery must be one of the two fallback codes — 131026 (the recipient cannot receive it) or 131042 (a business eligibility or payment-method problem) — and a fallback code in a later position is not checked. Nothing else falls back: a template that is not approved or unavailable (131045), a spam rate limit (131048) and a WABA on hold (131057) are all terminal. The send must also be a live (non-test) one to a recipient you have not suppressed, and your BYO routing must resolve for the destination — a country chain that covers it is necessary but not sufficient, and a managed Vodafone integration whose readiness no longer holds refuses to route even inside Egypt; and even then the fallback is abandoned if the SMS fee cannot be reserved against your utility budget, if the template fails to re-render as SMS, or if your provider does not accept the dispatch. It is billed as an SMS only once your provider has accepted it. When both channels are feasible up front, the pipeline's channel order decides; the default is WhatsApp first.


Templates and dual approval

Templates are the message content: a body with {{variable}} placeholders your send call fills in. A template can also carry a text header (up to 60 characters, at most one variable), a footer (up to 60 characters, no variables), and buttons — up to two URL buttons, one phone-number button, and quick replies, of which up to three may carry a stable action label. Build these in the template editor.

What a template is made of

The editor walks five sections, and shows a live WhatsApp preview as you type:

  • Basics — the template name and its language.
  • Message — an optional header (bold title, ≤60 characters, may carry one variable), the body (required, where your {{1}}, {{2}} placeholders go), and an optional footer (≤60 characters, no variables).
  • Variables — positional placeholders. The send call fills them in order.
  • Buttons — up to two URL buttons, one phone-number button, and quick replies.
  • Channels — whether this template is usable on WhatsApp, SMS, or both.

If no WhatsApp Business Account is connected, the editor says so at the top: the template can still be written and saved, but WhatsApp sends are blocked until you connect one.

The editor checks your template as you type

A counter in the header shows how many must-fix problems the template currently has. It is a pre-flight check that runs against the same rules Meta applies, so a template that would be rejected is caught before you spend a review cycle on it. Findings come in two kinds:

  • Name
    Must-fix
    Type
    blocking
    Description

    A mechanical rule Meta enforces — a header over 60 characters, a footer containing a variable, too many buttons, a variable with no example value, an unsupported language, a duplicate template name. These are shown against the section that owns them.

  • Name
    Advisory
    Type
    report only
    Description

    Judgement calls that live in the report drawer rather than blocking submit — an unused variable, very dense variable use, wording that reads as prohibited or sensitive, and the category prediction below.

The most useful advisory is "this will probably be re-classed as Marketing" — the linter reads your wording and warns before Meta re-prices the template. See Keeping the template classed as Utility.

Test it before you go live

The editor has a Test & go live panel. Save the template to give it an ID, then send a real message to your own number — or to another valid number — before submitting for review.

Keeping the template classed as Utility

Meta categorises every template. Utility templates are cheaper than Marketing ones and are the only category appropriate for transactional messages — but the category is inferred from your wording, and a single promotional-sounding line flips the whole template.

Every template carries two independent approval tracks:

  • Name
    Akedly status
    Type
    required for any send
    Description

    Every template is reviewed by Akedly before it can be sent — on any channel, no exceptions.

  • Name
    Meta status
    Type
    required for WhatsApp
    Description

    WhatsApp-usable templates are additionally submitted to Meta for approval. A template that is Akedly-approved but not Meta-approved can still send on SMS.

A sendable template is Akedly-approved and, for WhatsApp sends, Meta-approved. Sending with a template that lacks Akedly approval returns TEMPLATE_NOT_APPROVED; a template without Meta approval simply cannot resolve to WhatsApp.


Billing

Utilities are billed per message sent — there is no per-verification pricing.

  • WhatsApp — billing is deferred: the send is accepted immediately but billed only when Meta reports the delivery outcome. Messages that never deliver are not billed.
  • SMS — billed at send time as a flat BYO fee per message, not per segment. The rate resolves most-specific-first: a per-integration override, then your per-account rate, then the global default. Akedly sets every override level. The send response still reports segments and encoding, but they are informational — a multi-segment message costs the same as a single-segment one. They describe how the text was encoded: GSM-7 fits 160 characters per segment (153 once a message spans segments), while Arabic or emoji content switches to UCS-2 at 70 per segment (67 multi-segment). That is why an Arabic message splits at roughly half the length of an English one.

Each pipeline can set a daily spend cap (a BYO-SMS message priced at exactly 0 is exempt from it; WhatsApp is floored at 0.25 EGP and cannot be), and it gates both channels in two stages: a send is rejected with SPEND_CAP_EXCEEDED once the day's spend has already reached the cap, and again — after the message is priced — if reserving its own fee would carry the day past it. WhatsApp is not exempt and is not a special case: it prices the message before dispatch and reserves that exact amount against the cap, even though the message is only billed when Meta reports the delivery outcome.

Was this page helpful?