Skip to content

Technical

Components

Addon Manual SMS uses the following different components in Lime CRM:

  • Web components
  • Custom endpoints
  • Lime Marketing
  • Task Handler
  • Data structure
  • Security policies
  • Lime Bootstrap apps
  • Actionpads
  • Runtime configuration in Lime Admin
  • Application configuration

How it works — SMS lifecycle & statuses

When an SMS is sent, the addon creates one SMS sendout and one SMS recipient per receiver, and both move through a series of statuses as the work progresses.

The flow is:

  1. The send_sms endpoint creates the sendout in Lime (status created) and a matching SMS message in Lime Marketing.
  2. A background task (Lime task handler) creates and validates the recipients, and moves the sendout to init:
    1. One recipient object is created per receiver in Lime, each in status init. At this point the recipient exists in Lime but hasn't been handed to Lime Marketing yet.
    2. A recipient list is created in Lime Marketing and all recipients are imported into it (with their phone numbers and merge variables). This happens before the sendout is actually sent.
    3. The addon reads the imported list back from Lime Marketing and reconciles it against the Lime recipients. For each recipient: if its phone number was imported successfully, it stores the Lime Marketing recipient id and sets the status to queued; if the phone number is missing from the imported list (e.g. invalid format), it sets the status to failed.
  3. Lime Marketing sends the messages and reports progress back through webhooks, which update the statuses (sending/finished on the sendout, sent/delivered on the recipients).

Webhooks only ever move a status forward — a later webhook can never downgrade a status that is already further along.

Sendout statuses

Status Meaning When it's set Why it could be stuck here
Created The sendout and the Lime Marketing message have been created, but the background task hasn't run yet. By the send_sms endpoint. The Lime task handler isn't running, or the background task failed immediately (e.g. missing addon config).
Initialized The background task created the recipients and handed the list to Lime Marketing. Waiting for sending to start. By the background task once recipients are queued. The task failed before/at the hand-off to Lime Marketing, or the send_started webhook never arrived.
Sending Lime Marketing has started sending. By the send_started webhook. The send_finished webhook never arrived. Large sendouts can also legitimately stay here a while.
Finished Lime Marketing finished processing all sends. This is the final status. By the send_finished webhook. — (final status)
Failed Exists as an option but is never set automatically by the addon. A failed background task leaves the sendout in Created/Initialized, not Failed.

Recipient statuses

Status Meaning When it's set Why it could be stuck here
Initialized The recipient object was created in Lime but not yet handed to Lime Marketing. By the background task when creating recipients. The background task failed before reaching the hand-off to Lime Marketing.
Queued The phone number was accepted and imported into Lime Marketing. By the background task after syncing the list with Lime Marketing. The message was never actually sent (task failed at the send step), the sent webhook never arrived, or the message genuinely failed at the operator (no failure webhook is sent — see below).
Sent The message reached Lime Marketing's SMS service. This is not a delivery guarantee. By the sent_to_recipient webhook. The delivered_to_recipient webhook never arrived — the operator doesn't return delivery receipts, or the message was dropped after the sent webhook (e.g. by downstream sender-ID/country filtering, which shows as blocked in Lime Marketing).
Delivered The recipient's device confirmed delivery. This is the final status. By the delivered_to_recipient webhook. — (final status, operator-dependent)
Failed The phone number was invalid or didn't match anything in the Lime Marketing import. This is terminal. By the background task during the recipient import sync. — (terminal; no webhook ever changes it)

Why a status can get "stuck"

A status stops advancing whenever the next step in the chain doesn't happen. The most common causes:

  • The Lime task handler isn't running or is busy — the background task never starts or never finishes, so the sendout stays in Created/Initialized and recipients stay in Initialized.
  • The background task failed partway — depending on where it failed, recipients may be missing entirely, stuck in Initialized (never handed off), or stuck in Queued (handed off but the send step failed). The sendout stays in its current status.
  • The integration settings in Lime Marketing is misconfigured (wrong URL or API key) — Lime Marketing sends, but the addon never hears about it, so the sendout stays in Initialized/Sending and recipients stay in Queued/Sent.

Two things the status can't tell you

There are no failure webhooks from Lime Marketing — only success ones (sent, delivered). This means a message that genuinely failed at the operator stays in Queued or Sent forever. Queued/Sent is therefore not proof of success, and the absence of Delivered does not prove the message failed.

A sendout is never set to Failed automatically. If the background task throws, the sendout is simply left in Created or Initialized. Check the task handler and web server logs to confirm whether a sendout actually failed.

Sent means "handed to Lime Marketing's SMS service" — not "sent to the phone". Downstream sender-ID/country filtering can drop a message after the sent webhook has already fired (for example an unregistered sender ID for a country that requires registration, such as Finland). Because no non-delivery report is sent back, such a recipient stays in Sent in Lime CRM and never reaches Delivered — the addon can't tell it was dropped. In Lime Marketing the same recipient is shown with status blocked, so that's where you can confirm it.

Custom adjustments

Handle phone numbers

Phone numbers expects the current format: +<COUNTRY_CODE>701234567 i.e. +46701234567

The format of a phone number is quite strict. So if the phone numbers in your solution don't follow the same strict rules we recommend you to write your own custom formatting.

You can in a custom limeobject on your limetype containing the phone number. Set the formatted version of the phone number in a hidden field or maybe just replace the phone number if you'd like.

Here's one example on how it could look if you always expects the phone number to be swedish.

def format_phone_number(phone_number: str):
    valid_chars = [
        '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', '+'
    ]
    formatted_phone_number = ''.join([
        c for c
        in phone_number
        if c in valid_chars
    ])
    if (
        len(formatted_phone_number) == 10
        and formatted_phone_number.startswith('0')
    ):
        return f'+46{formatted_phone_number[1:]}'

    return formatted_phone_number

Table and Field Definitions Lime CRM

smssendout (SMS sendout)

Field name Suggested local name(en/sv) Field type Description
name Name/Namn Text field (32 characters) ReadOnly
message Message/Meddelande Text field (4000 characters) ReadOnly
send_date Send date/Utskicksdatum Time field Default value getdate().ReadOnly
smssendoutstatus Sendout status/Utskicksstatus Option field Option keys (finished, failed, init, sending, created (default)) ReadOnly
bw_sms_message_id SMS Message ID/SMS-meddelande ID Integer field The SMS message ID from Lime Marketing ReadOnly
smsrecipient Recipient/Mottagare relation (1:n smssendout-smsrecipient) Relation tab to the SMS recipients, a SMS sendout can have many SMS recipients ReadOnly

smstemplate (SMS template)

Field name Suggested local name(en/sv) Field type Description
name Name/Namn Text field (256 characters)
inactive Inactive/Inaktiv Yes/No field
fortable For table/Mot tabell Text field (256 characters), (Make sure to add empty option if the customer is using the desktop version)
default Default/Standardvärde Yes/No field
message Message/Meddelande Text field (1024 characters)

smsrecipient (SMS recipient)

Field name Suggested local name(en/sv) Field type Description
smssendout SMS sendout/SMS-utskick Relation field ReadOnly
smsrecipientstatus Delivery status/Leveransstatus Option field Option keys (init, queued, delivered, failed, sent) ReadOnly
bw_smsrecipient_id Recipient ID/MottagarID Integer field The SMS recipient ID from Lime Marketing ReadOnly
phoneno Phone number/Telefonnummer Formatted text field (128 characters) ReadOnly

Permissions

If the solution is using Object Access make sure that the API user is a member of a group with access to the data that should be available for the integration to use

Policy name R W A D Apply to
tbl_smssendout smssendout table
tbl_smsrecipient smsrecipient table
tbl_smstemplate smstemplate table
tbl_xyz xyz table if relation to xyz exists and is used on smsrecipient