# LimeCall Documentation

Guides for LimeCall's callback widget, AI receptionist and virtual phone numbers.

LimeCall turns website visitors and inbound callers into booked conversations. It is three products that share one dashboard, one contact record and one bill.

Pick the one you are here for.

<table data-view="cards"><thead><tr><th></th><th></th><th data-hidden data-card-target data-type="content-ref"></th></tr></thead><tbody><tr><td><strong>Callback &#x26; Web Widget</strong></td><td>Put a call button on your site. Visitors ask for a call, LimeCall rings them back and connects both sides in seconds.</td><td><a href="/callback">Callback &amp; Web Widget</a></td></tr><tr><td><strong>AI Receptionist</strong></td><td>An AI voice agent answers your phone around the clock, qualifies the caller, books meetings and hands over to a human when it matters.</td><td><a href="/ai-receptionist">AI Receptionist</a></td></tr><tr><td><strong>Virtual Phone Numbers</strong></td><td>Buy or port local and toll-free numbers, route them to people, teams or your AI, and text from them.</td><td><a href="/virtual-numbers">Virtual Phone Numbers</a></td></tr></tbody></table>

## New to LimeCall?

Start with [Choose your product](/start-here/choose-your-product) if you are not sure which of the three you need, or go straight to a quick start:

* [Quick start: Callback widget](/start-here/quickstart-callback) — a working call button in about 10 minutes
* [Quick start: AI Receptionist](/start-here/quickstart-ai-receptionist) — an AI answering your calls in about 15 minutes
* [Quick start: Virtual number](/start-here/quickstart-virtual-number) — a live business number in about 10 minutes

## Everything else

The three product sections above cover setup and configuration. These sections apply whichever product you use:

* [Inbox, Contacts & Leads](/inbox-and-leads) — where conversations, contacts and leads land
* [Analytics & Reporting](/analytics) — call volume, outcomes and what is converting
* [Integrations](/integrations) — HubSpot, Slack, Zapier, Make, Google Calendar and webhooks
* [Account & Billing](/account) — plans, credits, invoices, team and security
* [Developers](/developers) — the REST API and webhook events
* [Troubleshooting](/troubleshooting) — when something is not behaving

{% hint style="info" %}
Your dashboard lives at [app.limecall.com](https://app.limecall.com). Every "open X" instruction in these docs starts there.
{% endhint %}


# Start here

What LimeCall does, which product fits your problem, and how to get your first one running.

LimeCall is three products in one dashboard. They share contacts, conversations, analytics and billing, so anything you set up in one is visible to the others.

| Product                   | The problem it solves                                              |
| ------------------------- | ------------------------------------------------------------------ |
| **Callback & Web Widget** | People visit your site and leave without contacting you.           |
| **AI Receptionist**       | Calls come in when nobody is free to answer them.                  |
| **Virtual Phone Numbers** | You need a business line — local, toll-free or in another country. |

Most accounts end up using at least two. A common combination is a widget on the site that rings the team during business hours, an AI receptionist that answers everything out of hours, and a virtual number on the contact page.

## Read these in order

1. [Choose your product](/start-here/choose-your-product) — a short decision guide if you are not sure where to start.
2. [Create your account](/start-here/create-your-account) — sign up, verify, and what the trial includes.
3. One of the three quick starts below.

## Quick starts

* [Quick start: Callback widget](/start-here/quickstart-callback)
* [Quick start: AI Receptionist](/start-here/quickstart-ai-receptionist)
* [Quick start: Virtual number](/start-here/quickstart-virtual-number)

If a term in these guides is unfamiliar, [Glossary](/start-here/glossary) defines the ones specific to LimeCall.


# Choose your product

A short decision guide across the callback widget, AI receptionist and virtual numbers.

Answer the question that matches your situation.

## "People browse my site but never get in touch"

Use the **Callback & Web Widget**. It adds a button to your site. A visitor enters their number and LimeCall calls them straight back, bridging them to your team or your AI receptionist the moment they pick up. Connection typically happens in under 30 seconds.

Best for: marketing sites, pricing pages, demo requests, high-value B2B enquiries.

→ [Callback & Web Widget](/callback)

## "Calls come in and nobody answers them"

Use the **AI Receptionist**. An AI voice agent picks up, greets the caller in your business's words, answers questions from your knowledge base, qualifies the lead, books into your calendar and transfers to a human when the caller needs one.

Best for: out of hours, overflow when the team is busy, small teams without a dedicated receptionist, clinics, trades, agencies.

→ [AI Receptionist](/ai-receptionist)

## "I need a business phone number"

Use **Virtual Phone Numbers**. Buy a local or toll-free number in the countries you sell into, or port your existing number in. Route each number to a person, a team, voicemail or your AI receptionist. Send and receive SMS on numbers that support it.

Best for: replacing a landline, a dedicated line per campaign or region, keeping personal mobiles private.

→ [Virtual Phone Numbers](/virtual-numbers)

## Can I use more than one?

Yes, and most accounts do. They are designed to combine:

| Combination                      | What it gives you                                                                                       |
| -------------------------------- | ------------------------------------------------------------------------------------------------------- |
| Widget + AI receptionist         | The widget rings your team in business hours; the AI answers callback requests raised overnight.        |
| Virtual number + AI receptionist | Your published business number is answered 24/7 without hiring.                                         |
| Widget + virtual number          | The widget shows a real "call us" number for visitors who would rather dial themselves.                 |
| All three                        | Every inbound route — web, phone, out of hours — lands in the same inbox with the same contact history. |

{% hint style="info" %}
You do not choose at signup. Every account can use all three; what you can use is limited by your plan, not by a product choice. See [Plans & billing](/account/plans).
{% endhint %}


# Create your account

Sign up, verify your email and phone, and what the free trial includes.

## Sign up

1. Go to [app.limecall.com](https://app.limecall.com) and choose **Sign up**.
2. Register with Google or with an email address and password.
3. Confirm the verification link sent to your email.

If you registered with an email address, you must click the verification link before you can buy a number or publish a widget.

## Verify your phone number

LimeCall asks for a phone number you control. This is the number used for:

* test calls while you set things up,
* the fallback destination if a call cannot reach anyone,
* caller ID verification if you later want to show your own number on outbound calls.

You will receive a code by SMS or an automated call. Enter it to complete verification.

{% hint style="warning" %}
Verification is required before outbound calling is enabled. This is a carrier requirement, not a LimeCall setting, and it exists to prevent number spoofing.
{% endhint %}

## Tell LimeCall about your business

The onboarding flow asks for your company name, website and industry. This is not a formality — the answers seed your AI receptionist's knowledge:

* Your **website** is scanned to pre-fill what you do, your services and your opening hours.
* Your **industry** selects a scenario template (home services, dental/medical, legal, real estate, auto/dealership) with sensible questions already written.

You can edit all of it afterwards under **AI Receptionist → Knowledge**.

## What the trial includes

The trial gives you a working account with a limited allowance of calls, AI minutes and messages so you can test every product end to end. Specific allowances and their duration are shown on your **Plan** page, since they change with promotions.

During the trial you can:

* install and publish the widget,
* create and test an AI receptionist,
* make and receive test calls,
* connect integrations.

Buying or porting a phone number requires a paid plan.

## Next

* [Quick start: Callback widget](/start-here/quickstart-callback)
* [Quick start: AI Receptionist](/start-here/quickstart-ai-receptionist)
* [Quick start: Virtual number](/start-here/quickstart-virtual-number)


# Quick start: Callback widget

Get a working call button on your website in about ten minutes.

Goal: a visitor on your site clicks a button, enters their number, and your phone rings within seconds.

Time: about 10 minutes.

## 1. Set where calls should ring

Open **Settings → My calls** and set how calls reach you. Choose **Ring in browser** if you will answer at your desk, or add a phone number to ring instead.

Add your teammates under **Settings → Team** if calls should ring more than one person.

## 2. Set your hours

Open **Settings → Business hours** and set the hours you are open. The widget uses these to decide whether to offer an immediate call or a scheduled one.

## 3. Configure the widget

Open **Widget**. The settings are grouped in tabs:

* **General** — the name shown to visitors and the default behaviour.
* **Appearance** — colour, position, button style and text.
* **Channels** — which options appear: call now, schedule a call, SMS, WhatsApp, email, contact form.

You can leave everything else at its defaults for now.

## 4. Install it on your site

Go to the **Embed** tab and copy the snippet. Paste it immediately before the closing `</body>` tag on every page where the widget should appear.

If you use WordPress, Google Tag Manager or another platform, follow the matching guide:

* [Install with JavaScript](/callback/install-with-javascript)
* [Install on WordPress](/callback/install-on-wordpress)
* [Install with Google Tag Manager](/callback/install-with-google-tag-manager)

## 5. Test it

Open your site in a private/incognito window. The widget should appear within a couple of seconds.

Click it, enter a phone number you can answer, and request a call. That number rings within seconds — answer it, and you are connected to whatever the widget routes to, which is your AI receptionist unless you changed it.

{% hint style="success" %}
If both legs connect, you are done. The call, its recording and a new lead all appear under **Inbox** and **Leads**.
{% endhint %}

## If the widget does not appear

Work through [The widget is not showing](/troubleshooting/widget-not-showing). The usual causes are the snippet being placed on only one page, a caching plugin serving an old copy of the page, or a display rule restricting which URLs show it.

## Next steps

* Brand it: [Appearance](/callback/appearance)
* Control where it appears: [Display rules](/callback/display-rules)
* Capture more detail before the call: [Lead capture](/callback/lead-capture)


# Quick start: AI Receptionist

Get an AI voice agent answering your calls in about fifteen minutes.

Goal: a caller dials your number, an AI answers in your business's voice, handles the enquiry and writes it up.

Time: about 15 minutes.

## 1. Create the assistant

Open **AI Receptionist**. If you have no agent yet, choose **Create agent**.

You are asked for your business type. Pick the closest match — home services, dental/medical, legal, real estate, or auto/dealership — and LimeCall pre-writes the scenarios and qualifying questions for that industry. You can change every word later.

## 2. Check what it knows

Open the **Knowledge** group in the left-hand menu and work down it:

* **Company Details** — your business name and description.
* **Contact Information** — where you are, and when customers can reach you.
* **Products & Services** — what you sell, and the prices it is allowed to quote.
* **Additional Knowledge** — FAQs, policies and files it can draw on.

If your website was scanned at signup, much of this is already filled in. Read it anyway — this is what the AI will tell your customers.

{% hint style="warning" %}
Anything wrong here becomes something the AI says to a real caller with total confidence. Check prices and opening hours before you go live.
{% endhint %}

## 3. Set the voice and opening line

Open **Your Assistant** and set the assistant's name, its language, and the opening message — what the caller hears first.

Open **Voice & Tone** to pick a voice (Olivia, Sophie, Alex, Ethan, Freya or Oscar) and how quickly it replies. **Balanced** suits most businesses; **Patient** is better if your callers are older or tend to pause mid-sentence.

## 4. Decide what it should do

Open **Scenarios**. This is what the assistant actually does on a call — answer questions and take a message, take booking or order details, book into your calendar, or transfer the call.

Open **Transfers & Escalation** and set a number for calls the AI should hand over, plus what it says before connecting.

## 5. Test it

Open **Test your agent** and start a test call from your browser. Talk to it the way a real customer would, including the awkward questions.

Listen for: wrong prices, invented services, opening hours that do not match reality, and whether the transfer works.

## 6. Point a number at it

Open **Phone Numbers**. For any number you own, set **Who answers your calls** to your AI receptionist.

No number yet? See [Quick start: Virtual number](/start-here/quickstart-virtual-number).

{% hint style="info" %}
Recording and AI disclosure requirements vary by country and state. Read [Recording, consent & AI disclosure](/ai-receptionist/recording-consent-and-disclosure) before taking live calls.
{% endhint %}

## Next steps

* Teach it what a good lead looks like: [Lead qualification](/ai-receptionist/lead-qualification)
* Let it book meetings: [Calendar & booking](/ai-receptionist/calendar-and-booking)
* Send call data onward: [Actions & webhooks](/ai-receptionist/actions-and-webhooks)


# Quick start: Virtual number

Buy a business number and route it to your team in about ten minutes.

Goal: a working business number that rings the right person.

Time: about 10 minutes, plus verification time in regulated countries.

## 1. Open the number catalogue

Open **Phone Numbers → Buy a number**. Choose the country, then filter by area code, or by whether you want a local or toll-free number.

Each result shows its capabilities — voice, SMS, MMS — and its monthly price. Not every number does everything; if you intend to text from it, check SMS is listed before you buy.

{% hint style="info" %}
Numbers require a paid plan. If you are on a trial, the catalogue is visible but purchase is disabled until you upgrade.
{% endhint %}

## 2. Buy it

Select the number and confirm. It is attached to your account immediately and is billed monthly from that date.

Some countries require an address or identity document before a number can be issued. If so, you will be sent to **Addresses** and **Verification** to supply them — see [Addresses & verification](/virtual-numbers/address-and-verification). Approval usually takes a few business days.

## 3. Decide who answers it

On the number's row, set **Who answers your calls**. The options are:

| Destination             | What happens                                                        |
| ----------------------- | ------------------------------------------------------------------- |
| **Team member**         | Rings one person.                                                   |
| **Team**                | Rings a group, in the order that group is configured to use.        |
| **Forward to a number** | Rings an external number, such as a mobile or an existing landline. |
| **Voicemail**           | Goes straight to a recorded greeting.                               |
| **AI receptionist**     | Your AI answers, around the clock.                                  |

You can also set a different destination for **When busy** — useful for sending overflow to the AI while your team handles what they can.

## 4. Set the caller ID

Open the **Caller ID** tab and choose what recipients see when you call out. You can set a default for the account and override it per number.

To display a number you own outside LimeCall, verify it first — the same tab walks you through it.

## 5. Test it

Call the number from your mobile. Confirm it rings the destination you configured, and that hanging up produces a call record under **Calls**.

Then call it again and let it go unanswered, to check voicemail or the busy destination behaves as you expect.

## Next steps

* Text from the number: [SMS & messaging](/virtual-numbers/sms-and-messaging)
* Texting US numbers requires registration: [US carrier registration (10DLC)](/virtual-numbers/us-carrier-registration)
* Move an existing number to LimeCall: [Bring your number (porting)](/virtual-numbers/bring-your-number)
* Take calls on a desk phone or softphone: [Devices](/virtual-numbers/devices)


# Glossary

LimeCall-specific terms, defined.

Terms that mean something specific inside LimeCall.

**Agent** — a human user of your LimeCall account who takes calls. Not to be confused with the AI agent.

**AI minutes** — the metered unit for time your AI receptionist spends on calls. Tracked separately from ordinary call minutes and shown under **Settings → Usage & credits**.

**AI receptionist** — the AI voice agent that answers calls on your behalf. Sometimes shortened to "assistant" in the dashboard.

**Assistant** — the configured AI receptionist: its name, voice, knowledge, scenarios and rules.

**Callback** — a call initiated by LimeCall rather than dialled by the visitor. LimeCall dials the visitor, then bridges them to your AI receptionist, a team member or a team.

**Call type** — a named category of call your assistant recognises, each with its own behaviour and the fields it should collect. For example "Book an appointment" or "Emergency".

**Caller memory** — the assistant recognising someone who has called before, and referring to that earlier conversation.

**Caller ID** — the number displayed to the person you are calling. Separately configurable for callbacks and for ordinary outbound calls.

**Conversation** — a thread in the Inbox grouping calls and messages with one contact.

**Credits** — prepaid balance consumed by usage that sits outside your plan allowance, such as AI overage.

**Deal** — a revenue opportunity attached to a lead, with a value, an expected close date, and a won/lost outcome.

**Display rules** — the conditions deciding which pages of your site show the widget.

**Enrichment** — optional lookups that fill in a caller's name, company, line type or location from third-party data.

**Lead** — a person who has contacted you, with a status, a score and an owner. Created automatically from calls, messages and widget submissions.

**Lead score** — a grade the AI assigns based on the qualifying criteria you define.

**Porting** — moving a phone number you already own from another provider to LimeCall.

**Scenario** — the instructions telling your assistant what to say and do on a call.

**Snooze** — hiding a lead or conversation until a chosen time.

**Toll-free number** — a number the caller is not charged for, such as US 800 numbers. Subject to its own verification rules.

**Transfer** — handing a live call from the AI to a human.

**Widget** — the embeddable component on your website offering call, message and booking options.

**10DLC** — the US registration scheme for application-to-person texting from ordinary local numbers. Required before you can text US recipients. See [US carrier registration (10DLC)](/virtual-numbers/us-carrier-registration).


# Callback & Web Widget

Put a call button on your website and connect visitors to your team in seconds.

The widget is an embeddable panel on your website. A visitor asks to be called, and LimeCall connects them to your team — usually in under 30 seconds.

## How a callback works

1. A visitor opens the widget and enters their phone number.
2. LimeCall checks the request — number validity, your daily cap, and the cost of the destination.
3. **LimeCall calls the visitor**, from your own number.
4. The moment they answer, the call is bridged to whoever the widget routes to: your AI receptionist, a team member, or a team.

```mermaid
flowchart TD
    A["Visitor enters their number"] --> B["Validity, daily cap<br/>and destination checks"]
    B --> C["LimeCall dials the visitor<br/>from your number"]
    C --> D{"Visitor answers?"}
    D -- "No" --> E["Recorded as a missed callback<br/>in your Inbox"]
    D -- "Yes" --> F{"Widget routing"}
    F -- "AI receptionist" --> G["Assistant answers"]
    F -- "Member or team" --> H["Their phone rings"]
    H --> I{"Anyone picks up?"}
    I -- "Yes" --> J["Connected"]
    I -- "No" --> K["Voicemail"]
    G --> J
```

The visitor is dialled first because the whole promise is speed: the request becomes a live call immediately, rather than queueing behind whoever is free. Your side is brought on once the visitor has actually picked up, so an answered call is never spent on someone who has already walked away.

If nobody on your side answers, the request does not disappear. It is recorded as a missed callback and appears in your Inbox for follow-up, and the visitor can be offered a scheduled time instead.

## What the widget can offer

The widget is not only a call button. Under the **Channels** tab you choose which of these appear:

| Channel         | What the visitor gets                |
| --------------- | ------------------------------------ |
| Call now        | An immediate callback.               |
| Schedule a call | A time picker for later.             |
| SMS             | A text conversation.                 |
| WhatsApp        | A handoff to WhatsApp.               |
| Email           | A message form routed to your inbox. |
| Contact form    | Custom fields you define.            |

Turning off the ones you cannot staff is usually better than offering everything.

## Setting it up

1. [Install with JavaScript](/callback/install-with-javascript) or one of the platform guides below.
2. [General settings](/callback/general) and [Appearance](/callback/appearance) to make it yours.
3. [Hours](/callback/hours) so it behaves differently when you are closed.
4. [Testing your widget](/callback/testing-your-widget) before you rely on it.

## Installation guides

* [Install with JavaScript](/callback/install-with-javascript) — any site you can edit HTML on
* [Install on WordPress](/callback/install-on-wordpress)
* [Install with Google Tag Manager](/callback/install-with-google-tag-manager)
* [Install on other platforms](/callback/install-on-other-platforms) — Shopify, Webflow, Squarespace, Wix

## Configuration

* [General settings](/callback/general)
* [Appearance](/callback/appearance)
* [Hours](/callback/hours)
* [Lead capture](/callback/lead-capture)
* [Alerts & retry](/callback/alerts-and-retry)
* [Channels](/callback/channels)
* [Display rules](/callback/display-rules)


# Install with JavaScript

Add the widget to any website you can edit the HTML of.

This is the universal method. It works on any site where you can add a script tag.

Once it is in, visitors see a launcher in the corner of every page it loads on:

## Get your snippet

1. Open **Widget** in the dashboard.
2. Go to the **Embed** tab.
3. Copy the snippet shown. It contains your account's widget key — it is specific to you, not a generic tag.

## Add it to your site

Paste the snippet immediately before the closing `</body>` tag. It looks like this:

```html
<body>
  <!-- your page content -->

  <!-- LimeCall widget -->
  <script src="https://dashboard.limephone.io/callback-widget.js"
          data-key="YOUR_WIDGET_KEY"
          data-api="https://dashboard.limephone.io"></script>
</body>
```

{% hint style="info" %}
Copy the real snippet from the **Embed** tab rather than retyping the example above. Yours carries your own widget key, and the Embed tab is always the current, correct form.
{% endhint %}

If you chose the **Inline** display style, the snippet also includes a mount point. Put it where the widget should appear:

```html
<div id="limephone-callback"></div>
```

## Do not add your own `data-` attributes

The snippet deliberately carries only `data-key` and `data-api`. Every other setting travels in the configuration the widget fetches at load time, which is why changes you make on the Widget page take effect on your live site without you touching the code again.

Attributes **override** that configuration. Adding, say, `data-mode="bubble"` freezes the display style at the moment you pasted it — after which changing Display style in the dashboard updates the preview, saves fine, and does nothing at all to your site.

{% hint style="warning" %}
This is the most confusing failure the widget has, because nothing appears broken. If a setting refuses to take effect on your site but works in the preview, view your page source and check for a `data-` attribute pinning it.
{% endhint %}

## Put it on every page

The widget must be on every page where you want it to appear. Adding it to your homepage alone is the single most common installation mistake.

Nearly every site has a shared template that renders on all pages — a footer include, a layout file, a base template. Add the snippet there once, rather than page by page:

| Stack           | Where to put it                                     |
| --------------- | --------------------------------------------------- |
| Static HTML     | The shared footer include, if you have one.         |
| Next.js         | `app/layout.tsx`, or `pages/_document.js`.          |
| Nuxt / Vue      | `app.vue` or `nuxt.config` under `app.head.script`. |
| Laravel / Rails | The base layout template.                           |
| Django          | Your `base.html`.                                   |

If you want it on *some* pages only, install it everywhere and then restrict it with [Display rules](/callback/display-rules). That is far easier to maintain than editing templates.

## Verify it worked

1. Open your site in a private/incognito window — this avoids cached copies and any earlier dismissal of the widget.
2. Wait two or three seconds. The widget loads after your page content, so it appears last.
3. Open your browser's developer console and check for errors mentioning `limecall`.

If nothing appears, see [The widget is not showing](/troubleshooting/widget-not-showing).

## Content Security Policy

If your site sets a CSP header, allow the host in your snippet — the same value appears in both `src` and `data-api`, and the widget needs to load from it *and* call it:

```
script-src  https://dashboard.limephone.io
connect-src https://dashboard.limephone.io
```

Without this the browser blocks the script silently. The only sign is a CSP violation in the console.

## Next

Once it is installed, the widget can be driven from your own JavaScript — opened on a button click, or fired from a form you already have:

* [JavaScript API](/callback/javascript-api)
* [Connect your own form](/callback/connect-your-own-form)


# Install on WordPress

Three ways to add the widget to a WordPress site.

Pick whichever of these matches how your site is built. All three produce the same result.

## Option 1 — a header/footer plugin (recommended)

The safest method, because it survives theme updates.

1. In WordPress, go to **Plugins → Add New** and install a snippet plugin such as *WPCode* or *Insert Headers and Footers*.
2. Activate it, then open its settings.
3. Copy your snippet from **Widget → Embed** in LimeCall.
4. Paste it into the **Footer** box — not the header.
5. Save.

## Option 2 — your theme's built-in setting

Many themes include a custom-code area. Look under **Appearance → Customize** for "Custom Code", "Footer Scripts" or similar, and paste the snippet into the footer field.

{% hint style="warning" %}
Code pasted directly into a theme's own settings is usually lost when that theme updates. Option 1 avoids this.
{% endhint %}

## Option 3 — edit the theme directly

Only do this on a child theme. Editing a parent theme means losing your change on the next update.

1. Go to **Appearance → Theme File Editor**.
2. Open `footer.php`.
3. Paste the snippet immediately before `</body>`.
4. Update the file.

## Clear your cache

WordPress caching is the most common reason a correctly installed widget does not appear.

After installing, purge the cache in every layer you run:

* your caching plugin (WP Rocket, W3 Total Cache, LiteSpeed Cache, WP Super Cache),
* your host's server-side cache (Kinsta, WP Engine, SiteGround and others each have their own),
* Cloudflare or any other CDN in front of the site.

Then test in a private window.

## If you use an optimisation plugin

Plugins that combine, defer or minify JavaScript can break third-party widgets. If the widget does not load, add it to the exclusion list:

* **WP Rocket** — exclude `limecall` under *File Optimization → Excluded JavaScript Files*.
* **Autoptimize** — add `limecall` to *Exclude scripts from Autoptimize*.
* **LiteSpeed Cache** — add it to the JS Excludes list.

## Verify

Open your site in a private window and wait a few seconds for the widget to appear. If it does not, work through [The widget is not showing](/troubleshooting/widget-not-showing).


# Install with Google Tag Manager

Deploy the widget through GTM, with optional page targeting.

Use GTM if you already manage your marketing tags there, or if you cannot edit your site's code directly.

## Create the tag

1. Open your GTM container and go to **Tags → New**.
2. Click **Tag Configuration** and choose **Custom HTML**.
3. Paste your snippet from **Widget → Embed** in LimeCall.
4. Leave **Support document.write** unchecked.

## Set the trigger

1. Click **Triggering**.
2. Choose **All Pages** to show the widget site-wide.
3. Name the tag something recognisable, such as `LimeCall Widget`.
4. Save.

## Test before publishing

1. Click **Preview** in GTM and enter your site URL.
2. On the connected page, confirm the tag shows under **Tags Fired**.
3. Check the widget itself appears on the page.

## Publish

Return to GTM and click **Submit**, then **Publish**. Changes are not live for real visitors until you do this — a very common oversight when the widget "works in Preview but not in production".

## Targeting specific pages

You can restrict the widget using either GTM triggers or LimeCall's own display rules.

| Use                        | When                                                                      |
| -------------------------- | ------------------------------------------------------------------------- |
| **GTM trigger**            | You want the script not to load at all on some pages.                     |
| **LimeCall display rules** | You want the script everywhere but the widget visible only on some pages. |

LimeCall's rules are usually easier to change, because you edit them in the dashboard without republishing the GTM container. See [Display rules](/callback/display-rules).

To limit by GTM instead, create a **Page View** trigger with a condition such as *Page Path contains `/pricing`* and use that trigger instead of All Pages.

## Consent Mode

If you run GTM Consent Mode, decide whether the widget should fire before or after consent. The widget is a functional contact tool rather than an advertising tag, but the correct classification depends on your own privacy policy and jurisdiction. If you gate it behind consent, visitors who decline will not see a contact option at all — which is usually not what you want.


# Install on other platforms

Shopify, Webflow, Squarespace and Wix.

All of these paste the same snippet. Copy yours from **Widget → Embed** — it carries your own widget key:

```html
<script src="https://dashboard.limephone.io/callback-widget.js"
        data-key="YOUR_WIDGET_KEY"
        data-api="https://dashboard.limephone.io"></script>
```

{% hint style="warning" %}
Paste it as-is. Any extra `data-` attribute **overrides your saved settings and freezes that one**, so a snippet carrying `data-mode="bubble"` will ignore every later change to Display style. See [Install with JavaScript](/callback/install-with-javascript).
{% endhint %}

After pasting on any platform, confirm it actually loaded — open your live site and run this in the browser console:

```js
window.LimeCall && window.LimeCall.getState()
// { ready: true, open: false, mode: "bubble", inWebCall: false, tab: null, visible: true }
```

`undefined` means the script never ran: the code area was not published, a cache is stale, or the platform strips scripts on that plan. Each platform's specific version of that is noted below.

## Shopify

1. In your Shopify admin, go to **Online Store → Themes**.
2. On your current theme, choose **Actions → Edit code**.
3. Open `layout/theme.liquid`.
4. Paste the snippet immediately before `</body>`.
5. Save.

The widget now appears across the storefront, including product and collection pages.

On Online Store 2.0 themes `layout/theme.liquid` is still the right file — the snippet is a plain script tag, so it does not need to be an app embed or a section.

{% hint style="info" %}
Shopify checkout pages are locked down and will not run third-party scripts on most plans. This is expected — and usually desirable, since you rarely want a callback prompt mid-checkout.
{% endhint %}

## Webflow

1. Open **Site settings → Custom code**.
2. Paste the snippet into the **Footer code** field.
3. Save, then **Publish** the site.

Custom code only runs on the published site, not in the Designer preview. Always test on your live domain.

For a single page instead, open that page's settings and use its own **Before `</body>` tag** field.

{% hint style="info" %}
Webflow's Footer code field runs on every published page, which is what you want. Do not put it in **Head code** — the widget would load before the page it attaches to.
{% endhint %}

## Squarespace

1. Go to **Settings → Advanced → Code Injection**.
2. Paste the snippet into the **Footer** box.
3. Save.

Code Injection requires a Business plan or higher. On Personal plans, use a Code Block on individual pages instead — the same snippet works, it just has to be added per page.

Squarespace serves cached pages aggressively. If the widget does not appear, hard-reload once before assuming the snippet is wrong.

## Wix

1. Go to **Settings → Custom Code** in your site's dashboard.
2. Click **Add Custom Code**.
3. Paste the snippet.
4. Set **Add Code to Pages** to *All pages*, and **Place Code in** to *Body – end*.
5. Apply.

Custom code needs a Premium plan and a connected domain. It does not run on free `wixsite.com` addresses — `window.LimeCall` will be `undefined` there no matter how correct the snippet is.

Leave **Load code once** unselected. The widget expects to initialise on each page view, and loading it once across a session leaves it missing after client-side navigation.

## Anything else

If your platform lets you add HTML to a footer or a "custom code" area, the JavaScript method works. See [Install with JavaScript](/callback/install-with-javascript).

Framer, Ghost, Carrd, Notion-backed sites and most site builders all expose one of these. The rule is the same everywhere: the snippet goes at the end of the body, on every page you want the widget on.

For a React, Vue or Next.js app you control, add the script tag to the HTML shell rather than injecting it from a component — mounting it per route re-runs initialisation on every navigation. In Next.js that is `app/layout.tsx` or `pages/_document.tsx`.

If it does not, and you can add a Google Tag Manager container, use [Install with Google Tag Manager](/callback/install-with-google-tag-manager).

## After installing on any platform

1. Test in a private/incognito window.
2. Clear any platform or CDN cache first.
3. If nothing appears, see [The widget is not showing](/troubleshooting/widget-not-showing).


# General settings

The widget's name, default behaviour and core options.

Open **Widget → General**.

## Widget name

An internal label. It identifies this widget in your dashboard and in reports, and is not shown to visitors. If you run more than one widget — say one for your marketing site and one for your support portal — name them so the analytics are readable.

## Default behaviour

Decide what the widget does when a visitor first interacts with it:

| Behaviour                        | Effect                                                                                              |
| -------------------------------- | --------------------------------------------------------------------------------------------------- |
| Open on click                    | The panel stays closed until the visitor clicks. Least intrusive.                                   |
| Open automatically after a delay | The panel opens itself after a set number of seconds.                                               |
| Open on exit intent              | The panel opens when the cursor moves toward the browser chrome, suggesting the visitor is leaving. |

Automatic opening raises engagement but annoys some visitors. If you use it, set a delay long enough that the visitor has read something first — 20 to 30 seconds is a common starting point, rather than 3.

## Greeting text

The line shown when the panel opens. Keep it short and specific to what you do. "Want us to call you? We usually connect in under 30 seconds" performs better than "How can we help?" because it sets an expectation you then meet.

## Language

Sets the language of the widget's built-in labels and prompts. Your own custom text — greeting, form labels, button text — is used exactly as you type it and is not translated.

## Which number visitors see

If you display a "call us" number in the widget, choose it here. It must be a number you own in LimeCall. See [Caller ID](/virtual-numbers/caller-id).

## Saving

Changes take effect on your live site within a minute or two. You do not need to reinstall the snippet or republish your site — the widget reads its configuration at load time.

If you do not see a change, hard-reload the page (Ctrl+F5, or Cmd+Shift+R) to bypass your browser cache.


# Appearance

Match the widget to your brand — colour, position, shape and text.

Open **Widget → Appearance**.

## Colour

Set the primary colour used for the button and accents. Use your brand's action colour — the same one your main call-to-action buttons use — so the widget reads as part of the site rather than a bolted-on tool.

Check the contrast against your background. Light colours on white leave the button hard to see, which costs you clicks.

## Position

Choose which corner the button sits in. Bottom-right is the convention and is where most visitors look first.

Move it to bottom-left if you already have something in the bottom-right — a cookie banner, a chat tool, a back-to-top button. Two floating buttons stacked in one corner means neither gets clicked.

You can also adjust the offset from the page edges, which is useful for clearing a sticky footer or a mobile navigation bar.

## Button shape and size

Round is the default and is the most recognisable. A rounded rectangle with a text label ("Call me") is more explicit and tends to convert better with audiences unfamiliar with floating call buttons.

Keep the tap target comfortably large on mobile — a button smaller than about 44 pixels is hard to hit accurately.

## Button text and icon

Set the label and the icon. Be literal. "Call me back" tells a visitor what will happen; a bare phone icon leaves them guessing whether it dials immediately, which makes cautious visitors avoid it.

## Panel styling

Control the header, the background and the text colour of the open panel. Set your logo here — the panel is a moment where visitors decide whether this is really your company, and an unbranded panel on a branded site reads as third-party and reduces trust.

## Mobile

The widget adapts to small screens automatically, but check the result. On mobile the panel typically occupies most of the viewport, so long greeting text pushes the form below the fold.

Test on a real phone rather than only in your browser's device emulator.

{% hint style="info" %}
Changes appear on your live site within a minute or two. Hard-reload the page if you do not see them.
{% endhint %}


# Hours

Make the widget behave differently when you are open and when you are closed.

Open **Widget → Hours**.

The widget can offer different things depending on whether anyone is available to answer.

## Where hours come from

The widget follows your **Business hours**, set under **Settings → Business hours**. Set them there once and every part of LimeCall — the widget, the AI receptionist, routing — agrees on when you are open.

{% hint style="warning" %}
Check the time zone on your business hours. Hours set in the wrong zone are the most common cause of a widget that says you are closed during your actual working day.
{% endhint %}

## Open-hours behaviour

While you are open, the widget offers an immediate callback. This is the primary path and should stay enabled.

## Closed-hours behaviour

Choose one:

| Option                      | Effect                                                                       |
| --------------------------- | ---------------------------------------------------------------------------- |
| Offer scheduling            | The visitor picks a time in your next open window. Best for most businesses. |
| Collect a message           | The visitor leaves their details and you follow up.                          |
| Hand to the AI receptionist | The AI answers straight away, whatever the hour.                             |
| Hide the widget             | No contact option outside hours.                                             |

Hiding the widget is rarely the right choice — a visitor at 9pm is still a lead, and offering nothing loses them.

## Handing over to the AI

If you have an AI receptionist configured, pointing your closed hours at it is the strongest option: the visitor gets an answer immediately instead of a form, and the AI can qualify them and book a meeting while you sleep.

See [AI Receptionist](/ai-receptionist).

## Holidays and one-off closures

Add exceptions under **Settings → Business hours**. An exception overrides the weekly pattern for that date, so you do not have to edit your standard hours for a public holiday and remember to change them back.

## Per-person availability

Individual team members set their own hours under **Settings → My hours**. Business hours decide whether *the company* is open; personal hours decide whether *that person* is rung.

If a call arrives during business hours but everyone's personal hours have ended, there is nobody to ring — and the call falls through to your missed-call handling. When testing out-of-hours behaviour, check both layers.


# Lead capture

Choose what to ask visitors before the call connects.

Open **Widget → Lead capture**.

By default the widget asks for one thing: a phone number. You can ask for more.

## The trade-off

Every extra field costs you submissions. A phone number alone converts best. Each additional required field reduces completion — noticeably so on mobile.

Ask for more only when the information genuinely changes what happens next:

* **Name** — cheap to ask and makes the call warmer. Usually worth it.
* **Email** — worth it if you follow up in writing or need it in your CRM.
* **Company** — worth it in B2B, where it changes who takes the call.
* **Reason for calling** — worth it if you route by topic.

Anything you would not act on differently, do not ask.

## Required versus optional

Mark a field optional unless you truly cannot proceed without it. An optional field still gets filled in by a decent share of visitors, at no cost to the ones who will not.

## Custom fields

Add your own fields for information specific to your business — a policy number, a property address, a preferred appointment window.

Each custom field appears on the resulting lead record, so your team sees it before they speak.

## Field validation

Phone numbers are validated and normalised into international format, so a visitor typing a local format still produces a dialable number.

Email fields are checked for basic validity. Neither check confirms the contact is reachable — only that it is well-formed.

## Consent and privacy

If you operate under GDPR or similar rules, add a consent checkbox and link it to your privacy policy. Make the purpose specific: "I agree to be contacted by phone about my enquiry" is meaningful consent; a bare "I agree to the terms" generally is not.

Data collected here is stored against the lead record. See your account's data settings under **Settings** for retention.

## Where the data goes

Everything captured lands on the lead in **Leads**, and on the conversation in **Inbox**. If you have a CRM connected, it syncs there too — see [Integrations](/integrations).

## Pre-filling from your site

If a visitor is already logged into your site, you can pass what you know into the widget so they are not asked twice. See the developer notes in [Developers](/developers).


# Alerts & retry

Who gets told about a callback request, and what happens when nobody answers.

Open **Widget → Alerts** and **Widget → Retry**.

## Alerts

Choose how your team is told a callback has been requested.

| Channel              | Good for                                 |
| -------------------- | ---------------------------------------- |
| Browser notification | Agents working in the dashboard.         |
| Email                | A record, and for people not logged in.  |
| SMS                  | Teams away from a desk.                  |
| Slack                | Shared visibility across a team channel. |

Enable at least one channel that reaches someone who is not sitting in the dashboard. Browser notifications alone mean a request raised while everyone is in a meeting goes unseen.

Slack is usually the best default for a team — see [Slack](/integrations/slack).

## Who is alerted

Alerts follow your routing configuration. If the callback is assigned to a team, the members of that team are alerted; if it is assigned to a person, only they are.

Set routing under **Settings → Team**.

## Retry

When a callback is routed to a person or team and nobody picks up, the retry settings decide what happens next.

**Number of attempts** — how many times to try before giving up. Two or three is typical. More than that and you are calling a visitor who has moved on.

**Interval between attempts** — how long to wait. Short intervals (a minute or two) catch someone who stepped away; longer intervals are better if your team works in blocks.

**What to do after the final attempt** — the important setting. Options are to leave the request as a missed callback in your Inbox, send the visitor a message, or hand the call to your AI receptionist.

{% hint style="warning" %}
A missed callback that produces no alert and no follow-up is a lead you paid to acquire and then dropped. Configure the final-attempt behaviour deliberately rather than leaving it at the default.
{% endhint %}

## Retrying the visitor

If your side answers but the visitor does not, LimeCall can try the visitor again. Visitors frequently miss the first attempt because they do not recognise the number — which is a good reason to set a caller ID they will recognise. See [Caller ID](/virtual-numbers/caller-id).

## Reviewing what happened

Every attempt is logged on the call record, so you can see how many times each side was tried and where it failed. Find these under **Calls**, filtered by outcome.


# Channels

Choose which contact options the widget offers.

Open **Widget → Channels**.

The widget can offer several ways to get in touch. Turn on the ones you can actually staff.

## Available channels

**Call now** — an immediate callback. The core of the product, and the one to keep on.

**Schedule a call** — the visitor picks a time. Essential outside business hours, and useful in B2B where people prefer booking to being rung immediately. Requires a connected calendar; see [Google Calendar](/integrations/google-calendar).

**SMS** — a text conversation. Requires a number with SMS capability, and US traffic requires carrier registration. See [SMS & messaging](/virtual-numbers/sms-and-messaging).

**WhatsApp** — hands the visitor to WhatsApp. Strong in markets where WhatsApp is the default messenger; largely ignored in markets where it is not.

**Email** — a message form that routes to your inbox. The lowest-intent option, but the one some visitors want.

**Contact form** — your own fields, for structured enquiries.

## Choosing which to enable

More channels is not better. Each one you offer is a promise to respond on it.

A common, well-performing configuration:

* Call now — on
* Schedule a call — on
* Everything else — off

Then add SMS or WhatsApp only if you have someone watching those queues.

{% hint style="warning" %}
An enabled channel nobody monitors is worse than no channel. The visitor believes they have reached you and stops looking for another way.
{% endhint %}

## Order

The order channels appear in matters. Put your preferred contact method first — most visitors take the first reasonable option rather than reading all of them.

## Per-channel labels

Each channel's label is editable. Say what the visitor gets: "Call me in 30 seconds" is clearer than "Call".

## Where each channel lands

Every channel produces a conversation in your **Inbox**, attached to the same contact record. A visitor who texts and later calls appears as one person with one history, not two strangers.

See [Inbox, Contacts & Leads](/inbox-and-leads).


# Display rules

Control which pages show the widget, and to whom.

Open **Widget → Display rules**.

Install the widget everywhere, then use these rules to decide where it actually shows. This is far easier to maintain than editing page templates.

## URL rules

Show or hide the widget by URL.

| Rule             | Example     | Matches                        |
| ---------------- | ----------- | ------------------------------ |
| Contains         | `/pricing`  | Any URL with `/pricing` in it. |
| Starts with      | `/blog`     | Every page under `/blog`.      |
| Exactly matches  | `/contact`  | That one page only.            |
| Does not contain | `/checkout` | Everywhere except checkout.    |

Hiding the widget on checkout, login and account pages is a common and sensible default — those visitors have already converted, and a callback prompt is a distraction.

## Rule order

Rules are evaluated in order, and the first match decides the outcome. If a page seems to ignore a rule, check whether an earlier rule already matched it.

## Device rules

Show the widget on desktop only, mobile only, or both.

Consider mobile carefully. A floating button takes real estate on a small screen, but a mobile visitor is holding a phone — the friction between "I want to talk to someone" and an actual call is lower than on desktop.

## Timing rules

Delay the widget's appearance until the visitor has been on the page for a set time, or has scrolled a certain distance. Both are ways of waiting until someone is engaged rather than interrupting immediately on arrival.

## Visitor rules

Where supported, target by traffic source or whether the visitor is new or returning. Showing a different message to someone arriving from a paid ad than to a returning customer is a straightforward way to lift conversion.

## Testing your rules

After changing rules:

1. Open the page in a private/incognito window.
2. Check the widget appears, or does not, as intended.
3. Test a page that should *not* show it — verifying only the positive case is how over-broad rules get missed.

{% hint style="info" %}
Rules apply at page load. A single-page app that changes the URL without a reload may not re-evaluate them until the next full navigation.
{% endhint %}


# Testing your widget

Verify the whole path works before you rely on it.

Test the full path, not just whether the button appears.

## Before you start

Use a private/incognito window. A normal window may serve a cached page, and may remember that you dismissed the widget earlier.

Have a phone you can answer that is **not** the destination number — you need two distinct phones to test a callback properly, one for each leg.

## The checklist

**1. It appears.** Open your site. The widget should load within a few seconds, in the right corner, in your brand colour.

**2. It appears on the right pages.** Check a page that should show it and one that should not. See [Display rules](/callback/display-rules).

**3. It opens.** Click it. The panel should open showing the channels you enabled.

**4. The form validates.** Enter an obviously invalid phone number. It should be rejected rather than accepted and silently failed later.

**5. Your side rings.** Enter a real number and submit. Your configured destination should ring within a few seconds.

**6. The visitor side rings.** Answer your side. The number you entered should then ring.

**7. Both sides can hear each other.** Speak on both. One-way audio usually means a browser microphone permission problem — see [Calls are not connecting](/troubleshooting/calls-not-connecting).

**8. It is recorded.** Hang up and open **Calls**. The call should be listed with its duration and, if recording is on, a playable recording.

**9. A lead was created.** Open **Leads**. A new lead should exist with the number and any fields you captured.

**10. Your alerts fired.** Check the channels you configured — email, Slack, SMS.

## Test the unhappy paths too

**Nobody answers your side.** Request a callback and let it ring out. Confirm your retry settings behave as configured and the request appears as a missed callback. See [Alerts & retry](/callback/alerts-and-retry).

**Outside business hours.** Temporarily set your business hours so you are closed, then reload the widget. Confirm it offers what you intended — scheduling, a message, or the AI. Set the hours back afterwards.

**On a phone.** Do the whole flow on a real mobile device. Check the panel is usable and the form is not pushed below the fold.

## Test calls and billing

Test calls consume the same minutes and allowances as real calls. Keep them short.

## If something fails

* Widget not appearing → [The widget is not showing](/troubleshooting/widget-not-showing)
* Calls not connecting → [Calls are not connecting](/troubleshooting/calls-not-connecting)


# JavaScript API

Drive the widget from your own code — open it, start a call, read its state, listen for events.

Once the widget is installed it exposes a global, `window.LimeCall`, so your own code can control it.

Everything here runs in the browser and needs no API key — the widget is already authenticated by the `data-key` in your snippet.

## Waiting until it is ready

`window.LimeCall` does not exist until the script has loaded, and the widget keeps initialising for a moment after that. Use the `ready` event:

```js
(function poll() {
  if (!window.LimeCall) return setTimeout(poll, 100);
  window.LimeCall.on("ready", function (state) {
    // safe to do anything here
  });
})();
```

Subscribing to `ready` **after** the widget is already ready still fires your handler, so there is no race to lose.

{% hint style="info" %}
Method calls made before the widget finishes initialising are queued and replayed once it is — up to **8** of them. Beyond that they are dropped. The catch is that a queued call returns `false` immediately, so never treat the return value as "it failed".
{% endhint %}

## Methods

| Method                           | Does                                                                    |
| -------------------------------- | ----------------------------------------------------------------------- |
| `open()`                         | Opens the widget panel.                                                 |
| `close()`                        | Closes it.                                                              |
| `toggle()`                       | Opens if closed, closes if open.                                        |
| `openTab(tab)`                   | Opens the panel on a tab: `"call"`, `"message"` or `"chat"`.            |
| `showLauncher()`                 | Shows the floating launcher button.                                     |
| `hideLauncher()`                 | Hides it — the widget still works through the API.                      |
| `call(phoneNumber)`              | Requests a callback to that number.                                     |
| `requestCallback(phone, fields)` | Requests a callback and **returns a promise** with the result.          |
| `schedule()`                     | Opens the scheduling view.                                              |
| `startWebCall()`                 | Starts a browser call.                                                  |
| `endWebCall()`                   | Ends it.                                                                |
| `hasAvailableAgents()`           | Promise resolving to whether anyone can actually take a call right now. |
| `setDepartment(label)`           | Routes subsequent requests to a department.                             |
| `getDepartments()`               | The departments configured on this widget.                              |
| `getState()`                     | Returns the widget's current state.                                     |
| `getVisitorId()`                 | This visitor's attribution id.                                          |
| `on(event, handler)`             | Subscribes to an event.                                                 |
| `off(event, handler)`            | Unsubscribes.                                                           |
| `version`                        | The loaded widget version.                                              |

### `openTab(tab)`

Only `"call"`, `"message"` and `"chat"` are accepted. Anything else returns `false` and does nothing.

### `call(phoneNumber)`

```js
window.LimeCall.call("+447700900123");
```

Trimmed and truncated to 32 characters; an empty value returns `false` without submitting.

**It does not tell you whether the callback was accepted.** Either listen for `callback:requested` and `callback:failed`, or use `requestCallback()` below, which returns a promise.

### `requestCallback(phone, fields)`

The same request, but you get the answer back:

```js
const result = await window.LimeCall.requestCallback("+447700900123", {
  name:  "Sam Okafor",
  email: "sam@example.com"
});

if (result.ok) {
  console.log("Callback id", result.id);   // poll or reconcile with this
} else {
  console.warn(result.message);            // show this to the visitor
}
```

Resolves to `{ ok, id, message }`. It never rejects — a network failure resolves as `{ ok: false, id: null, message: "network error" }`, so you do not need a `try`/`catch` around it.

The phone number is validated **before** any network call. It must be E.164 — a leading `+`, country code, 7–15 digits — and anything else resolves immediately with `ok: false` and a message saying so. Spaces, dashes and brackets are stripped for you, so `+44 7700 900123` is fine; `07700900123` is not, because there is no country code.

`name` is capped at 80 characters and `email` at 120. The department set through `setDepartment()` and the visitor's attribution id are attached automatically — you do not pass either.

{% hint style="info" %}
`id` is the same id the widget uses internally, so you can reconcile it against the `callback:requested` event or against calls in the REST API.
{% endhint %}

### `hasAvailableAgents()`

Resolves to `true` or `false`: can a call actually be taken right now?

```js
if (await window.LimeCall.hasAvailableAgents()) {
  showCallButton();
} else {
  showFormInstead();
}
```

The answer depends on how the widget routes:

| Routing                | Answers from                                                                                                                                    |
| ---------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------- |
| To a person or team    | Working hours, **and** whether the people it routes to still resolve. Someone who has left the account makes it `false`, not a silent dead end. |
| To the AI receptionist | Your remaining AI minutes. If you are out but have an overflow person configured, it is still `true` — a human answers.                         |

```mermaid
flowchart TD
    A["hasAvailableAgents()"] --> B{"How does the widget route?"}
    B -- "To a person or team" --> C{"Inside working hours?"}
    C -- "No" --> D["false"]
    C -- "Yes" --> E{"Do those people still resolve?"}
    E -- "No" --> D
    E -- "Yes" --> F["true"]
    B -- "To the AI receptionist" --> G{"AI minutes left?"}
    G -- "Yes" --> F
    G -- "No" --> H{"Overflow person configured?"}
    H -- "Yes" --> F
    H -- "No" --> D
```

Use it to decide whether to offer a call at all. Offering one that nobody picks up costs more goodwill than not offering it.

{% hint style="info" %}
The result is cached for 20 seconds, so a page that checks it repeatedly does not generate a request each time. Calling `setDepartment()` clears the cache, because availability can differ per department.
{% endhint %}

{% hint style="warning" %}
It is deliberately conservative on the client and optimistic on the server. No widget key, or a network failure, resolves `false` — so a broken page hides the call button rather than promising a call. But if the availability check itself errors server-side it answers `true`, matching what the call path does: an outage should not silently switch off inbound calls. Treat it as a strong signal, not a guarantee.
{% endhint %}

### `setDepartment(label)` and `getDepartments()`

If your widget has departments, you can route from code instead of making the visitor choose:

```js
window.LimeCall.on("ready", function () {
  console.log(window.LimeCall.getDepartments());   // ["Sales", "Support", "Billing"]

  if (location.pathname.startsWith("/pricing")) {
    window.LimeCall.setDepartment("Sales");
  }
});
```

`getDepartments()` returns the department names as plain strings. It reads them from the widget's loaded configuration, so **call it inside `ready`** — before that it returns an empty array.

`setDepartment(label)` applies to every request afterwards: the form, `call()`, `requestCallback()` and browser calls. It also moves the visible department picker, if one is rendered. Pass `""` or `null` to clear it.

{% hint style="info" %}
If the visitor picks a department themselves, **their choice wins.** `setDepartment()` sets the default, not an override — which is what you want, since they know why they are calling better than the page does.
{% endhint %}

A label that does not match a configured department resets the visible picker to "Any department", and routing falls back to your default. Match the names exactly as they appear in `getDepartments()`.

### `getVisitorId()`

Returns the attribution id the widget assigns this visitor, or `null` before it is ready:

```js
analytics.identify({ limecall_visitor_id: window.LimeCall.getVisitorId() });
```

It is the same id carried on callback requests, so it is how you stitch a widget conversion to a session in your own analytics.

### `getState()`

```js
var s = window.LimeCall.getState();
// { ready: true, open: false, mode: "bubble", inWebCall: false, tab: null, visible: true }
```

| Key         | Meaning                                                            |
| ----------- | ------------------------------------------------------------------ |
| `ready`     | The widget has finished initialising.                              |
| `open`      | The panel is open.                                                 |
| `mode`      | Display style: `inline`, `bubble`, `side` or `popup`.              |
| `inWebCall` | A browser call is in progress.                                     |
| `tab`       | The tab currently shown, or `null`.                                |
| `visible`   | The widget is rendered on this page — respects your display rules. |

`visible` is the one to check before wiring your own button to `open()`: a display rule may have hidden the widget on this page entirely.

## Events

Subscribe with `on(event, handler)`, unsubscribe with `off(event, handler)`.

| Event                | Fires when                        | Payload                                                                                         |
| -------------------- | --------------------------------- | ----------------------------------------------------------------------------------------------- |
| `ready`              | The widget has initialised.       | `{ visible, mode }`                                                                             |
| `open`               | The panel opens.                  | `{ mode }`                                                                                      |
| `close`              | The panel closes.                 | `{ mode }`                                                                                      |
| `tab`                | The visitor switches tab.         | `{ tab }`                                                                                       |
| `teaser`             | The teaser prompt is shown.       | `{ text }`                                                                                      |
| `score`              | The visitor's lead score changes. | `{ points, total, threshold, rule }`                                                            |
| `callback:requested` | A callback was accepted.          | `{ phone, mode, id }` — `mode` is `"now"` or `"schedule"`; `scheduledAt` present when scheduled |
| `callback:failed`    | A request was rejected or failed. | `{ reason, phone, message }` — `reason` is `"rejected"` or `"network"`                          |
| `message:sent`       | The visitor sent a message.       | —                                                                                               |
| `webcall:started`    | A browser call began.             | —                                                                                               |
| `webcall:ended`      | A browser call ended.             | —                                                                                               |

Unknown event names are rejected: `on()` returns `false` rather than silently registering a handler that never fires.

### Tracking a conversion

`callback:requested` fires only once the request was accepted, so it does not over-count:

```js
window.LimeCall.on("callback:requested", function (e) {
  gtag("event", "generate_lead", {
    method: "limecall_widget",
    mode: e.mode,
    callback_id: e.id
  });
});

window.LimeCall.on("callback:failed", function (e) {
  console.warn("Callback failed:", e.reason, e.message);
});
```

Wire `callback:failed` too. A silent rejection — closed hours, a blocked number, an unsupported country — otherwise looks exactly like a visitor who changed their mind.

### The `score` event

The widget scores visitor engagement and fires `score` as it changes, with the running `total` and the `threshold` it is working toward. Use it to trigger your own behaviour — reveal an offer, or open the widget — when someone is clearly engaged:

```js
window.LimeCall.on("score", function (e) {
  if (e.total >= e.threshold) window.LimeCall.open();
});
```

## Opening from your own button

```html
<button type="button" id="call-me">Request a callback</button>

<script>
window.LimeCall && window.LimeCall.on("ready", function () {
  window.LimeCall.hideLauncher();
  document.getElementById("call-me").addEventListener("click", function () {
    window.LimeCall.open();
  });
});
</script>
```

## Opening from a link, with no code

Any link to `#limecall` opens the widget when the page loads:

```html
<a href="#limecall">Request a callback</a>
```

`#lc-open` and `#lc-widget` do the same thing. They work across pages too, which is the useful part — put `https://example.com/pricing#limecall` in an email, an ad or a QR code and the widget opens on arrival, with nothing to install on the page beyond the usual snippet.

{% hint style="info" %}
The link opens the widget on load and whenever the address changes. If a visitor closes the widget and clicks the **same** link again, the address has not changed, so nothing happens — the browser fires no event. For a button the visitor may use more than once, call `open()` in a click handler instead.
{% endhint %}

## Next

* [Connect your own form](/callback/connect-your-own-form) — fire a callback from a form you already have
* [Widget recipes](/callback/widget-recipes) — copy-paste patterns
* [Testing & debugging](/callback/testing-and-debugging)


# Connect your own form

Auto-trigger a phone call when your existing lead form is submitted.

You already have a lead form. You do not have to replace it — have it trigger a phone call as well, so a submitted form rings your team within seconds instead of sitting in an inbox.

This is the highest-value integration the widget has. Speed of response is the single biggest driver of inbound lead conversion, and a form that rings you immediately beats one that emails you every time.

```mermaid
sequenceDiagram
    participant V as Visitor
    participant P as Your page
    participant Y as Your backend
    participant L as LimeCall
    V->>P: Submits your form
    P->>Y: Saves the lead, as it always did
    P->>L: requestCallback(phone)
    L-->>P: {ok, id}
    P->>V: "We're calling you now"
    L->>V: Phone rings
    V->>L: Answers
    L->>L: Bridges to your team or AI
```

## Two ways

| Approach                                          | Use when                                                                     |
| ------------------------------------------------- | ---------------------------------------------------------------------------- |
| [Ask the widget](#ask-the-widget)                 | The widget is installed. Shortest path, and it handles validation for you.   |
| [Hand off to the widget](#hand-off-to-the-widget) | You want the widget's own confirmation screen and ringing state.             |
| [Post directly](#post-directly)                   | You want your own interface end to end, or you are submitting from a server. |

## Ask the widget

If the widget is already on the page, `requestCallback()` does the whole thing and tells you what happened:

```html
<form id="enquiry">
  <input name="name" placeholder="Your name" required>
  <input name="phone" type="tel" placeholder="Phone number" required>
  <button type="submit">Request a callback</button>
</form>
<p id="enquiry-status" role="status"></p>

<script>
document.getElementById("enquiry").addEventListener("submit", async function (e) {
  e.preventDefault();
  var status = document.getElementById("enquiry-status");
  status.textContent = "Requesting your call…";

  var result = await window.LimeCall.requestCallback(e.target.phone.value, {
    name: e.target.name.value
  });

  status.textContent = result.ok
    ? "We're calling you now — please keep your phone nearby."
    : result.message;
});
</script>
```

No key in your code, no endpoint to get right, and the phone number is validated before anything leaves the browser. It resolves `{ ok, id, message }` and never rejects, so there is nothing to catch.

## Hand off to the widget

To show the widget's own confirmation and ringing state instead of your own, pass the number to `call()` and let it take over:

```js
document.getElementById("enquiry").addEventListener("submit", function (e) {
  e.preventDefault();
  if (window.LimeCall) window.LimeCall.call(e.target.phone.value);
});
```

`call()` returns a boolean that tells you nothing about the outcome — listen for `callback:requested` and `callback:failed`, or use `requestCallback()` above.

Pair either with `hideLauncher()` if you do not want the floating button on the page.

## Post directly

To keep your own interface entirely, post to the widget's public endpoint. This uses your **widget key** — the publishable one from your snippet's `data-key` — not a secret API key.

```js
async function requestCallback(fields) {
  const res = await fetch("https://dashboard.limephone.io/api/public/callback", {
    method: "POST",
    headers: {
      "Content-Type": "application/json",
      "X-Widget-Key": "YOUR_WIDGET_KEY"
    },
    body: JSON.stringify(fields)
  });
  const body = await res.json();
  if (!res.ok) throw new Error(body.message || "Callback request failed");
  return body;            // { id: "..." }
}
```

Use the same host as your snippet's `data-api` value.

### Fields

| Field        | Required | Notes                                                                                                                             |
| ------------ | -------- | --------------------------------------------------------------------------------------------------------------------------------- |
| `phone`      | yes      | The number to call back, international format.                                                                                    |
| `name`       | no       | Shown to whoever takes the call.                                                                                                  |
| `email`      | no       | Stored on the resulting lead.                                                                                                     |
| `department` | no       | Routes to a specific team.                                                                                                        |
| `captured`   | no       | Extra fields you collected, carried onto the lead.                                                                                |
| `sessionId`  | no       | Ties the request to a widget session for attribution. If the widget is on the page, get it from `window.LimeCall.getVisitorId()`. |

Success returns the callback's `id`. A failure returns a `message` worth showing the visitor — it is where "outside business hours" arrives.

### Scheduling instead

Same shape plus a time, to a different path:

```js
fetch("https://dashboard.limephone.io/api/public/callback/schedule", {
  method: "POST",
  headers: { "Content-Type": "application/json", "X-Widget-Key": "YOUR_WIDGET_KEY" },
  body: JSON.stringify({ phone: "+447700900123", scheduledAt: "2026-09-15T09:30:00Z" })
});
```

## Worked example — an existing lead form

A complete drop-in: keep your form and its styling, add a call request, and fall back gracefully when nobody can be reached.

```html
<form id="lead-form">
  <input name="name"    placeholder="Name" required>
  <input name="email"   placeholder="Email" type="email" required>
  <input name="phone"   placeholder="Phone" type="tel" required>
  <textarea name="message" placeholder="How can we help?"></textarea>
  <button type="submit" id="lead-submit">Send &amp; get a call back</button>
</form>
<p id="lead-status" role="status"></p>

<script>
(function () {
  var form   = document.getElementById("lead-form");
  var button = document.getElementById("lead-submit");
  var status = document.getElementById("lead-status");

  form.addEventListener("submit", async function (e) {
    e.preventDefault();
    button.disabled = true;                         // never double-submit
    status.textContent = "Requesting your call…";

    var data = Object.fromEntries(new FormData(form));

    // 1. Your own backend still gets the lead, exactly as before.
    try {
      await fetch("/api/leads", {
        method: "POST",
        headers: { "Content-Type": "application/json" },
        body: JSON.stringify(data)
      });
    } catch (err) {
      // Don't abandon the call request just because your own endpoint failed.
      console.error("Lead save failed", err);
    }

    // 2. Then ask LimeCall to ring both sides.
    try {
      const res = await fetch("https://dashboard.limephone.io/api/public/callback", {
        method: "POST",
        headers: {
          "Content-Type": "application/json",
          "X-Widget-Key": "YOUR_WIDGET_KEY"
        },
        body: JSON.stringify({
          phone: data.phone,
          name:  data.name,
          email: data.email,
          captured: { message: data.message }       // carried onto the lead
        })
      });
      const body = await res.json();

      if (res.ok) {
        status.textContent = "Thanks — we're calling you now. Please keep your phone nearby.";
      } else {
        // Closed, blocked, or an unsupported country. Say what the API said.
        status.textContent = body.message || "We've got your details and will be in touch.";
        button.disabled = false;
      }
    } catch (err) {
      status.textContent = "We've got your details and will be in touch.";
      button.disabled = false;
    }
  });
})();
</script>
```

### What that example gets right

**Your backend still receives the lead.** The call request is added alongside, not instead. If LimeCall is unreachable you have still captured the enquiry.

**It tells the visitor a call is coming.** Someone who does not expect a call does not answer an unknown number, and the whole point is lost. Say it before the phone rings.

**It shows the API's own message on failure.** "We're closed right now" is useful; "Something went wrong" is not.

**It disables the button.** A visitor who clicks twice otherwise gets rung twice.

**`captured` carries the free-text field** onto the lead, so whoever picks up can see what was asked before they speak.

## Only promise a call someone can take

Ask before you offer. `hasAvailableAgents()` accounts for working hours, whether the people the widget routes to still resolve, and — on an AI-routed widget — whether you have minutes left:

```js
if (await window.LimeCall.hasAvailableAgents()) {
  button.textContent = "Send & get a call back";
} else {
  button.textContent = "Send";     // same form, no promise of a call
}
```

Changing the label is better than hiding the option. The lead is still captured either way; the visitor just is not told to expect a ringing phone that never comes.

If you are posting directly rather than using the widget, the request still succeeds outside hours — the response `message` is where "we're closed right now" arrives, which is why the example above shows it to the visitor verbatim.

## Which key is which

{% hint style="warning" %}
The **widget key** (`data-key`) is publishable — it is already in your page source and belongs in browser code. A **secret key** (`sk_live_…`) is not: putting one in front-end code exposes your whole account to anyone who opens developer tools. The widget endpoints take `X-Widget-Key`; the REST API takes `Authorization: Bearer`. They are not interchangeable.
{% endhint %}

See [API keys](/developers/api-keys).

## Doing it server-side instead

If your form already posts to your own backend, create the callback there. It is the right choice when you want to validate, deduplicate, enrich or rate-limit before spending a call — and the visitor's browser never has to be trusted.

It is the **same endpoint**, with a secret key instead of a widget key:

|              | Browser                         | Your server                       |
| ------------ | ------------------------------- | --------------------------------- |
| Header       | `X-Widget-Key: pk_live_…`       | `Authorization: Bearer sk_live_…` |
| Origin       | Must be on your allowed list    | Not checked                       |
| `fromNumber` | From your saved widget settings | **Required in the body**          |
| Daily cap    | Your widget's cap (default 50)  | `dailyCallbackCap`, default 200   |

{% hint style="warning" %}
The secret key needs the **`calls:write`** scope. Without it the request is rejected with `403 insufficient_scope` — placing a call spends real money, so it is held to the same scope requirement as every `/api/v1` route.
{% endhint %}

### Node

```js
// Node 18+. Never expose sk_live_ to a browser.
export async function requestCallback({ phone, name, email }) {
  const res = await fetch("https://dashboard.limephone.io/api/public/callback", {
    method: "POST",
    headers: {
      "Authorization": `Bearer ${process.env.LIMECALL_SECRET_KEY}`,
      "Content-Type": "application/json"
    },
    body: JSON.stringify({
      phone,                                  // E.164, e.g. +447700900123
      fromNumber: process.env.LIMECALL_FROM,  // required, and must be a number you own
      name,
      email
    })
  });

  const body = await res.json();
  if (!res.ok) {
    // body.error is a stable code; body.message is safe to show a visitor.
    throw new Error(`${body.error}: ${body.message}`);
  }
  return body.id;                             // the callback id
}
```

### PHP

```php
<?php
function limecall_request_callback(string $phone, ?string $name = null): string {
    $payload = array_filter([
        "phone"      => $phone,                      // E.164
        "fromNumber" => getenv("LIMECALL_FROM"),     // required
        "name"       => $name,
    ]);

    $ch = curl_init("https://dashboard.limephone.io/api/public/callback");
    curl_setopt_array($ch, [
        CURLOPT_POST           => true,
        CURLOPT_RETURNTRANSFER => true,
        CURLOPT_HTTPHEADER     => [
            "Authorization: Bearer " . getenv("LIMECALL_SECRET_KEY"),
            "Content-Type: application/json",
        ],
        CURLOPT_POSTFIELDS => json_encode($payload),
    ]);

    $raw    = curl_exec($ch);
    $status = curl_getinfo($ch, CURLINFO_HTTP_CODE);
    curl_close($ch);

    $body = json_decode($raw, true);
    if ($status >= 400) {
        throw new RuntimeException("{$body['error']}: {$body['message']}");
    }
    return $body["id"];
}
```

### What you can send

`phone` and `fromNumber` are required. `name`, `email`, `department`, `captured` and `sessionId` behave exactly as they do from the browser.

The server path also accepts routing overrides the browser cannot set, so one key can serve several brands or campaigns: `dailyCallbackCap`, `bridgeProvider` (`"vapi"` or `"grok"`), `voiceAgentId`, `callableCountries`, `blockedCountries` and `blockVoip`.

### Errors worth handling

| Status | `error`               | Means                                           |
| ------ | --------------------- | ----------------------------------------------- |
| 400    | `missing_from_number` | `fromNumber` was not sent.                      |
| 401    | `unauthorized`        | Key missing, malformed or revoked.              |
| 403    | `insufficient_scope`  | The key lacks `calls:write`.                    |
| 403    | `from_not_owned`      | That caller ID is not a number on your account. |
| 403    | *(destination)*       | The number is in a range we refuse to dial.     |
| 429    | `spend_cap`           | The daily cap is spent.                         |

{% hint style="info" %}
`from_not_owned` exists because `fromNumber` comes from your request body on this path. The check stops a leaked key being used to spoof someone else's caller ID.
{% endhint %}

See [API keys](/developers/api-keys) for creating a key with the right scope.


# Widget recipes

Copy-paste patterns for common widget customisations.

Working patterns you can paste. All of them assume the widget is installed — see [Install with JavaScript](/callback/install-with-javascript).

Each wraps its work in the `ready` event, which is the safe place for API calls.

## Your own button, no floating launcher

```html
<button type="button" id="cta">Talk to us</button>

<script>
window.LimeCall && window.LimeCall.on("ready", function () {
  window.LimeCall.hideLauncher();
  document.getElementById("cta").addEventListener("click", function () {
    window.LimeCall.open();
  });
});
</script>
```

## Open straight onto a specific tab

```js
document.getElementById("msg-us").addEventListener("click", function () {
  window.LimeCall.openTab("message");
});
```

## Open from a link

Link to `#limecall` — no JavaScript at all:

```html
<a href="#limecall">Request a callback</a>
```

`#lc-open` and `#lc-widget` work the same way, and the anchor survives a cross-page link (`/pricing#limecall`), which makes it the one to use in emails and ads.

For a link the visitor may click more than once, handle the click instead — a repeated identical anchor fires no event:

```html
<a href="#" onclick="window.LimeCall&&window.LimeCall.open();return false;">Request a callback</a>
```

## Show the widget only on high-intent pages

Display rules in the dashboard are the better tool for this — see [Display rules](/callback/display-rules). When you need logic they cannot express:

```js
window.LimeCall.on("ready", function () {
  var highIntent = /\/(pricing|demo|contact)/.test(location.pathname);
  if (highIntent) window.LimeCall.showLauncher();
  else window.LimeCall.hideLauncher();
});
```

## Open automatically for an engaged visitor

The widget scores engagement and reports it. Rather than a fixed timer, wait until someone is actually engaged:

```js
window.LimeCall.on("score", function (e) {
  if (e.total >= e.threshold) window.LimeCall.open();
});
```

## Send conversions to Google Analytics

```js
window.LimeCall.on("callback:requested", function (e) {
  gtag("event", "generate_lead", {
    method: "limecall_widget",
    mode: e.mode,
    callback_id: e.id
  });
});
```

## Send conversions to Meta

```js
window.LimeCall.on("callback:requested", function () {
  if (window.fbq) fbq("track", "Lead");
});
```

## Log failures you would otherwise never see

```js
window.LimeCall.on("callback:failed", function (e) {
  // "rejected" = closed / blocked / unsupported country. "network" = connectivity.
  console.warn("LimeCall:", e.reason, e.message);
  if (window.gtag) gtag("event", "callback_failed", { reason: e.reason });
});
```

Worth doing early. Failed requests are invisible otherwise, and a run of `rejected` usually means your business hours are wrong.

## React to a browser call starting and ending

```js
window.LimeCall.on("webcall:started", function () {
  document.body.classList.add("in-call");   // e.g. pause a background video
});
window.LimeCall.on("webcall:ended", function () {
  document.body.classList.remove("in-call");
});
```

## Do not offer a call when the widget is hidden

```js
window.LimeCall.on("ready", function (state) {
  if (!state.visible) document.getElementById("cta").hidden = true;
});
```

## Only promise a call someone can take

`state.visible` tells you the widget is on the page. `hasAvailableAgents()` tells you somebody would actually answer — closed hours, an empty team, or exhausted AI minutes all come back `false`.

```js
window.LimeCall.on("ready", async function () {
  var cta = document.getElementById("cta");
  if (await window.LimeCall.hasAvailableAgents()) {
    cta.textContent = "Talk to us now";
  } else {
    cta.textContent = "Leave your number";     // still captures the lead
  }
});
```

Swapping the wording beats hiding the button. The visitor who wanted to talk still gets a way through.

## Route by page, without asking the visitor

```js
window.LimeCall.on("ready", function () {
  var byPath = { "/pricing": "Sales", "/docs": "Support", "/billing": "Billing" };
  var dept = byPath[location.pathname];
  if (dept && window.LimeCall.getDepartments().indexOf(dept) !== -1) {
    window.LimeCall.setDepartment(dept);
  }
});
```

Checking against `getDepartments()` first means renaming a department in the dashboard degrades to your default routing instead of sending a mismatched label.

## Submit from your own form and keep the result

```js
var r = await window.LimeCall.requestCallback(phoneInput.value, { name: nameInput.value });
status.textContent = r.ok ? "Calling you now — keep your phone nearby." : r.message;
```

Full version, including keeping your own backend in the loop: [Connect your own form](/callback/connect-your-own-form).

## Clean up in a single-page app

Handlers persist across client-side navigation, so remove the ones tied to a page:

```js
function onRequested(e) { /* … */ }

window.LimeCall.on("callback:requested", onRequested);
// later, when the view unmounts
window.LimeCall.off("callback:requested", onRequested);
```

Registering the same handler twice is safe — it is only added once — but a handler belonging to a page the visitor has left will still fire.


# Testing & debugging

How to test widget code, and what to check when something does not work.

## Test in a private window

A normal window may serve a cached page and may remember the widget was dismissed. Nearly every "it stopped working" report resolves here.

## Check the widget actually loaded

In the browser console:

```js
window.LimeCall && window.LimeCall.version
```

`undefined` means the script has not loaded — a snippet problem, not an API problem. See [The widget is not showing](/troubleshooting/widget-not-showing).

## Check its state

```js
window.LimeCall.getState()
// { ready: true, open: false, mode: "bubble", inWebCall: false, tab: null, visible: true }
```

`visible: false` means a display rule has hidden the widget on this page. `ready: false` means it is still initialising.

## Watch every event at once

The fastest way to see what the widget is doing:

```js
["ready","open","close","tab","teaser","score",
 "callback:requested","callback:failed","message:sent",
 "webcall:started","webcall:ended"].forEach(function (ev) {
  window.LimeCall.on(ev, function (payload) {
    console.log("[LimeCall]", ev, payload);
  });
});
```

Paste that, then use the widget normally. It answers most "why did nothing happen" questions in one pass.

## Do not trust the return value

Methods return `false` when the widget is not ready yet — but the call is still queued and replayed, up to 8 of them. A `false` is not a failure, and `true` is not a delivered callback.

For anything that matters, use the events — or `requestCallback()`, whose promise does resolve with the real outcome.

## Check whether anyone can answer

```js
await window.LimeCall.hasAvailableAgents();
```

`false` has several causes, and the method deliberately does not tell you which: outside working hours, nobody configured to route to, or no AI minutes left. To find out which one applies, open the Network tab and look at the response from `callback/availability` — it carries a `reason`:

| `reason`            | Means                                                                               |
| ------------------- | ----------------------------------------------------------------------------------- |
| `outside_hours`     | Working hours say closed.                                                           |
| `nobody_configured` | The widget routes to a person or team that no longer resolves.                      |
| `no_ai_minutes`     | AI minutes are exhausted and no overflow person is configured.                      |
| `overflow`          | Out of AI minutes, but a human answers — this one is paired with `available: true`. |

Remember the 20-second cache: after changing your hours or routing, wait it out, or reload the page, before re-testing.

## `getDepartments()` returns an empty array

You called it too early. Departments arrive with the widget's configuration, so the array is empty until `ready` fires. Move the call inside `on("ready", …)`.

## `setDepartment()` seems to be ignored

Two things override it, both intentionally:

* **The visitor's own choice.** If they pick a department in the form, theirs wins.
* **A label that does not match.** Compare against `getDepartments()` — the names must match exactly, and renaming a department in the dashboard breaks a hard-coded string.

## The `#limecall` link does nothing the second time

The anchor opens the widget on load and whenever the address changes. Clicking a link to the address you are already at changes nothing, so the browser fires no event. Use a click handler calling `open()` for a control the visitor may use repeatedly.

## A setting changes in the dashboard but not on your site

Check your page source for `data-` attributes beyond `data-key` and `data-api`.

Attributes override the fetched configuration and freeze that setting permanently. A snippet carrying `data-mode="bubble"` ignores every later change to Display style.

## The widget loads but calls never connect

That is routing, not the widget. Work through [Calls are not connecting](/troubleshooting/calls-not-connecting) — the usual causes are business hours, personal hours, or no destination configured.

## Requests are rejected

Listen for `callback:failed` and read `e.message`. `reason: "rejected"` is a deliberate refusal — closed hours, blocked number, unsupported country. `reason: "network"` is connectivity.

## Content Security Policy

A blocked script fails silently except for a console violation. Allow the host from your snippet in both directives:

```
script-src  https://dashboard.limephone.io
connect-src https://dashboard.limephone.io
```

## Testing on a local machine

The widget works on `localhost`. If you restrict by URL, remember your display rules apply to the local URL too — a rule matching your production path will hide the widget locally.

## Getting help

Include the page URL, the browser, the output of `getState()`, and any console errors. Those four turn a multi-day exchange into one reply.


# Styling the widget

Brand the widget from the dashboard, and what to know before writing your own CSS.

## Use the dashboard first

Colour, position, corners, launcher style, button text and the panel's logo are all settings — see [Appearance](/callback/appearance).

Settings travel in the configuration the widget fetches at load time, so they apply everywhere the widget is installed, they survive widget updates, and they can be changed without touching your site's code. Reach for CSS only for something the settings genuinely cannot express.

{% hint style="warning" %}
Do not brand the widget by adding `data-` attributes to your snippet. They override the fetched configuration and freeze that setting on your site, after which the dashboard stops affecting it. Use the Appearance settings.
{% endhint %}

## If you must write CSS

The widget renders into your page with class names prefixed `lp-`. You can target them from your own stylesheet.

```css
/* Nudge the launcher clear of a sticky footer */
.lp-launcher {
  bottom: 96px !important;
}
```

`!important` is usually required, because the widget sets its own positioning inline.

## Know what you are taking on

{% hint style="warning" %}
Internal class names are not a supported API. They are implementation detail and can change in any widget update, without a version bump and without warning — the widget updates itself on your site.
{% endhint %}

That is a real trade-off, not a formality: CSS written against internal classes can break silently, and the first sign is usually a customer telling you the contact button looks wrong.

If you do it:

* **Keep it minimal.** Position and spacing survive far better than restyling internals.
* **Scope it tightly.** One rule against one class beats a cascade of overrides.
* **Re-check after updates.** Put it on whoever owns the site as a periodic check.
* **Never rely on layout internals.** Anything depending on the panel's internal structure will break.

## Better alternatives

**The widget does not fit your design.** Hide the launcher and use your own button, so the only visible element is one you control:

```js
window.LimeCall.on("ready", function () { window.LimeCall.hideLauncher(); });
```

See [Widget recipes](/callback/widget-recipes).

**You want your own form entirely.** Post to the widget API and never render the panel at all — your markup, your styling, your validation. See [Connect your own form](/callback/connect-your-own-form).

That is the right answer for anyone doing heavy visual customisation: a supported API you control beats CSS against classes that can move.

## Inline mode

The **Inline** display style renders the widget into a container on your page rather than floating it:

```html
<div id="limephone-callback"></div>
```

Size and position that container with your own CSS as you would any other element. This is the supported way to place the widget inside a page layout, and it does not depend on internal class names.


# AI Receptionist

An AI voice agent that answers your calls, qualifies callers, books meetings and hands over to a human.

The AI receptionist answers your phone. It greets the caller in your business's words, answers questions from what you have taught it, works out whether the caller is worth your time, books them in, and hands over to a human when it should.

It works on phone calls, SMS, WhatsApp and email — the same assistant, the same knowledge, across every channel you switch on.

## What it can do

| It can                               | Notes                                                     |
| ------------------------------------ | --------------------------------------------------------- |
| Answer calls 24/7                    | No hold music, no queue.                                  |
| Answer questions about your business | From the knowledge you give it.                           |
| Qualify a caller                     | Against criteria you define, with a score.                |
| Book into your calendar              | Real availability, not a callback promise.                |
| Take a message                       | Structured, not a recording you have to listen to.        |
| Transfer to a human                  | On request, on emergency, or when it is out of its depth. |
| Write the call up                    | A summary, tags and the collected fields.                 |
| Recognise a returning caller         | And refer to what was discussed before.                   |

## What it will not do

It will not invent an answer it does not have — when it does not know, it says so and offers to take a message. It will not make outbound sales calls. It will not pretend to be human if asked directly.

## How it is organised

The editor groups its settings the way the assistant itself is built. These docs follow the same order:

1. **Assistant** — who it is. [Your assistant](/ai-receptionist/your-assistant)
2. **Channels** — where it answers. [Phone calls](/ai-receptionist/phone-calls), [Text messages](/ai-receptionist/text-messages), [WhatsApp](/ai-receptionist/whatsapp), [Emails](/ai-receptionist/emails)
3. **Instructions** — what it does. [Scenarios & call types](/ai-receptionist/scenarios-and-call-types), [Lead qualification](/ai-receptionist/lead-qualification), [Summaries & tagging](/ai-receptionist/summaries-and-tagging), [Caller memory](/ai-receptionist/caller-memory)
4. **Voice** — how it sounds. [Voice & tone](/ai-receptionist/voice-and-tone)
5. **Integrations** — what it connects to. [Transfers & escalation](/ai-receptionist/transfers-and-escalation), [Calendar & booking](/ai-receptionist/calendar-and-booking), [Actions & webhooks](/ai-receptionist/actions-and-webhooks)
6. **Knowledge** — what it knows. [Company details](/ai-receptionist/company-details), [Contact information](/ai-receptionist/contact-information), [Products & services](/ai-receptionist/products-and-services), [Additional knowledge](/ai-receptionist/additional-knowledge)
7. **Safety** — who it will not talk to. [Spam & blocking](/ai-receptionist/spam-and-blocking)

## Start here

New to it? [Create your assistant](/ai-receptionist/create-your-assistant) walks through the first setup, and [Test your assistant](/ai-receptionist/test-your-assistant) shows how to check it before you put it in front of customers.

{% hint style="warning" %}
Before taking live calls, read [Recording, consent & AI disclosure](/ai-receptionist/recording-consent-and-disclosure). Several jurisdictions require you to disclose recording, AI use, or both.
{% endhint %}


# Create your assistant

Set up your first AI receptionist from scratch.

## Start

Open **AI Receptionist**. If you have no agent yet, the page shows **No agent yet** — choose **Create agent**.

## Pick your business type

You are asked what kind of business you run. The choices are:

* Home services
* Dental / medical
* Legal
* Real estate
* Auto / dealership

Pick the closest. Your choice pre-writes the scenarios and the qualifying questions for that industry — a dental practice is asked whether the caller is a new or existing patient; a dealership is asked whether there is a trade-in. Everything is editable afterwards.

If none fit, pick the nearest and rewrite the scenario. The template is a starting point, not a constraint.

## Let it read your website

If you gave your website address at signup, LimeCall will have scanned it to pre-fill what you do, your services and your hours.

Review what it found before going further. A scraper reads what is on the page, including out-of-date prices and a phone number you no longer use.

## Work down the menu

The left-hand menu is ordered roughly the way you should fill it in.

**1. Your Assistant** — its name, its language, and the opening message callers hear first.

**2. Knowledge** — the four pages under this group are what the assistant actually knows. Do these before anything clever. An assistant with a beautiful voice and wrong prices is worse than no assistant.

**3. Scenarios** — what it should do on a call.

**4. Voice & Tone** — how it sounds.

**5. Transfers & Escalation** — when to fetch a human.

Everything else can wait until the basics work.

## Set a transfer destination

Before you go live, set at least one number the assistant can transfer to, under **Transfers & Escalation**. An assistant with no escape hatch will keep a frustrated caller in a loop.

## Test it

Open **Test your agent** and call it from your browser. See [Test your assistant](/ai-receptionist/test-your-assistant) for what to listen for.

## Connect it to a number

Open **Phone Numbers**, and on the number you want it to answer, set **Who answers your calls** to your AI receptionist.

You can also send only *some* calls to it — for example using the **When busy** destination so it picks up overflow while your team handles what it can. See [Call forwarding & routing](/virtual-numbers/call-forwarding-and-routing).

## Version history

The editor keeps a **Version history**. If a change makes things worse, you can see what changed and restore an earlier version — useful when you have been editing the prompt heavily and the assistant starts behaving oddly.


# Your assistant

Name, language and the opening message callers hear.

Open **AI Receptionist → Your Assistant**. These settings are true on every channel, not just phone calls.

## Assistant name

The name the assistant uses for itself. Callers hear it in the greeting and when it refers to itself.

Use a human first name. "You're through to Sarah at Northgate Dental" is easier to talk to than "You're through to the Northgate Dental Automated Assistant".

This name is separate from the voice. You can call it Sarah and give it any of the available voices.

## Language

The language the assistant speaks. Available languages include English, French, German and Dutch, among others.

The language affects speech recognition as well as output. Setting it correctly matters more than it looks — an assistant set to the wrong language will mishear callers, not merely reply oddly.

## Opening message

The first thing a caller hears. This is the single most important line in the whole configuration, because it sets what the caller says next.

A good opening does three things:

1. Confirms they reached the right place.
2. Gives the assistant a name.
3. Asks a question that moves things forward.

> "Thanks for calling Northgate Dental, this is Sarah. Are you an existing patient, or is this your first time with us?"

That gets you a useful answer immediately. Compare:

> "Hello, how can I help you today?"

which invites a rambling reply the assistant then has to untangle.

Keep it under about three seconds of speech. Callers interrupt long greetings, and an interrupted greeting means the assistant missed the start of what they said.

## A different message for outbound calls

If your assistant also places calls, enable **Use a different message for outbound calls**. An outbound opening has to do more work — the caller was not expecting you, so it must identify who is calling and why before asking anything.

## Telling callers it is recorded

**Tell callers the call is recorded** adds a recording notice to the greeting.

Whether this is optional depends on where you and your callers are. See [Recording, consent & AI disclosure](/ai-receptionist/recording-consent-and-disclosure) before deciding.

## System messages

Under **System messages** you can set what the assistant says in specific situations — when it cannot hear the caller, when it needs a moment, or when it is ending the call. Editing these is optional; the defaults are reasonable.


# Phone calls

How the assistant answers voice calls.

Open **AI Receptionist → Phone Calls**. This is the main channel for most accounts.

## Turning it on

**Answers phone calls** switches the assistant on for voice. With it off, calls routed to the AI fall through to whatever you have set as a fallback.

## Which calls reach it

The assistant does not decide which calls it gets — your numbers do. On each number under **Phone Numbers**, **Who answers your calls** decides whether that line rings a person, a team, voicemail or the AI.

Common patterns:

| Pattern                | How to set it                                                                       |
| ---------------------- | ----------------------------------------------------------------------------------- |
| AI answers everything  | Set the AI as the destination for all inbound calls.                                |
| AI covers overflow     | Keep the team as the main destination; set the AI as the **When busy** destination. |
| AI covers out of hours | Use business hours so the AI is the destination outside them.                       |
| AI on one line only    | Point a single number at the AI and leave the rest as they are.                     |

See [Call forwarding & routing](/virtual-numbers/call-forwarding-and-routing).

## Call settings

**End-of-speech patience** decides how long the assistant waits after you stop talking before it replies. This is the setting that most affects how natural the call feels.

* Too short and it interrupts people who pause mid-sentence.
* Too long and the conversation feels sluggish.

Start at **Balanced**. Move to **Patient** if your callers are older, speak slowly, or are often reading something out — an address, a policy number. Move to **Fast** only if your calls are short and transactional.

**Respond within** sets how quickly it starts speaking once it has decided what to say.

## When the assistant is paused

**Forward to while paused** sets where calls go if you pause the assistant. Set this. A paused assistant with no forwarding destination means calls to that number go nowhere.

Pausing is useful during a change — you can edit the assistant without callers hearing a half-finished configuration.

## Call recording

Recording is set per number rather than on the assistant. Recordings appear on the call record under **Calls**, alongside the transcript.

See [Call insights & transcripts](/analytics/call-insights-and-transcripts).

## AI minutes

Time the assistant spends on calls is metered as AI minutes, separately from ordinary call minutes. Watch the balance under **Settings → Usage & credits**.

If you run out mid-period, the assistant stops answering — so set an alert rather than discovering it from a customer. See [AI minutes & usage](/ai-receptionist/ai-minutes-and-usage).

## Caller lookup

**Caller lookup** enriches the caller's record with name, company, line type and location before the assistant speaks, where that data is available. It lets the assistant greet a known caller by name.

See [Contacts](/inbox-and-leads/contacts).


# Text messages

Let the assistant reply to inbound SMS.

Open **AI Receptionist → Text Messages**.

The same assistant that answers your phone can reply to text messages, using the same knowledge and the same rules.

## Turning it on

**Replies to text messages** enables the channel. Once on, inbound SMS to your numbers is answered by the assistant instead of sitting in the Inbox unread.

## Requirements

* A number with SMS capability. Not all numbers have it — check the capabilities before buying. See [Buy a number](/virtual-numbers/buy-a-number).
* For US recipients, completed carrier registration. See [US carrier registration (10DLC)](/virtual-numbers/us-carrier-registration).

{% hint style="warning" %}
Texting US numbers without completed 10DLC registration results in messages being filtered or blocked by carriers. This is enforced by the carriers, not by LimeCall.
{% endhint %}

## How text differs from voice

The assistant adapts, but a few things are worth knowing.

**There is no end of the call.** A text conversation can sit idle for hours and resume. The assistant keeps context across that gap.

**Replies should be shorter.** What reads naturally when spoken is too long as a text. The assistant compresses, but if you have written long scenario instructions, check how they read as messages.

**People send fragments.** Texters send several short messages in a row rather than one complete thought. The assistant waits briefly for a follow-up before replying, so it answers the whole thought rather than the first fragment.

## What it can do over text

The same things it does on a call: answer from your knowledge, collect details, qualify the enquiry, book into your calendar, and hand over to a human.

Handing over works differently — instead of transferring a live call, the conversation is assigned to a person and appears in their Inbox. See [Working a conversation](/inbox-and-leads/working-a-conversation).

## Taking over yourself

Any conversation the assistant is handling can be taken over by a human at any point from the Inbox. The assistant stops replying on that thread as soon as you do.

This is the right response to a conversation going wrong — take it over, sort it out, and then fix the knowledge or scenario that caused it.

## Opt-outs

Replies of STOP, UNSUBSCRIBE and similar are handled automatically: the contact is suppressed and no further messages are sent to them. This is a legal requirement in most markets and is not something you should override.

## Auto-replies are not the assistant

LimeCall also has simple template auto-replies, configured under **Settings → Messaging**. Those are fixed text sent on a trigger. The assistant is a conversation. If you have both configured, make sure they are not both replying to the same message.


# WhatsApp

Answer WhatsApp messages with the same assistant.

Open **AI Receptionist → WhatsApp**.

## What it does

Your assistant answers WhatsApp messages using the same knowledge, scenarios and qualifying rules as it uses on calls and SMS.

## Setting it up

You need a WhatsApp sender number connected to your account. Set it under **WhatsApp sender number** in this pane.

WhatsApp Business numbers are provisioned through an approval process run by Meta, not by LimeCall. Expect it to take longer than buying an ordinary number, and to require business verification documents.

## How WhatsApp differs

**The 24-hour window.** WhatsApp lets you reply freely for 24 hours after a customer's last message. Outside that window, only pre-approved template messages can be sent. This is Meta's rule and applies to every business on the platform.

In practice this means the assistant can hold a normal conversation while the customer is engaged, but cannot start a fresh conversation days later without a template.

**Rich formatting.** WhatsApp supports more than plain text, and people expect faster replies than on email.

**Identity is stronger.** WhatsApp carries a verified profile name, so callers know it is you — and expect a higher standard of response than an unknown SMS number.

## What it can do

The same as the other channels: answer questions, collect information, qualify, book, and hand over to a human.

## Handing over

As with text, handover assigns the conversation to a person rather than transferring a live call. It lands in their Inbox and they continue the same thread.

## Where conversations appear

In the **Inbox**, alongside calls and SMS from the same contact. A customer who WhatsApps you and later rings appears as one person with one history.

## If WhatsApp is not the right channel for you

WhatsApp dominates in much of Europe, Latin America, India and the Middle East, and is marginal in the US. If your customers are not on it, enabling it adds a queue nobody uses. Check your actual customer base rather than enabling it because it is available.


# Emails

Let the assistant draft and send email replies.

Open **AI Receptionist → Emails**.

## What it does

The assistant can draft and send email replies on your behalf, using the same knowledge it uses on calls.

## Approval mode

This is the setting that matters most here.

**Let me check it before it sends** — the assistant writes the reply and leaves it as a draft for a human to review, edit and send.

**Send automatically** — the assistant replies without review.

Start with review. Email is written, forwarded, and screenshotted in a way phone calls are not; a wrong answer in an email has a longer life than a wrong answer on a call. Move to automatic sending only once you have read enough of its drafts to trust them, and only for enquiry types where a mistake is cheap.

{% hint style="warning" %}
Never enable automatic sending for anything involving quotes, contractual commitments, medical or legal information, or complaints.
{% endhint %}

## Confirm before executing

**Confirm with the caller before executing** makes the assistant check with the person before taking an action it cannot undo — booking, cancelling, or sending something onward.

## Sender address

Emails are sent from the address configured for your account. Replies come back into your Inbox and the thread stays together.

Make sure the sending domain is properly authenticated, or your assistant's replies will land in spam. That is a DNS configuration on your domain — SPF, DKIM and DMARC — not something LimeCall can set for you.

## Drafting style

The assistant writes in the tone you have configured. Email tolerates more length than speech, but the same rule applies: answer the question asked, do not pad.

If its drafts are consistently too long or too formal, adjust the tone under [Voice & tone](/ai-receptionist/voice-and-tone) — those instructions apply to written channels too.

## Escalating

Frustrated or complex emails should go to a person. **Escalate frustrated callers automatically** applies here as well as on calls: when the sentiment of an incoming message reads as angry, the assistant stops drafting and assigns the thread to a human.

## Where emails appear

In the **Inbox**, threaded with everything else from that contact.


# Scenarios & call types

What your assistant says and does on a call.

Open **AI Receptionist → Scenarios**. This is where you decide what the assistant actually does.

## How the assistant should behave

The main instruction field. It is written in plain language, not code.

Good instructions are specific about behaviour and boundaries:

> You are the receptionist for a two-partner dental practice. Be warm and efficient. New patients should be offered a check-up appointment; existing patients should be asked what the problem is before booking. Never give clinical advice — if someone describes pain or a dental emergency, offer the emergency slot and transfer to the on-call number. Do not quote prices for treatment beyond the check-up fee.

Notice what that does: it sets a role, a tone, a default action, and two hard limits. The limits matter more than the tone.

Use **Insert prompt template** to start from a written example for your industry.

## What it should not do

State this explicitly. Models follow a clear prohibition better than an implication.

Worth naming: quoting prices it cannot verify, promising delivery dates, giving medical or legal advice, confirming appointments it has not actually booked, and claiming to be human if directly asked.

## Call types

A call type is a named kind of call, each with its own behaviour and the fields it should collect. You can define up to twelve.

For each one, set:

**Name** — what this kind of call is. "Book an appointment", "Emergency", "Complaint", "Supplier".

**Description** — how the assistant recognises it. This is how it tells a routine booking from an emergency, so be concrete about the signals.

**How it should handle this call** — the behaviour:

| Behaviour                         | What happens                 |
| --------------------------------- | ---------------------------- |
| Answer questions & take a message | Handles it and writes it up. |
| Take booking / order details      | Collects structured details. |
| Book into my calendar             | Books a real slot.           |
| Transfer the call                 | Hands to a human.            |

**Fields** — what to collect. Mark a field with **Make sure it finds out** and the assistant will keep asking until it has it, rather than letting the caller skip past.

Ask only for what changes your next action. Every required field lengthens the call.

## Emergencies

If your business has genuine emergencies, define one call type for them.

Set **What counts as an emergency** precisely. "Urgent" is not precise — callers say everything is urgent. "No heating and there is a child or someone over 70 in the property" is precise.

Set an **On-call number for emergencies** so those calls transfer immediately rather than being written up for the morning.

## Specialized terms

Under **Specialized terms** you can add words the assistant will otherwise mishear — product names, drug names, local place names, your own brand if it is an unusual spelling. Adding them measurably improves recognition.

## Custom variables

**Custom variables** let you pass in values — a campaign name, a source, a customer ID — and refer to them in the instructions. Useful when the same assistant answers several numbers and should behave slightly differently on each.

## After you change anything

Test it. Scenario edits have effects you will not predict by reading them. See [Test your assistant](/ai-receptionist/test-your-assistant).


# Lead qualification

Teach the assistant what a good lead looks like and how to grade it.

Open **AI Receptionist → Lead Qualification**.

Qualification is what makes the assistant more than an answering machine. It decides which calls deserve your attention.

## What counts as a good lead

Describe your ideal customer in plain language. Be concrete — "a good lead" means nothing; the specifics mean everything:

> A good lead is a homeowner, not a tenant, within 20 miles of Leeds, with a job worth over £2,000, who wants work done within three months and is the person who makes the decision.

That gives the assistant five things to establish, and a clear basis for grading.

## Qualifying questions

The questions it asks to work this out. Templates give you a starting set for your industry — a home services assistant asks how urgent the job is; a B2B assistant asks about team size and whether the caller is the decision maker.

Typical dimensions:

* **Authority** — are they the decision maker?
* **Need** — what is the actual problem?
* **Timing** — how urgent is it?
* **Budget** — can they afford it?
* **Fit** — are they the kind of customer you serve?

Ask three or four, not all of them. A caller subjected to a full interview hangs up.

## Asking without interrogating

Set the questions to be woven into the conversation rather than fired in sequence. A caller should feel they had a conversation, not filled in a form out loud.

The assistant can also infer answers it was not told directly — if a caller mentions "our office manager will need to approve it", authority is established without asking.

## Lead score

The assistant assigns a score from your criteria. Scores appear on the lead in **Leads** and can be filtered and sorted.

Use the score to triage, not to discard. A low score means "do not interrupt someone for this", not "this is worthless".

## Not qualified

Decide what happens to callers who do not qualify. They should still be handled courteously — a tenant who cannot buy today may be a homeowner in two years, and rudeness to them shows up in reviews.

Usually the right behaviour is to answer their question helpfully, take the details, and simply not flag it for follow-up.

## Where it goes

Qualification data lands on the lead record: the score, the answers to each question, and the assistant's reasoning.

Your team sees this before they call back, so the first human conversation starts from what is already known instead of repeating the same questions. See [Leads & scoring](/inbox-and-leads/leads-and-scoring).

## Tuning it

Review the scores against what actually converted, after a few weeks. If high-scoring leads are not closing, your criteria describe the customer you want rather than the customer you win — adjust them to match reality.


# Summaries & tagging

How each call is written up afterwards.

Open **AI Receptionist → Summaries & Tagging**.

Every call the assistant handles is written up. This is what your team reads instead of listening to a recording.

## How call summaries are written

Set what the summary should contain and how it should read.

A useful summary answers, in order: who called, what they wanted, what was agreed, and what needs to happen next. Anything else is padding.

You can instruct it to always surface specific things — a quoted price, a promised callback time, a competitor mentioned.

Keep summaries short. A summary nobody reads because it is six paragraphs long has failed at its only job.

## AI write-up versus transcript

Three things are produced per call:

| Artefact       | What it is for                      |
| -------------- | ----------------------------------- |
| **Summary**    | The quick read. What happened.      |
| **Transcript** | The exact words, searchable.        |
| **Recording**  | The audio, if recording is enabled. |

Most people read summaries and only open the transcript when something is disputed or unclear.

## Call tags

Tags categorise calls so you can filter and report on them. Define the set that matches how you actually think about your calls — "new patient", "rebooking", "complaint", "supplier", "wrong number".

The assistant applies them automatically from the content of the conversation.

Keep the list short. Twenty tags means inconsistent tagging and useless reports; six well-chosen ones get used.

## Sentiment

**How you judge sentiment** sets what counts as a good or bad call for your business. This is genuinely business-specific — a raised voice in a complaints line is normal, while the same tone on a booking line is a problem.

Sentiment feeds the escalation rules. If **Escalate frustrated callers automatically** is on, this setting decides what "frustrated" means.

## Collected fields

Any field defined on a call type appears on the record as structured data, separate from the prose summary. These are what integrations and reports read, so they are worth defining properly rather than relying on the summary text.

## Where it all appears

On the call record under **Calls**, on the lead under **Leads**, and in the conversation in your **Inbox**.

If you have a CRM connected, the summary and fields sync there too. See [Integrations](/integrations).


# Caller memory

Let the assistant recognise people who have called before.

Open **AI Receptionist → Caller Memory**.

## What it does

**Recognize returning callers** lets the assistant know it has spoken to someone before, and refer to that earlier conversation.

Without it, every call starts from zero — a customer who rang yesterday about a broken boiler has to explain the whole thing again.

With it:

> "Hello again Mrs Patel — is this about the boiler repair we booked for Thursday?"

## How it works

Callers are matched on their phone number against your contacts. When a match is found, the assistant is given the relevant history: previous calls, what was discussed, any open items.

## What it remembers

Summaries and outcomes of previous conversations, rather than full transcripts. It knows a caller rang about a quote and was told £2,400; it does not replay the whole earlier call.

You can set how far back it looks. A long window is useful for businesses with a slow cycle — legal, property, big-ticket services. A short one is better where the same customer calls often about unrelated things.

## Where the history comes from

The contact record. Every call, message and widget submission from a number is attached to the same contact, so memory covers every channel — the assistant knows about a WhatsApp exchange when the person later rings.

See [Contacts](/inbox-and-leads/contacts).

## Privacy

Caller memory means one caller's information being spoken aloud to whoever is holding that phone.

Consider this for shared numbers — a family landline, a shared office line, a reception desk. If your calls involve health, legal or financial matters, be cautious about how much the assistant volunteers unprompted, and prefer confirming identity before referring to specifics.

You can limit how much it offers before the caller has identified themselves.

## When to leave it off

Turn it off if:

* your calls are mostly one-off strangers, so there is no history to draw on;
* your subject matter is sensitive enough that mistaken identity would be damaging;
* you operate under rules requiring explicit consent before processing call history this way.

## Testing it

Call twice. On the second call, check it recognises you and that what it recalls is accurate and appropriate to say out loud.


# Voice & tone

How your receptionist sounds.

Open **AI Receptionist → Voice & Tone**.

## Choosing a voice

Six voices are available:

| Voice      | Character                    |
| ---------- | ---------------------------- |
| **Olivia** | Warm, friendly · female      |
| **Sophie** | Bright, upbeat · female      |
| **Alex**   | Even, neutral · male         |
| **Ethan**  | Calm, measured · male        |
| **Freya**  | Expressive, British · female |
| **Oscar**  | Deep, authoritative · male   |

Listen to each before choosing. A voice that reads well as a description can be wrong for your callers.

Match the voice to the situation rather than to personal taste:

* **Calm and measured** (Ethan, Alex) suits calls where people are stressed — medical, emergency, complaints.
* **Warm and friendly** (Olivia) suits consumer services and hospitality.
* **Bright and upbeat** (Sophie) suits retail and consumer sales, and grates in a serious context.
* **Authoritative** (Oscar) suits professional services.
* **British** (Freya) matters if your customers are British; an American voice on a UK local number gets commented on.

## Response speed

Three settings:

**Fast — reply quickly.** Short, transactional calls. Risks cutting people off.

**Balanced (recommended).** Where to start.

**Patient — wait for pauses.** For callers who speak slowly, pause to think, or read things out. Choose this for older demographics, and for any call where people recite a policy number or an address.

This setting has more effect on how natural the call feels than the voice does. If callers report being interrupted, move toward Patient before changing anything else.

## Tone of voice

Written instructions about how it should speak. These apply on written channels too.

Be specific and give examples:

> Speak plainly. Short sentences. Do not say "absolutely" or "perfect". If you do not know something, say "I'm not sure, but I can find out and have someone call you back" rather than guessing.

Naming the words you do not want is unusually effective — a generic instruction to "be natural" does far less than a short list of banned filler.

## Pronunciation

If the assistant mispronounces a name, a product or a place, add it under **Specialized terms** in [Scenarios & call types](/ai-receptionist/scenarios-and-call-types). This helps both output and recognition.

## Testing the voice

Always test on a real phone, not only in the browser. Phone audio is narrowband and compressed, and voices that sound clear on laptop speakers can be harder to follow down a line.


# Transfers & escalation

When and where to hand a call to a human.

Open **AI Receptionist → Transfers & Escalation**.

Every assistant needs a way out. This is it.

## Where to transfer

**Transfer to** sets the destination — a team member, a team, or an external number such as a mobile.

You can set more than one for different situations: general enquiries to the office, emergencies to an on-call phone.

## What the caller hears

**What the AI says before transferring** is the line spoken before the handover.

Say what is happening and set an expectation:

> "I'll put you through to Mark now — one moment."

Silence during a transfer makes callers think they have been cut off, and they hang up.

## What the colleague hears

**What the assistant says before connecting** is a whisper played to the person receiving the call, before the two sides are joined.

This is valuable and often skipped. A whisper like "Callback for a boiler repair, existing customer, urgent" means your colleague starts the conversation already informed instead of saying "hello, how can I help?" to someone who has just explained everything.

## When to transfer

Configure the triggers:

**On request.** The caller asks for a person. Always honour this — refusing is the fastest way to make someone angry. Never make a caller ask three times.

**On emergency.** A call matching your emergency definition. Set the on-call number under [Scenarios & call types](/ai-receptionist/scenarios-and-call-types).

**On frustration.** **Escalate frustrated callers automatically** watches sentiment and hands over when a caller is getting annoyed. Worth enabling — the cost of an unnecessary transfer is far lower than the cost of a furious customer stuck with a machine.

**When out of its depth.** When the assistant cannot answer from its knowledge. Better than inventing something.

## If nobody answers the transfer

Set the fallback. Options are voicemail, taking a message, or offering a callback.

{% hint style="warning" %}
An unanswered transfer with no fallback drops the call. Configure this — it is the most damaging failure mode the assistant has, because it happens to the callers who most wanted a human.
{% endhint %}

## Transfers and business hours

Transfers respect availability. Outside your business hours there may be nobody to transfer to, so set what the assistant should do instead — usually take a detailed message and flag it for the morning.

## Warm versus cold

A warm transfer plays the whisper and lets your colleague accept before connecting. A cold transfer connects immediately.

Warm is better for anything sales-related or sensitive. Cold is faster and fine for a simple redirect.

## Test it

Call your assistant, ask for a human, and check: the line is spoken, the right phone rings, the whisper plays, and both sides can hear each other. Then test the unanswered case.


# Calendar & booking

Let callers book straight into your calendar.

Open **AI Receptionist → Calendar & Booking**.

## What it does

The assistant can check real availability and book an appointment during the call — not promise a callback to arrange one.

## Connect a calendar

Connect your calendar under **Settings → Scheduling** or via [Google Calendar](/integrations/google-calendar).

The assistant reads free/busy from the connected calendar, so existing commitments are respected without you maintaining a separate availability list.

## Booking rules

**Which calendar** to book into, when more than one is connected.

**Appointment length** — the default duration. Different call types can book different lengths, so a consultation and a quick check-in do not have to be the same.

**Buffer** — time either side of a booking. Without it, back-to-back appointments leave no room to travel, write up notes or take a breath.

**Notice period** — how soon someone can book. Setting this to two hours stops a caller booking a slot fifteen minutes from now that nobody can make.

**How far ahead** — the booking window. Too far and you fill your calendar with appointments people forget about.

## Availability

Booking availability follows your business hours by default, and can be narrowed further — you may be open all day but only take appointments in the afternoons.

Each team member's own hours also apply if bookings go into individual calendars. See [Hours](/callback/hours).

## What the caller gives you

Set the fields collected at booking. Name and contact details are the minimum; add whatever your team needs to prepare.

For call types set to **Book into my calendar**, the fields on that call type are collected too. See [Scenarios & call types](/ai-receptionist/scenarios-and-call-types).

## Confirmations

Set a confirmation to the caller by SMS or email when a booking is made, and a reminder before it.

Reminders reduce no-shows more than anything else you can configure here. A reminder the day before, and a short one on the day, is the standard pattern.

## Rescheduling and cancelling

The assistant can reschedule or cancel an existing booking on request, if it can identify the caller and find the booking. Caller memory helps here — see [Caller memory](/ai-receptionist/caller-memory).

## Double-booking

Because availability is read live at the moment of booking, two callers cannot take the same slot.

If you also book from elsewhere — a paper diary, a separate system — those bookings are invisible to the assistant unless they are on the connected calendar. Keep one source of truth.

## Test it

Book a real appointment through the assistant and confirm it appears in the calendar with the right time, duration and details attached. Then cancel it.


# Actions & webhooks

What happens automatically after a call.

Open **AI Receptionist → Actions & Webhooks**.

Actions are things that happen automatically once a call ends.

## What actions can do

**Draft & send emails** — email a summary or a follow-up, to the caller or to your team. For example "Email my team about a hot lead".

**Send a text message** — SMS the caller with a confirmation, a link or directions.

**Post to a webhook** — send the call data to your own system.

**Create or update a CRM record** — where a CRM is connected.

## Conditional actions

Actions can be conditional, which is where they become useful. Rather than emailing every call, email only the qualified ones; rather than texting everyone, text only the people who booked.

Set the condition from qualification results, call type, or collected fields.

## Approval mode

**Approval mode** decides whether actions run automatically or wait for a human.

**Let me check it before it sends** holds the action as a draft. Use this for anything customer-facing until you trust it.

**Confirm with the caller before executing** makes the assistant check with the caller before doing something irreversible — worth keeping on for bookings and cancellations.

## Webhooks

**POST to** sends a JSON payload to a URL you control when a call ends.

Configure:

* **Method** — usually POST.
* **Header name** and **Authentication** — a shared secret so your endpoint can verify the request came from LimeCall.
* **Verified-caller param** — passes whether the caller's identity was verified.

The payload includes the call metadata, the summary, the transcript, the collected fields and the qualification result.

{% hint style="warning" %}
Always authenticate your webhook endpoint. An unauthenticated URL that creates records can be called by anyone who discovers it.
{% endhint %}

Your endpoint should return quickly — do the work asynchronously rather than holding the connection open. See [Webhook events](/developers/webhook-events).

## Live lookups in your API

Under **Developers**, **Live lookups in your API** lets the assistant call your API *during* a call and use the answer in conversation — checking an order status, looking up a booking, confirming whether someone is an existing customer.

This is the most powerful feature here and the one most worth getting right. Two rules:

* **Be fast.** The caller is waiting in silence. Target under a second; anything over two is a noticeably awkward pause.
* **Fail gracefully.** If your API is down, the assistant should say it cannot check right now and offer to take a message — not stall.

## Testing actions

Use **Send test** to fire a sample payload at your endpoint before relying on it.

After a real test call, check every action fired: the email arrived, the webhook was received, the CRM record was created.

## Idempotency

Webhook delivery is retried on failure, so your endpoint may receive the same call more than once. Key on the call ID and ignore duplicates, rather than creating a second record each time.


# Company details

Your business name and description — the foundation of what the assistant knows.

Open **AI Receptionist → Company Details**.

This is the first of four Knowledge pages. Together they are what the assistant actually knows about you.

## Company name

The name the assistant uses. Use the name customers know you by, not your registered legal entity — "Northgate Dental", not "Northgate Dental Practice Holdings Ltd".

If you trade under more than one name, use the one matching the number the caller dialled.

## What you do

A short description of the business. This gives the assistant the context to answer questions you never explicitly anticipated.

Write it as you would explain it to a new employee on their first morning:

> We are a family dental practice in Leeds with two dentists and a hygienist. We do routine check-ups, hygiene appointments, fillings, crowns and whitening. We are not an emergency dental service, though we keep two emergency slots a day for existing patients. We take NHS and private patients; the NHS list is currently closed to new patients.

Notice how much that answers implicitly — a caller asking "do you do implants?" gets a correct no, without implants ever being mentioned.

## What you do not do

Worth stating explicitly. The most damaging assistant errors are confident yeses to things you do not offer.

List the adjacent services you are regularly asked for and do not provide, and what to say instead — ideally a referral, which turns a no into something useful.

## Where the initial content came from

If you gave your website at signup, much of this is pre-filled from a scan of your site.

Read it critically. A scraper extracts what is written on the page, including prices from an out-of-date pricing page and services you stopped offering.

## Keeping it current

This is the page that most often goes stale. When your business changes — new service, dropped service, moved premises, changed hours — this is where to update it, and the change takes effect on the next call.

{% hint style="warning" %}
Everything here is said to real customers as fact. A wrong detail is not a cosmetic problem; it is a promise you did not mean to make.
{% endhint %}

## Next

* [Contact information](/ai-receptionist/contact-information)
* [Products & services](/ai-receptionist/products-and-services)
* [Additional knowledge](/ai-receptionist/additional-knowledge)


# Contact information

Where and when customers can reach you.

Open **AI Receptionist → Contact Information**.

## Address

Your business address. The assistant uses it to answer "where are you?", give directions and confirm whether you cover a caller's area.

Add anything a visitor genuinely needs that a map does not tell them — which entrance to use, where to park, that you are above a shop with an easily missed door.

## Opening hours

When customers can reach you.

These should match your business hours under **Settings → Business hours**. If they disagree, the assistant tells callers one thing while your routing does another — and the caller believes the assistant.

Include the exceptions people actually ask about: lunchtime closing, different Saturday hours, and what happens on public holidays.

## Phone and email

The contact details the assistant can give out. Be deliberate — a direct dial given to every caller stops being a direct dial.

## Service area

If you travel to customers, define the area you cover. Be specific: named towns, postcode prefixes, or a radius from a point.

This is a common source of wasted calls. An assistant that does not know your limits will happily book a job ninety minutes outside your area, and someone has to ring back and cancel it.

Also say what happens just outside the boundary — whether you travel for larger jobs, or refer to a partner.

## Out of hours

What the assistant should tell people when you are closed. Give it something useful:

* when you next open,
* what to do in an emergency,
* that it can take a message or book them in now.

"We're closed" alone is a wasted call. "We're closed now but I can book you in for tomorrow morning — would 9:30 work?" keeps the customer.

## Multiple locations

If you have several sites, enter each with its own address, hours and service area, and describe how the assistant should decide which one a caller needs — usually by asking where they are.

## Keeping it accurate

Wrong hours are the most commonly reported assistant error, because hours change more often than anything else here. When you change your hours, change them in both places: here and under **Settings → Business hours**.


# Products & services

What you offer, and the prices the assistant may quote.

Open **AI Receptionist → Products & Services**.

## What you offer

List your services or products. For each, give a short description in the language customers use, not your internal name for it.

A caller asks for "a filling", not "a direct composite restoration". List both if it helps, but lead with theirs.

## Prices

The most sensitive thing on this page, because anything here will be quoted to a customer as fact.

Three options per item:

**A fixed price.** Only where the price genuinely is fixed. "£65 for a check-up."

**A range.** Where it varies. "Between £150 and £400 depending on the size."

**No price.** Where quoting would be misleading. Tell the assistant what to say instead — "it depends on the job, I can book a free survey".

{% hint style="warning" %}
A price the assistant states is a price your customer heard from your business. Leave it blank rather than approximate, and update it the day your prices change.
{% endhint %}

## What affects the price

If your pricing depends on variables — size, urgency, distance, materials — say so, and say which questions establish it. The assistant can then either give a properly conditioned answer or collect what is needed for a real quote.

## What you do not offer

List the adjacent things you are asked for and do not provide, with what to say instead. A referral to someone who does it turns a dead end into goodwill.

## Availability and lead times

If something has a waiting list or a lead time, record it. "Our next new-patient appointment is about three weeks out" manages expectations far better than discovering it at booking.

## Offers

Current promotions can go here, with their end date. Remember to remove them — an assistant still offering January's promotion in March is a problem.

## Keeping it current

This page and [Company details](/ai-receptionist/company-details) go stale fastest. Set a recurring reminder to read both, and check them whenever prices change.

## Testing

Call your assistant and ask about price for your three most commonly requested services. Then ask about something you do not do. Both answers should be right.


# Additional knowledge

FAQs, policies and files the assistant can draw on.

Open **AI Receptionist → Additional Knowledge**.

Everything that does not fit the other three Knowledge pages — the facts, policies and documents your assistant should be able to draw on.

## What to put here

**Frequently asked questions.** Start with the questions your team actually answers every day. If you have to explain your parking situation six times a week, write it down once here.

**Policies.** Cancellation terms, deposits, refunds, guarantees, what happens if someone is late.

**Procedures.** What a first appointment involves, what to bring, how long things take.

**Facts that do not fit elsewhere.** Accreditations, languages spoken, accessibility, whether you are dog-friendly.

## Writing good entries

Write in question-and-answer form where you can. It matches how callers ask and gives the assistant a clear pairing.

Be complete in the answer. A partial answer produces a follow-up question the assistant may not be able to handle.

> **Do you take card payments?** Yes — all major cards including Amex, plus Apple Pay and Google Pay. We do not take cheques. Card payment is taken at the end of the appointment, not in advance.

That answers the question and the two that follow it.

## Files

Upload documents the assistant can draw on — price lists, terms, service brochures, FAQs you already maintain.

Keep uploads focused. A well-structured two-page FAQ is more useful than a forty-page brochure, because everything in a long document competes for relevance.

Text-based PDFs work; a scanned image of a document does not, unless it has been through OCR.

## Keeping it accurate

Uploaded files are a common source of stale answers, because a document uploaded once is easy to forget. When you revise a price list, replace the file here too.

{% hint style="info" %}
If the assistant gives a wrong answer, the fix is almost always here or in the other Knowledge pages — not in the scenario instructions. Correct the fact rather than instructing the assistant around it.
{% endhint %}

## What not to put here

Do not upload anything containing personal data about your customers, internal credentials, or commercially sensitive material you would not want read aloud. Assume anything here can be surfaced to a caller who asks the right question.

## Testing

After adding knowledge, call the assistant and ask about it — in your own words, not the words you wrote. Then ask something adjacent that you have deliberately not covered, and check it says it does not know rather than inventing an answer.


# Spam & blocking

Keep junk and specific callers away from the AI.

Open **AI Receptionist → Spam & Blocking**.

Every AI minute spent on a robocall is one you paid for.

## Screen spam and robocalls

**Screen spam & robocalls** detects automated and nuisance calls and stops them reaching the assistant.

Detection uses call characteristics and reputation data. It is not perfect in either direction, so review what it catches for the first week.

## Blocking specific callers

**Never let the AI answer these people** is an explicit block list, by phone number.

Use it for:

* persistent nuisance callers,
* cold-callers who keep coming back,
* numbers you would rather route to a person.

Blocked callers do not reach the assistant. Set what they get instead — a message, voicemail, or a plain disconnect.

## Blocking from a call record

The quickest route is after the fact. On any call in **Calls** or lead in **Leads**, choose **Block it**. If you block something by mistake, **Not spam** reverses it.

## Anonymous and withheld numbers

Decide how to handle calls with no caller ID. Many are legitimate — people calling from switchboards or with privacy settings on — so blocking them outright loses real customers.

A reasonable middle ground is to let them through but not apply caller memory, since there is no number to match on.

## International calls

If you only serve one country, calls from unexpected international ranges are worth screening. This also limits exposure to toll-fraud patterns that target inbound numbers.

If you do serve internationally, do not enable this — you will block customers.

## What blocking does not do

Blocking is per-account and applies to your numbers only. It does not report the caller to anyone, and it does not stop them calling — it stops them reaching your assistant.

## Reviewing

Check the blocked and screened calls periodically. If real customers are being caught, loosen the screening; if junk is getting through, add the numbers to the block list.

Every blocked call is AI minutes you did not spend — see [AI minutes & usage](/ai-receptionist/ai-minutes-and-usage).


# Test your assistant

What to check before real customers call it.

Open **AI Receptionist → Test your agent**.

Do not skip this. Reading a configuration tells you what you intended; a test call tells you what you built.

## Two ways to test

**Test agent in the browser** — fastest for iterating. Talk to it directly from the dashboard.

**A real phone call** — how customers will actually experience it. Phone audio is narrower and more compressed, so always confirm on a real call before going live.

## Test as your worst caller, not your best

Anyone can have a good call with their own assistant, because you know what to say. Test the awkward cases:

* Mumbling, or a noisy background.
* Interrupting mid-sentence.
* Asking something you have not covered.
* Asking for a price on your most complicated service.
* Asking for a human immediately.
* Being rude.
* Asking "am I talking to a robot?"
* Going quiet.
* Changing your mind halfway through a booking.

## The checklist

**Greeting** — correct name, right business, and short enough not to be interrupted.

**Knowledge** — ask about your three most common enquiries. Every answer correct?

**Prices** — ask what things cost. Are the numbers right, and does it decline to guess where it should?

**Boundaries** — ask about something you do not do. Does it say no and offer a referral, or invent a service?

**Qualification** — play a good lead and a poor one. Do the scores reflect reality?

**Booking** — book an appointment. Does it appear in the calendar with the right details?

**Transfer** — ask for a human. Does the line get spoken, the right phone ring, and the whisper play?

**Emergency** — describe an emergency in your business's terms. Does it escalate?

**Write-up** — hang up and read the summary. Would your team know what to do from it alone?

## Listen for these failure modes

**Inventing things.** The most serious. It should say it does not know.

**Being interrupted.** If it talks over callers, move response speed toward Patient.

**Mishearing terms.** Add them under **Specialized terms**.

**Rambling.** Tighten the tone instructions.

**Refusing to transfer.** Fix immediately — it makes callers furious.

## Test the routing too

A perfect assistant on a number pointing somewhere else helps nobody. Call the actual published number and confirm the assistant answers it.

## After you change anything

Retest. Prompt edits have effects you will not predict from reading them — a line added to fix one behaviour frequently changes another.

Use **Version history** to compare against what worked, and restore if a change made things worse.

## Before going live

* Prices correct.
* Hours correct and matching **Settings → Business hours**.
* Transfer destination set and answering.
* Fallback set for unanswered transfers.
* Recording and AI disclosure appropriate for your jurisdiction — see [Recording, consent & AI disclosure](/ai-receptionist/recording-consent-and-disclosure).
* Enough AI minutes for expected volume — see [AI minutes & usage](/ai-receptionist/ai-minutes-and-usage).


# AI minutes & usage

How AI time is metered, and how to avoid running out.

## What an AI minute is

Time your AI receptionist spends on a call, metered separately from ordinary call minutes.

A call answered by a human uses call minutes. The same call answered by the AI uses AI minutes. A call the AI answers and then transfers uses AI minutes for the AI's portion and call minutes for the rest.

## Where to see your balance

**Settings → Usage & credits** shows what you have used this period and what is left. The **Overview** pane of the AI Receptionist also shows whether it is answering right now and what it has left to answer with.

## What is included

Your plan includes an allowance per billing period. It resets at the start of each period and does not roll over.

See [Plans & billing](/account/plans).

## Running past your allowance

Usage beyond your included allowance draws on credits — **AI overage credit**. If you have a credit balance, the assistant keeps answering and draws down.

If you have no credits and no allowance left, **the assistant stops answering**.

{% hint style="warning" %}
When the assistant runs out of minutes, calls do not fail visibly — they fall through to whatever else that number is configured to do. If nothing is configured, callers get nothing. Set a fallback destination on every number the AI answers.
{% endhint %}

## Do not find out from a customer

Set a usage alert under **Settings → Notifications** so you are warned before you run out rather than after.

A sensible threshold is around 80% of your allowance — enough warning to top up before the weekend.

## What uses more than you expect

**Spam and robocalls.** Every one is metered. Enable screening — see [Spam & blocking](/ai-receptionist/spam-and-blocking).

**Long silences.** A caller who puts the phone down without hanging up keeps the call open. Set a sensible maximum call length.

**Patient response speed.** Longer waits mean longer calls. Worth it for the experience, but it does add up.

**Testing.** Test calls are metered like real ones. Keep them short.

## Reducing usage without losing calls

* Screen spam aggressively.
* Tighten the greeting — three seconds saved on every call adds up quickly.
* Keep required fields to what you will act on. Every extra question is call time.
* Transfer early on calls the AI cannot resolve.

## Topping up

Add credits under **Settings → Usage & credits**. See [Usage & credits](/account/usage-and-credits).

If you regularly exceed your allowance, moving up a plan is usually cheaper than repeated top-ups.

## Where usage is reported

Under **Analytics**, alongside call volume and outcomes, so you can see cost against results rather than in isolation.


# Recording, consent & AI disclosure

What you must tell callers about recording and about talking to an AI.

{% hint style="warning" %}
This page explains what the product does and points at the obligations that commonly apply. It is not legal advice. Requirements vary by country and by state, and they change. Check your own position before going live.
{% endhint %}

## Two separate obligations

They are often confused, and they are not the same thing:

1. **Recording disclosure** — telling people the call is recorded.
2. **AI disclosure** — telling people they are talking to an AI.

You may be subject to one, both, or neither, depending on where you and your callers are.

## Recording

### One-party and two-party consent

In some jurisdictions only one participant needs to consent, which can be you. In others — including several US states such as California, Florida, Pennsylvania, Illinois, Washington and Massachusetts — **every** participant must consent.

The stricter rule generally applies when a call crosses jurisdictions. If you take calls from anywhere in the US, the practical approach is to disclose on every call.

### In Europe

Under GDPR, recording is processing personal data. You need a lawful basis, you must tell people at the point of collection, and you must be able to honour access and deletion requests.

### How to disclose

Enable **Tell callers the call is recorded** under [Your assistant](/ai-receptionist/your-assistant). This adds a notice to the greeting.

Put it in the opening line, before the caller says anything substantive:

> "Thanks for calling Northgate Dental, this is Sarah. This call is recorded for quality and training. How can I help?"

If someone objects, you need a path that does not record — usually a transfer to a human on a line without recording.

### Turning recording off

Recording is configured per number. If you cannot meet the disclosure requirements, turn it off. You still get transcripts and summaries.

## AI disclosure

### Where it is required

A growing number of jurisdictions require businesses to disclose that a caller is interacting with an AI rather than a person. California's bot-disclosure law is the best-known example, the EU AI Act contains transparency obligations for systems that interact with people, and several other US states have introduced similar rules.

Requirements differ on **when** disclosure is needed — some only when the AI is used to sell or influence, others more broadly.

### Never claim to be human

Whatever your jurisdiction requires, do not instruct the assistant to deny being an AI when asked directly. Aside from the legal exposure, a caller who catches you in it will not trust anything else they were told.

### How to disclose

The simplest approach is the opening message:

> "Thanks for calling Northgate Dental. I'm Sarah, an AI assistant — I can book you in or answer questions, and I'll put you through to the team whenever you'd like."

That discloses, sets expectation, and offers the escape route in one line. In practice callers accept this readily — what upsets people is discovering it later.

## Practical checklist

* Decide whether your jurisdiction and your callers' require recording consent.
* Decide whether AI disclosure applies to you.
* Put whatever is needed in the opening message, not buried later.
* Give callers a working way to reach a human — see [Transfers & escalation](/ai-receptionist/transfers-and-escalation).
* Make sure the assistant never denies being an AI.
* Know how you would honour a deletion request for a recording.

## Data handling

Recordings, transcripts and summaries are stored against the call record. Access is controlled by your team's roles — see [Team & roles](/account/team-and-roles).

For a data processing agreement or details of sub-processors, contact support.


# Virtual Phone Numbers

Buy or port business numbers, route them to people, teams or your AI, and text from them.

A virtual number is a phone number that belongs to your LimeCall account rather than to a handset. Nothing is plugged in anywhere. You decide what each number does, and you can change it whenever you like.

## What you can do with one

* Publish a local number in a city you have no office in.
* Take a toll-free number so customers are not charged.
* Route each number somewhere different — a person, a team, voicemail or your AI receptionist.
* Send and receive SMS, where the number supports it.
* Keep personal mobiles private while still taking business calls on them.
* Give each campaign or region its own number and see which generates calls.

## Getting a number

Two routes:

**Buy one** — pick from the catalogue and it is live in minutes. See [Buy a number](/virtual-numbers/buy-a-number).

**Bring your existing one** — port it from your current provider, keeping the number your customers already know. Takes days to weeks. See [Bring your number (porting)](/virtual-numbers/bring-your-number).

{% hint style="info" %}
Numbers require a paid plan. On a trial you can browse the catalogue but not purchase.
{% endhint %}

## Regulatory requirements

Many countries require a verified local address, and some require identity documents, before they will issue a number. This is telecoms regulation, not a LimeCall policy.

Start this early — approval can take several business days and is the usual reason a number takes longer than expected. See [Addresses & verification](/virtual-numbers/address-and-verification).

## Deciding who answers

Each number has a destination, set under **Who answers your calls**:

| Destination             | Behaviour                 |
| ----------------------- | ------------------------- |
| **Team member**         | Rings one person.         |
| **Team**                | Rings a group.            |
| **Forward to a number** | Rings an external number. |
| **Voicemail**           | Straight to a greeting.   |
| **AI receptionist**     | Your AI answers, 24/7.    |

You can set a different destination for **When busy**. See [Call forwarding & routing](/virtual-numbers/call-forwarding-and-routing).

## In this section

* [Buy a number](/virtual-numbers/buy-a-number)
* [Bring your number (porting)](/virtual-numbers/bring-your-number)
* [Addresses & verification](/virtual-numbers/address-and-verification)
* [Caller ID](/virtual-numbers/caller-id)
* [Call forwarding & routing](/virtual-numbers/call-forwarding-and-routing)
* [Voicemail](/virtual-numbers/voicemail)
* [SMS & messaging](/virtual-numbers/sms-and-messaging)
* [US carrier registration (10DLC)](/virtual-numbers/us-carrier-registration)
* [Devices](/virtual-numbers/devices)


# Buy a number

Choose and purchase a local or toll-free number.

Open **Phone Numbers → Buy a number**.

## Choose a country

Start with the country. Availability, price and regulatory requirements all differ by country, and some require documentation before a number can be issued — see [Addresses & verification](/virtual-numbers/address-and-verification).

## Local or toll-free

**Local numbers** carry an area code. They signal that you are nearby, which raises answer rates for consumer and trades businesses, and they are cheaper.

**Toll-free numbers** are free for the caller. They read as established and national, and are the convention for support lines in the US. They cost more, and in the US they have their own verification process before they can send messages.

## Check the capabilities

Each number lists what it can do — voice, SMS, MMS. **Not every number supports texting.**

If you intend to text from the number, confirm SMS is listed before buying. Adding it afterwards is not possible; you would need a different number.

## Search

Filter by area code to get a number in a specific city, or search for a pattern if you want something memorable. Memorable numbers matter for anything printed on a van or a billboard, and not at all for a number that only ever appears as a clickable link.

## Buy it

Select the number and confirm. It is attached to your account immediately and billed monthly from that date.

If the country requires an address or documents, you are taken to supply them. The number is reserved while approval is pending.

## Set it up

A new number does nothing useful until you configure it.

1. **Who answers your calls** — the destination. See [Call forwarding & routing](/virtual-numbers/call-forwarding-and-routing).
2. **Caller ID** — what recipients see when you call out. See [Caller ID](/virtual-numbers/caller-id).
3. **A label** — name it for what it does. "Google Ads — Leeds" is useful in six months; "Number 3" is not.
4. **Tracking source** — attributes calls to a campaign or channel in your reporting.

## Test it

Call it from your mobile. Confirm it rings the right destination, and that a record appears under **Calls**.

## Costs

Numbers carry a monthly rental, separate from call and message charges. Usage rates vary by destination country.

See [Usage & credits](/account/usage-and-credits).

## Releasing a number

You can release a number you no longer need, which stops the monthly charge.

{% hint style="warning" %}
Releasing is permanent. The number returns to the carrier's pool and you will almost certainly not get it back. Check it is not printed on anything or configured as a caller ID before releasing it.
{% endhint %}


# Bring your number (porting)

Move an existing number from another provider to LimeCall.

Open **Phone Numbers → Bring your number**.

Porting moves a number you already own to LimeCall, keeping the number your customers know.

## Before you start

**Do not cancel your existing service.** This is the single most important rule of porting. A cancelled number is released back to the carrier and can no longer be ported — it is simply gone. Keep the old account active and paid until the port completes.

## What you need

**A recent bill** from your current provider, showing the account number, the service address and the account holder's name exactly as they hold it.

**The account number and PIN** for the losing carrier. Many mobile carriers require a transfer PIN generated from your account.

**Authorisation** — a Letter of Authorisation, signed by the person named on the account.

**Matching details.** The name and address you give must match the losing carrier's records character for character. A mismatch is the most common cause of rejection — "Suite 4" against "Ste 4" is enough to fail.

## Submit the request

1. Open **Phone Numbers → Bring your number**.
2. Enter the numbers to port.
3. Supply the account details and upload your bill and authorisation.
4. Submit.

## How long it takes

| Type            | Typical              |
| --------------- | -------------------- |
| US/Canada local | 2–4 weeks            |
| US toll-free    | 2–4 weeks            |
| UK geographic   | 2–4 weeks            |
| Mobile numbers  | Varies; often faster |
| Other countries | Varies considerably  |

Treat any date as provisional until the losing carrier confirms it.

## If it is rejected

Rejections are common and usually clerical:

* Name or address does not match the carrier's records.
* Account number or PIN wrong.
* A pending order on the account at the losing carrier.
* The number is part of a bundle that must be split first.
* Outstanding balance on the account.

You will be told the reason. Correct it and resubmit — a rejection does not prevent a fresh attempt.

## Partial ports

If you are porting some numbers from an account but not all, say so explicitly. Porting the main billing number of an account can disconnect the others.

## On the day

Porting completes during a cutover window. There may be a short period where calls route unpredictably.

Plan for it: pick a quiet time of day, have a colleague available to test immediately, and do not port on the morning of a campaign launch.

## After it completes

1. Configure who answers it — see [Call forwarding & routing](/virtual-numbers/call-forwarding-and-routing).
2. Test inbound calls and, if applicable, SMS.
3. Set caller ID — see [Caller ID](/virtual-numbers/caller-id).
4. **Then** cancel the old service.

{% hint style="info" %}
US numbers need separate carrier registration before they can send messages, even after porting. See [US carrier registration (10DLC)](/virtual-numbers/us-carrier-registration).
{% endhint %}


# Addresses & verification

The regulatory documents some countries require before issuing a number.

Open **Phone Numbers → Addresses** and **Phone Numbers → Verification**.

Many countries will not issue a phone number without a verified address, and some require identity documents. This is telecoms regulation in the destination country, not a LimeCall policy, and LimeCall cannot waive it.

## Addresses

Add the addresses you will register numbers against under the **Addresses** tab.

Requirements vary:

| Requirement                                    | Where it is common              |
| ---------------------------------------------- | ------------------------------- |
| Any address                                    | Some countries, minimal checks. |
| A local address in the country                 | Much of Europe.                 |
| A local address in the specific city or region | Where numbers are geographic.   |
| Proof of address document                      | Several European countries.     |

{% hint style="warning" %}
A "local address" generally means a real place of business, and providing an address you have no connection to can mean losing the number and the account. If you have no presence in a country, a toll-free or non-geographic number is usually the legitimate route.
{% endhint %}

## Verification

The **Verification** tab holds the document bundles regulators require. Depending on the country and number type you may need:

* Proof of identity for the account holder — passport or national ID.
* Proof of business — registration or incorporation certificate.
* Proof of address — a recent utility bill or lease.
* A declaration of intended use.

## Getting documents accepted

Most rejections are avoidable:

* **Legible.** Photograph in good light, flat, all four corners visible. Scans beat photos.
* **Current.** Utility bills are usually required to be within the last three months.
* **Consistent.** The name and address must match across every document and your account details.
* **Complete.** Every page, including blank ones, where a multi-page document is requested.
* **Unedited.** Do not crop, annotate or redact. Alterations cause rejection.

## How long it takes

Usually a few business days. Some regulators take longer, and some require a physical letter.

Start before you need the number. Discovering a two-week verification the day a campaign launches is avoidable.

## While you wait

The number is reserved. You are not billed for it until it is issued, and you cannot route calls to it yet.

## Toll-free verification

US toll-free numbers have their own verification before they can send messages, separate from 10DLC. You submit details of your business and what you will send, and approval typically takes a few business days.

Until it passes, messages from a toll-free number are heavily filtered.

## Keeping documents current

Some registrations must be renewed, and some regulators require you to notify them when your address changes. If your registered address is out of date, numbers can be suspended.

Review this whenever you move.

## If something is rejected

You are told why. Fix the specific issue and resubmit — usually a clearer scan or a document within the date window. Repeated rejections of the same document without change do not succeed.


# Caller ID

Control what people see when you call them.

Open **Phone Numbers → Caller ID**.

Caller ID is the number displayed to the person you are calling. Getting it right materially changes how many people answer.

## The three settings

LimeCall separates caller ID by purpose, because the right answer differs.

**Account default** — used when nothing more specific is set.

**Callback caller ID** — shown when the widget connects a callback. This is the one that matters most. The visitor just asked to be called and is watching their phone; if an unrecognised number appears, a good share will not answer. Use a number that matches your brand and ideally the visitor's region.

**Outbound caller ID** — the default for calls your team dials.

## Per-number overrides

Any individual number can override the account default. Useful when a regional team should show a local number, or when a campaign line should always present itself as that campaign.

## Showing a number you own elsewhere

To display a number that is not in your LimeCall account — an existing office line, for example — verify it first.

1. Open the **Caller ID** tab and add the number.
2. LimeCall calls it and reads out a verification code.
3. Enter the code.

You must be able to answer that number to complete this. It is a carrier requirement designed to prevent spoofing, and there is no way around it.

## Local presence

Showing a local number raises answer rates, particularly for consumer calls. People answer a number that looks like their area.

Buy a number in each region you sell into and set it as the caller ID for calls to that region. See [Buy a number](/virtual-numbers/buy-a-number).

{% hint style="warning" %}
Do not rotate through many numbers to evade filtering. Carriers detect the pattern and flag the numbers as spam, which is much worse than the problem you were solving.
{% endhint %}

## Getting marked as spam

Modern phones label suspected spam, and a labelled number is largely useless.

What causes it: high volume from a new number, short call durations, low answer rates, and recipients marking calls as spam.

What helps:

* Warm a new number up gradually.
* Call people who are expecting it — callbacks are ideal.
* Register your number with the US caller-ID registries if you call US numbers.
* Do not use a single number for high-volume cold outbound.

## Withheld caller ID

You can withhold caller ID, but almost nobody answers an unknown number, and some networks reject withheld calls outright. There is rarely a good reason.

## The "call us" number

Separately, the widget can display a number for visitors who prefer to dial you. Set this under [General settings](/callback/general). It must be a number you own.

## Testing

Call your own mobile from LimeCall and check what appears. Test each configuration you have set — callback and outbound can differ, and only testing both reveals it.


# Call forwarding & routing

Decide who answers each number, and what happens when they do not.

Open **Phone Numbers** and, on any number, set **Who answers your calls**.

## Destinations

| Destination             | Behaviour                                                  |
| ----------------------- | ---------------------------------------------------------- |
| **Team member**         | Rings one person, wherever they have chosen to take calls. |
| **Team**                | Rings a group, in that group's configured order.           |
| **Forward to a number** | Rings an external number — a mobile, an existing landline. |
| **Voicemail**           | Straight to a greeting.                                    |
| **AI receptionist**     | Your AI answers, around the clock.                         |

## Routing rules

Two rules can be set per number:

**All inbound calls** — the primary destination.

**When busy** — where calls go if the primary destination is engaged or does not answer.

The busy destination is the one people forget. Setting it to your AI receptionist means overflow gets answered instead of abandoned, which is usually the single highest-value routing change available to you.

## How a team rings

A team destination rings its members according to how that team is configured under **Settings → Team**. Common patterns are ringing everyone at once, ringing in a fixed order, or distributing evenly.

Ringing everyone connects fastest. A fixed order is better where seniority or specialism matters.

## Availability

Two layers decide whether there is anyone to ring:

**Business hours** (**Settings → Business hours**) — whether the company is open.

**Personal hours** (**Settings → My hours**) — whether that individual is available.

A call during business hours when every individual is outside their own hours has nobody to ring, and falls through to your busy or fallback destination. When routing behaves unexpectedly, check both layers.

## Where a person actually answers

Each team member chooses under **Settings → My calls** and **Settings → Devices** — in the browser, on a desk phone, on a softphone, or by forwarding to their mobile. See [Devices](/virtual-numbers/devices).

## Ring duration

Set how long to ring before moving on. Too short and people cannot reach their phone; too long and the caller gives up. Around 20–25 seconds suits most teams.

## When nobody answers

Set the fallback explicitly. Options are voicemail, the AI receptionist, or forwarding elsewhere.

{% hint style="warning" %}
A number whose destination does not answer and which has no fallback simply drops the call. The caller hears ringing and then nothing, and you have no record of who it was.
{% endhint %}

## Combining with the AI

Common arrangements:

* **Team first, AI on busy** — humans answer what they can, AI catches the rest.
* **AI first, transfer to team** — AI screens and qualifies, passes on the good ones.
* **Team in hours, AI outside** — driven by business hours.

## Testing

Test every path, not just the main one: answer normally; let it ring out; call while the line is busy; call outside business hours. Each should land where you expect.


# Voicemail

Greetings, where messages land, and why the AI is usually better.

Voicemail is available as a destination on any number, and as a fallback when nobody answers.

## Setting it up

Set a number's destination to **Voicemail**, or set it as the fallback under **When busy**.

## The greeting

Record or upload a greeting, or have one generated from text.

A good greeting is short and tells the caller what to do and what to expect:

> "You've reached Northgate Dental. We're closed right now — leave your name, number and what you need, and we'll call you back when we open at 8:30. For a dental emergency, call 0113 496 0000."

That gives them an alternative, a timeframe and an emergency route. Compare a greeting that says only "leave a message after the tone", which tells the caller nothing about whether anyone will hear it.

## Different greetings for different situations

Where supported, set separate greetings for out-of-hours and for busy. A caller who rang during your advertised opening hours and got voicemail should hear something that acknowledges that, rather than a message saying you are closed.

## Where messages go

Voicemails appear in your **Inbox** as conversations, attached to the caller's contact record, and in **Calls** as call records.

They are transcribed, so you can read a message instead of listening to it — much faster to triage, and searchable afterwards.

## Notifications

Set alerts under **Settings → Notifications** so a voicemail reaches someone. A message nobody is told about sits unheard.

Email with the transcription is the most practical default.

## Why the AI is usually better

For most businesses, pointing the fallback at the AI receptionist rather than voicemail is a straight improvement.

A voicemail is a one-way message that half your callers will not leave — most people hang up on voicemail and call a competitor. The AI has an actual conversation: it answers the question, qualifies the caller, books the appointment, and escalates a genuine emergency.

Keep voicemail as the destination when:

* your callers specifically expect it,
* the AI is out of minutes and you need a safety net,
* you are not yet confident in the AI for a particular line.

See [AI Receptionist](/ai-receptionist).

## Retention

Voicemails and their transcripts are kept with the call record. Consider your data retention obligations, particularly if callers leave sensitive information — a voicemail is a recording and is subject to the same rules. See [Recording, consent & AI disclosure](/ai-receptionist/recording-consent-and-disclosure).


# SMS & messaging

Send and receive text messages from your numbers.

## What you need

**A number with SMS capability.** Not all numbers have it — check capabilities before buying. See [Buy a number](/virtual-numbers/buy-a-number).

**Carrier registration, for US recipients.** Required before you can reliably text US numbers. See [US carrier registration (10DLC)](/virtual-numbers/us-carrier-registration).

## Sending a message

From the **Inbox**, open a conversation and reply, or start a new message to a contact. Messages are threaded with everything else from that person — calls, WhatsApp, email — on one timeline.

## Receiving

Inbound messages arrive in the **Inbox**. They can be answered by a person, or by your AI receptionist if you have enabled the text channel. See [Text messages](/ai-receptionist/text-messages).

## Templates and signatures

Set message templates and signatures under **Settings → Inbox** and **Settings → Messaging**, for the replies you send repeatedly.

## Auto-replies

Simple trigger-based automatic replies are configured under **Settings → Messaging** — for example, an acknowledgement to a message received out of hours.

These are fixed text, not the AI. If both are enabled, make sure they are not both responding to the same message.

## Campaigns

To message many contacts at once, use **Campaigns** rather than the Inbox. See [Campaigns](/inbox-and-leads/campaigns).

## Deliverability

Texting is heavily filtered by carriers. What gets messages delivered:

* **Register properly.** Unregistered US traffic is blocked. This is not optional.
* **Identify yourself.** Say who you are in the first message; a message from an unknown number with no sender name looks like a scam.
* **Include opt-out instructions** on bulk messages.
* **Avoid link shorteners.** Public shorteners are strongly associated with spam. Use your own domain.
* **Send at reasonable hours** in the recipient's time zone. Many jurisdictions restrict the hours for commercial messages.

{% hint style="warning" %}
Carriers filter silently. A message can be accepted by the API, reported as sent, and never delivered. If delivery rates look wrong, check your registration status first.
{% endhint %}

## Opt-outs

Replies of STOP, UNSUBSCRIBE, CANCEL and similar suppress the contact automatically, and no further messages are sent to them.

This is a legal requirement in most markets. Do not attempt to work around it — the penalties are significant and the suppression protects your numbers' reputation.

## MMS

Some numbers support picture messaging. Check capabilities before relying on it, and note MMS is not universally supported outside North America.

## Costs

Messages are charged per segment. A long message is split into several segments and billed accordingly, and using emoji or other non-GSM characters reduces the characters per segment considerably — a single emoji can nearly halve it.

See [Usage & credits](/account/usage-and-credits).

## If messages are not arriving

See [Texts are not being delivered](/troubleshooting/sms-not-sending).


# US carrier registration (10DLC)

What you must register before texting US numbers, and how.

Open **Settings → Messaging**, or **Settings → US carrier registration**.

## What it is

10DLC — ten-digit long code — is the US scheme for businesses sending application-to-person text messages from ordinary local numbers.

US carriers require every business to register its identity and its messaging campaigns before messages are delivered. Unregistered traffic is filtered or blocked outright.

{% hint style="warning" %}
This is enforced by US carriers, not by LimeCall. No provider can send unregistered A2P traffic to US numbers reliably, and no setting in LimeCall bypasses it.
{% endhint %}

## Who needs it

Anyone sending text messages to US phone numbers from a US local number, including:

* appointment reminders and confirmations,
* notifications and alerts,
* AI receptionist text replies,
* marketing messages.

It applies to transactional messages as well as marketing.

You do not need it if you never text US numbers.

## The two stages

**Brand registration.** Your business identity — legal name, EIN or equivalent tax ID, address, website, and a contact. The details must match your official registration exactly; a mismatch against tax records is the most common failure.

**Campaign registration.** What you will actually send. You describe the use case, provide sample messages, and show how people opt in and opt out.

## Getting the campaign approved

Reviewers check specific things:

* **Sample messages** must be realistic and include your business name.
* **Opt-in** must be described accurately and demonstrably — where on your site people consent, and what the wording says. If you claim web opt-in, the reviewer may look at the page.
* **Opt-out** instructions must be present.
* **Use case** must match what you actually send. Registering as transactional and sending marketing gets the campaign revoked.

## How long it takes

Brand registration is often same-day to a few days. Campaign approval typically takes a few business days, longer if anything needs clarifying.

Start well before you need it.

## Throughput

Approved campaigns get a throughput allowance based on your brand's trust score. Higher trust means more messages per minute.

Trust improves with a verified EIN, a real website and a clean sending history.

## Toll-free is different

Toll-free numbers use a separate toll-free verification process, not 10DLC. If you are only using a toll-free number, do that instead. See [Addresses & verification](/virtual-numbers/address-and-verification).

## What happens without it

Messages are accepted by the system and then filtered by carriers. You see them as sent; recipients never receive them. There is often no error, which is why unregistered accounts can appear to be working for some time before anyone notices.

If your delivery rates look wrong, check registration status before anything else.

## Outside the US

10DLC is US-specific. Other countries have their own rules — the UK and much of Europe use alphanumeric sender IDs with their own registration, and some countries require pre-registered templates. Check the requirements for each country you message.


# Devices

Take calls in your browser, on a desk phone or on a softphone app.

Open **Settings → Devices**.

Choose where your calls actually ring.

## Ring in browser

Calls ring in the LimeCall dashboard and you speak through your computer.

Nothing to install, but it requires:

* the dashboard open in a tab,
* microphone permission granted to the browser,
* a stable connection.

Best for people working at a desk all day. Use a headset — laptop microphones pick up the room and produce echo.

{% hint style="info" %}
If the browser never rings, microphone permission is the usual cause. Check the padlock icon in the address bar and confirm microphone access is allowed for app.limecall.com.
{% endhint %}

## Forward to a phone

Calls ring an ordinary phone number — typically a mobile.

The most reliable option, because it uses the normal phone network rather than your internet connection. Best for people who are out, on site, or driving.

Your mobile number stays private; the caller sees your LimeCall caller ID.

## Desk phone or softphone (SIP)

Connect a SIP device — a physical desk phone, or a softphone app on a computer or mobile.

This suits teams with existing handsets, and anyone who wants a real phone on the desk rather than a browser tab.

Setting one up requires connecting the device to your LimeCall SIP credentials. The Devices page generates these and can show a QR code that provisions a softphone app directly, which avoids typing a long string of settings by hand.

{% hint style="warning" %}
SIP credentials let a device place calls billed to your account. Treat them like a password: do not share them, and regenerate them if a device is lost or a person leaves.
{% endhint %}

## Using more than one

You can have several devices. Calls can ring them together, so you answer wherever you are, or in order.

Ringing your browser and your mobile at once is a common and effective setup — you answer at your desk when you are there, and on your mobile when you are not.

## Personal availability

Whichever device you use, calls only reach you during your personal hours, set under **Settings → My hours**.

## Audio quality

If calls sound poor:

* Use a wired headset rather than laptop speakers, which cause echo.
* Prefer a wired network connection to wi-fi for browser calling.
* Close other applications using bandwidth — video calls and large uploads especially.
* For SIP handsets, confirm the device is on the same network you configured and not behind a restrictive firewall.

If quality is consistently poor in the browser but fine on a forwarded mobile, the problem is your local network rather than the platform.

## Testing

Make a test call to each device you have configured. Check it rings, that both sides can hear each other, and that the call appears under **Calls** afterwards.


# Inbox, Contacts & Leads

Where conversations, people and opportunities land, whichever product created them.

Every product feeds the same three places. A widget callback, an AI-answered call and an inbound text from the same person produce one contact, one conversation history and one lead — not three strangers.

## How they relate

**Contact** — the person. Their number, name, company and everything known about them.

**Conversation** — the thread. Every call and message with that contact, on one timeline, across every channel.

**Lead** — the opportunity. A status, a score, an owner, and what needs to happen next.

**Deal** — the money. Attached to a lead, with a value and a won/lost outcome.

One contact can have many conversations and, over time, several leads.

## In this section

* [Working a conversation](/inbox-and-leads/working-a-conversation) — the day-to-day of answering and closing
* [Contacts](/inbox-and-leads/contacts) — the people, and what LimeCall knows about them
* [Leads & scoring](/inbox-and-leads/leads-and-scoring) — triage and qualification
* [Deals & pipeline](/inbox-and-leads/deals-and-pipeline) — revenue tracking
* [Campaigns](/inbox-and-leads/campaigns) — outbound to many contacts at once


# Working a conversation

The day-to-day of handling what comes in.

Open **Inbox**.

A conversation groups everything with one contact — calls, texts, WhatsApp, email — on a single timeline.

## Filtering

The Inbox filters by channel, direction, who answered, assignment, campaign, and more.

Two views most teams live in:

* **Unassigned and open** — what nobody has picked up.
* **Assigned to me and open** — your own work.

Save the filters you use daily rather than rebuilding them each morning.

## Assignment

Assign a conversation to yourself or a colleague. **Assigned to** shows the current owner.

An unassigned conversation is nobody's job. Assign as you pick things up, so two people do not answer the same customer.

## Taking over from the AI

When the AI receptionist is handling a conversation, you can take it over at any time. The AI stops replying on that thread immediately.

Do this when the conversation is going wrong, when the customer is frustrated, or when it needs a decision only a person can make. Afterwards, fix the knowledge or scenario that caused it — see [Additional knowledge](/ai-receptionist/additional-knowledge).

## Context

Open the contact panel beside the conversation to see who you are talking to: previous interactions, company, location, line type, first and last seen.

If enrichment is on, this includes data looked up automatically. See [Contacts](/inbox-and-leads/contacts).

## Calls in the timeline

Calls appear alongside messages with their duration, outcome, recording and transcript, plus the AI's write-up if it handled the call.

Read the summary rather than playing the recording — it is faster, and the transcript is searchable when you need the exact words.

## Closing

Close a conversation when it is finished. **Close without a reason** is available, but recording a reason makes your reporting meaningful — you learn what people actually contact you about.

## Snoozing

Snooze a conversation to hide it until a chosen time — waiting on a customer, or a follow-up due next week. It reappears in your queue then, rather than sitting in your open list looking like work.

**Clear snooze** brings it back immediately.

## Starring

Star a conversation to flag it. Stars are per-conversation and visible to your team.

## Composing

The composer supports templates and signatures, set under **Settings → Inbox**, and can help polish a reply before you send it.

## Keeping it clean

An Inbox where everything is open and nothing is assigned stops being useful within a week. A workable rhythm:

1. Assign anything unassigned.
2. Answer or snooze everything assigned to you.
3. Close what is finished, with a reason.


# Contacts

The people who contact you, and what LimeCall knows about them.

Open **Contacts**.

A contact is a person. Every call, message and form submission attaches to one, so history follows the person rather than the channel.

## How contacts are created

Automatically, whenever someone new contacts you — a call to one of your numbers, an inbound message, or a widget submission. Matching is on phone number.

You can also add them manually, or import a list.

## What is stored

Name, phone, email, company, plus fields collected by your widget or assistant.

LimeCall also records behavioural detail: first seen, last seen, last call, which channels they use, and the campaign or source that brought them in.

## Enrichment

Optional lookups fill in what the caller did not tell you — name, company, line type, carrier, and rough location.

**Line type** is the most immediately useful. Knowing a number is a mobile, a landline or a VoIP number tells you whether texting will work and is a reasonable spam signal.

Enable providers under **Settings → Enrichment**. Enrichment is an add-on with its own costs — see [Usage & credits](/account/usage-and-credits).

{% hint style="info" %}
Enrichment is a lookup against third-party data, so it is neither complete nor always current. Treat it as a hint, not a fact — and check whether your privacy notice covers it.
{% endhint %}

## Caller memory

Enrichment and history are what let the AI receptionist recognise a returning caller. See [Caller memory](/ai-receptionist/caller-memory).

## Importing

Import contacts from CSV. Match your columns to LimeCall's fields during the import.

Before importing:

* **Normalise phone numbers** to international format where you can. It substantially improves matching.
* **Deduplicate** first — cleaning a list before import is far easier than merging afterwards.
* **Check your legal basis** for the data, particularly if you intend to message them.

## Duplicates

Contacts are matched on phone number, so the same person contacting from two different numbers creates two records. Merge them to keep one history.

## Blocking

Block a contact from their record. Blocked contacts do not reach your AI receptionist. See [Spam & blocking](/ai-receptionist/spam-and-blocking).

## Contacts and leads

A contact is a person; a lead is an opportunity. The same contact can generate several leads over time — someone who enquired last year and again this year is one contact with two leads.

See [Leads & scoring](/inbox-and-leads/leads-and-scoring).

## Syncing to your CRM

Where a CRM is connected, contacts sync to it. See [Integrations](/integrations).

## Deleting

You can delete a contact and its associated data. If you are subject to GDPR or similar, this is how you honour an erasure request — note it also removes the call history and recordings attached to that person.


# Leads & scoring

Triage what came in and decide what deserves your attention.

Open **Leads**.

A lead is an opportunity — someone who contacted you and might become a customer.

## How leads are created

Automatically from inbound activity: a widget callback, a call the AI qualified, an inbound message. You can also add one manually.

## What is on a lead

| Field                         | What it tells you                              |
| ----------------------------- | ---------------------------------------------- |
| **Lead score**                | The AI's grade against your criteria.          |
| **Qualification**             | The answers it established, and its reasoning. |
| **AI lead brief**             | A short written assessment.                    |
| **How they came in**          | Channel, campaign and source.                  |
| **Collected from the caller** | The fields your call types captured.           |
| **Activity**                  | Every interaction, on one timeline.            |
| **Assignment**                | Whose job this is.                             |

## Scoring

Scores come from the criteria you set under [Lead qualification](/ai-receptionist/lead-qualification).

Use the score to order your day, not to discard people. A low score means "do not drop everything for this"; it does not mean the person is worthless.

## Triage

A practical rhythm:

1. Sort by score, newest first.
2. Work the high scores immediately — speed of response matters more than almost anything else in converting an inbound lead.
3. Batch the middle.
4. Let the low ones wait, but do not let them rot.

## Assignment

Assign each lead an owner. An unassigned lead is nobody's job and will sit.

## Status

Move leads through their lifecycle as things happen. **Not qualified** is a legitimate and useful outcome — recording it honestly keeps your reporting real and stops you working the same dead lead twice.

## Filtering

Filter by score, status, channel, campaign, owner, country and more. Save the views you use.

Two worth keeping: unassigned leads, and high-score leads not yet contacted.

## Snoozing

Snooze a lead that is real but not now. It comes back when you asked rather than cluttering your queue.

## Spam

**Block it** on a lead blocks the contact. **Not spam** reverses a wrong call. Some leads are also flagged by IP — **IP blocked** and the visitor's IP location are shown where available.

## Creating a deal

When a lead is a real opportunity with a value, **Create deal**. See [Deals & pipeline](/inbox-and-leads/deals-and-pipeline).

## Notes and activity

Add notes as you work. Everything appears on the activity timeline with calls and messages, so the next person to pick it up has the full story.

## Tuning your scoring

After a few weeks, compare scores against what actually converted. If high scorers are not closing, your criteria describe the customer you want rather than the one you win. Adjust them.


# Deals & pipeline

Track the revenue attached to a lead.

A deal is the money attached to a lead: what it is worth, when you expect to close it, and whether you won.

## Creating a deal

From a lead, choose **Create deal**. Set:

* **Value** — what it is worth if you win.
* **Expected close** — when you think it lands.
* **Stage** — where it is in your process.

Not every lead needs a deal. Create one when there is a real opportunity with a number attached; leaving enquiries as leads keeps your pipeline honest.

## Stages

Deals move through stages reflecting your sales process. Keep the list short — five or six stages that mean something beats a dozen nobody applies consistently.

A stage should be defined by something observable. "Quote sent" is observable; "interested" is a feeling, and everything will pile up in it.

## Winning and losing

**Mark won** or **Mark lost** when it resolves.

Record losses honestly and with a reason. A pipeline where nothing is ever lost tells you nothing, and the loss reasons are usually more informative than the wins — they tell you about price, timing, and which competitor keeps beating you.

## Expected close dates

Keep them current. A pipeline full of dates that passed months ago cannot be forecast from, and quietly stops being used.

## The pipeline view

See deals grouped by stage with their total value, so you can tell whether the pipeline is healthy or whether everything is stuck in one place.

Signals worth watching: a stage holding far more than the others, deals that have not moved in weeks, and a close date cluster at the end of the month that never materialises.

## Deals and leads

The lead is the person and the enquiry; the deal is the commercial opportunity. One lead usually has one deal, but a returning customer can generate several over time.

Deal outcomes feed back into your reporting, which is what makes lead scoring meaningful — see [Conversions](/analytics/conversions).

## Syncing to your CRM

If you run a full CRM, connect it and let deals sync rather than maintaining two pipelines. LimeCall's pipeline is designed for teams whose selling happens on the phone; it is not a replacement for a large sales organisation's CRM.

See [HubSpot](/integrations/hubspot).

## What to measure

* Conversion rate from lead to deal.
* Conversion rate from deal to won.
* Average deal value by source.
* Time from first contact to close.

The first and third together tell you which channels are worth more of your money — see [Analytics & Reporting](/analytics).


# Campaigns

Send messages to many contacts at once.

Open **Campaigns**.

Campaigns send a message to a list of contacts, rather than one conversation at a time.

## Before you start

**Check you are allowed to message these people.** Consent requirements differ by market and are strictly enforced. A purchased list is almost never a lawful basis for messaging.

**Complete carrier registration for US recipients.** Unregistered bulk traffic is blocked. See [US carrier registration (10DLC)](/virtual-numbers/us-carrier-registration).

## Building a list

Select contacts by filter — by tag, source, campaign, status or any other field.

Build the list from the filter rather than a static export where you can, so it stays current.

## Writing the message

Three things every bulk message needs:

1. **Who you are.** A message from an unknown number with no sender name reads as a scam and gets reported.
2. **Why they are hearing from you.** Reference the thing that connects you.
3. **How to stop.** Opt-out instructions, always.

Keep it to one segment where possible. Messages are billed per segment, and emoji or other non-GSM characters cut the characters per segment substantially.

## Personalisation

Merge fields let you include the contact's name and other details. Check your data first — a message beginning "Hi ," because the name field is empty is worse than no personalisation.

## Sending

Review before sending. Check the recipient count, send a test to yourself, and read it on an actual phone — line breaks and links look different there.

{% hint style="warning" %}
A campaign cannot be recalled once sending starts. Check the recipient list, not just the message.
{% endhint %}

## Timing

Send during reasonable hours in the recipient's time zone. Many jurisdictions restrict when commercial messages may be sent, and a message at 3am generates complaints regardless of legality.

## Tracking

Each campaign reports what was sent, delivered, failed and replied to.

**Delivered is not the same as sent.** Carriers filter silently; a large gap between the two usually means a registration or content problem rather than bad numbers.

Replies land in your **Inbox** as ordinary conversations, so the team answers them normally — and your AI receptionist can answer them too, if the text channel is on.

## Opt-outs

STOP and similar replies suppress the contact automatically and permanently. Suppressed contacts are excluded from future campaigns without you doing anything.

Do not attempt to work around suppression. Beyond the legal exposure, complaints damage your numbers' reputation and hurt delivery of everything else you send.

## What works

* Small, well-targeted lists beat large, vague ones.
* A message referencing a real prior interaction gets answered; a generic blast does not.
* One clear action per message.
* Be ready to handle the replies — a campaign that generates responses nobody answers is worse than not sending it.


# Analytics & Reporting

Call volume, outcomes, transcripts and what is actually converting.

Open **Analytics**.

## What is measured

**Volume** — calls and messages, inbound and outbound, over time.

**Outcomes** — answered, missed, voicemail, transferred, and your own outcome names.

**Handling** — who answered, how long it took to pick up, how long the call ran.

**Source** — which campaign, channel or number produced the contact.

**AI performance** — what the assistant handled, what it escalated, and how much AI time it used.

## Reading it properly

A few habits that avoid the usual mistakes.

**Compare like periods.** Week against week, not this week against last month. Call volume is strongly weekly — a Tuesday and a Saturday are different businesses.

**Watch missed calls, not just total calls.** Growth in total calls is only good news if you are answering them.

**Segment by source before drawing conclusions.** An overall conversion rate is the average of channels that behave nothing like each other, and the average describes none of them.

**Give it enough data.** A 40% change on nine calls is noise.

## The numbers worth acting on

| Metric                | Why                                                                    |
| --------------------- | ---------------------------------------------------------------------- |
| Missed call rate      | Every missed call is a lead you already paid for.                      |
| Time to answer        | Correlates strongly with conversion on inbound.                        |
| Answer rate by source | Tells you which channels bring real people.                            |
| AI escalation rate    | Rising means the assistant is out of its depth — check your knowledge. |
| Conversion by source  | The only way to compare channels honestly.                             |

## Attribution

Calls are attributed to their source when one is known — the campaign, the tracking source on the number, or the page the widget was on.

Use a distinct number per campaign or channel when you want clean attribution. It is cruder than tracking parameters but it never breaks. See [Buy a number](/virtual-numbers/buy-a-number).

## Exporting

Export call records and lead data for analysis elsewhere, or pull them through the API. See [Developers](/developers).

## In this section

* [Call insights & transcripts](/analytics/call-insights-and-transcripts)
* [Conversions](/analytics/conversions)


# Call insights & transcripts

Recordings, transcripts, summaries and what to do with them.

Open **Calls**, then any call.

## What each call carries

**Recording** — the audio, if recording is enabled on that number.

**Transcript** — the words, speaker-separated and searchable.

**Summary** — the AI's write-up of what happened.

**Collected fields** — the structured data captured during the call.

**Qualification** — the score and reasoning, on AI-handled calls.

## Use the summary first

Read the summary. Open the transcript when you need exact wording. Play the recording only when tone matters — a complaint, a dispute, or coaching someone on the call.

Listening to recordings as a default is the slowest possible way to work through your calls.

## Searching transcripts

Transcripts are searchable, which is where a lot of the value sits. You can find every call where a competitor was mentioned, where a specific product came up, or where someone asked for something you do not offer.

That last search is the most useful thing on this page. A pattern of callers asking for something you do not sell is direct evidence of demand, and it never shows up in a dashboard of call counts.

## What to do with what you find

**Questions the assistant could not answer** → add them to [Additional knowledge](/ai-receptionist/additional-knowledge).

**Terms it mishears** → add them under **Specialized terms** in [Scenarios & call types](/ai-receptionist/scenarios-and-call-types).

**Objections that keep coming up** → answer them on your website, before the call.

**Calls escalating that should not** → the assistant is missing knowledge, not judgement.

## Call outcomes

Record what a call led to. You can write outcomes back through the API, including the money the call produced — see [Webhook events](/developers/webhook-events) and [Conversions](/analytics/conversions).

This is what turns a call log into a report about revenue rather than activity.

## Accuracy

Transcription is good but not perfect. Accents, crosstalk, background noise and poor line quality all degrade it. Treat a transcript as a reliable guide and the recording as the record of what was actually said.

## Retention and access

Recordings and transcripts are personal data. Access follows your team's roles — see [Team & roles](/account/team-and-roles) — and your obligations on consent and deletion are covered in [Recording, consent & AI disclosure](/ai-receptionist/recording-consent-and-disclosure).


# Conversions

Define what counts as a win so the numbers mean something.

Open **Settings → Conversions**.

## Why this matters

Without a definition of success, your analytics can only report activity — how many calls, how long they were. That tells you how busy you were, not whether it worked.

Defining a conversion lets everything else be measured against it: which channel, which campaign, which number and which time of day actually produce business.

## Defining a conversion

Decide what counts as a won lead for your business. Reasonable definitions:

* An appointment booked.
* A deal marked won.
* A call lasting beyond a threshold that indicates a real conversation.
* A custom outcome you write back from your own system.

Pick something that genuinely correlates with revenue. A conversion defined too loosely — "any answered call" — makes every channel look equally good and gives you nothing to act on.

## Writing outcomes back

The most accurate approach is to tell LimeCall what actually happened, from whatever system holds the truth.

```bash
curl -X PATCH https://app.limecall.com/api/v1/calls/{callId} \
  -H "Authorization: Bearer sk_live_..." \
  -H "Content-Type: application/json" \
  -d '{"outcome":"appointment_booked","value":250,"currency":"USD"}'
```

The outcome name is yours. Use the same name consistently and calls group by it in the call log and in reporting.

Sending `value` is what lets LimeCall report revenue per channel rather than call counts per channel — the difference between "Google Ads produced 40 calls" and "Google Ads produced £9,400".

## Sending conversions to ad platforms

Where connected, conversions can be forwarded to advertising platforms so their optimisation learns from real outcomes rather than from clicks.

This is the highest-leverage integration available to anyone spending on ads. An ad platform optimising toward form fills will happily buy you cheap, worthless leads; one optimising toward closed revenue buys you customers.

## Attribution windows

A call today may close in three weeks. Set an attribution window long enough to capture your real sales cycle, or your best channels will look like your worst because their revenue lands outside the window.

## Reviewing

Check conversion by source monthly. Look for:

* channels with high volume and low conversion — cut or fix,
* channels with low volume and high conversion — buy more,
* changes after a campaign or website change.

## Related

* [Deals & pipeline](/inbox-and-leads/deals-and-pipeline)
* [Call insights & transcripts](/analytics/call-insights-and-transcripts)


# Integrations

Connect LimeCall to your CRM, calendar, chat and automation tools.

Open **Settings → Integrations**.

## What is available

| Integration         | What it does                                     |
| ------------------- | ------------------------------------------------ |
| **HubSpot**         | Two-way sync of contacts, calls and deals.       |
| **Slack**           | Notifications into a channel.                    |
| **Google Calendar** | Availability and booking for your assistant.     |
| **Zapier**          | Connect to thousands of apps without code.       |
| **Make**            | Visual automation with more control than Zapier. |
| **n8n**             | Self-hosted automation.                          |
| **Google Sheets**   | Push rows for reporting.                         |
| **Webhooks**        | Send events to your own systems.                 |

## Choosing an approach

**Use a native integration** where one exists. HubSpot, Slack and Google Calendar are purpose-built and handle the details correctly.

**Use Zapier or Make** when you need to connect something without a native integration and do not want to write code.

**Use webhooks** when you have developers and want full control. See [Webhooks](/integrations/webhooks).

## Before connecting anything

Decide what should be the source of truth for each kind of data. Two systems both authoritative on contacts produces conflicts that are tedious to unpick later.

Usually: your CRM owns the customer record, LimeCall owns the conversation record.

## Connecting

Most integrations connect with OAuth — you authorise LimeCall from the other tool's own login screen. You will be asked to grant specific permissions; read them.

{% hint style="warning" %}
Connect using an account that will still exist in a year. Integrations authorised under a departing employee's login stop working the day their account is deactivated, usually silently.
{% endhint %}

## Disconnecting

Disconnecting revokes the credentials. Any automation depending on that connection stops. Check what you have built before disconnecting anything.

## In this section

* [HubSpot](/integrations/hubspot)
* [Slack](/integrations/slack)
* [Google Calendar](/integrations/google-calendar)
* [Zapier, Make & n8n](/integrations/zapier-and-make)
* [Webhooks](/integrations/webhooks)


# HubSpot

Sync contacts, calls and deals with HubSpot.

## Connect

1. Open **Settings → Integrations**.
2. Choose **HubSpot** and **Connect**.
3. Sign in to HubSpot and select the account (portal) to connect.
4. Review and grant the requested permissions.

Connect using an account that will persist. An integration authorised under someone who leaves stops working when their HubSpot seat is removed.

## What syncs

**Contacts.** People who contact you are created or matched in HubSpot. Matching is on phone number and email.

**Calls.** Logged as activities on the contact timeline, with duration, direction, outcome and the AI summary where there is one.

**Deals.** Deals created in LimeCall can be created in HubSpot, and stage changes kept in step.

## Which direction

Decide what owns what before enabling two-way sync.

The usual arrangement: HubSpot owns the customer record — name, company, lifecycle stage — and LimeCall owns the conversation record — calls, recordings, transcripts.

Two-way sync on the same fields produces conflicts, and the resolution rules are never what someone expects six months later.

## Field mapping

Map LimeCall fields to HubSpot properties. Fields captured by your widget or AI assistant can populate custom HubSpot properties.

Create the custom properties in HubSpot first, then map to them. Mapping to a property that does not exist fails silently.

## Duplicates

HubSpot matches on email primarily; LimeCall matches on phone number. A caller whose number you have but whose email you do not can create a second HubSpot contact.

Reduce this by capturing email where you reasonably can — see [Lead capture](/callback/lead-capture) — and by running HubSpot's own duplicate management periodically.

## Owners

Where team members exist in both systems, map them so calls are logged against the right HubSpot owner. Otherwise everything is attributed to the connecting user, and your HubSpot reporting by rep becomes meaningless.

## Workflows

Once calls are in HubSpot, its workflows can act on them — notify an owner about a high-score lead, move a lifecycle stage after a qualified call, enrol someone in a sequence after a missed one.

This is where most of the value is. The sync is only plumbing; the workflow is what does the work.

## Verifying

After connecting, make a test call and confirm within a few minutes that the contact exists in HubSpot, the call is on the timeline with its summary, and any mapped custom fields are populated.

## Troubleshooting

**Nothing syncing** — check the connection is still authorised; OAuth tokens are revoked when the authorising user loses access.

**Some records missing** — usually a required property missing in HubSpot, or a field-mapping mismatch.

**Duplicates** — see above.


# Slack

Get LimeCall notifications in a Slack channel.

## Connect

1. Open **Settings → Integrations**.
2. Choose **Slack** and **Connect**.
3. Authorise LimeCall in your Slack workspace.
4. Choose the channel notifications should post to.

## What you can be notified about

* A missed call.
* A new callback request.
* A high-scoring lead.
* A new inbound message.
* A voicemail left.
* AI usage approaching its limit.

## Choose a channel deliberately

Post to a channel the right people actually read. A dedicated channel like `#limecall-leads` works better than a busy general channel where notifications scroll away in minutes.

If your team is large, separate channels by purpose — missed calls to the team who can call back, usage alerts to whoever owns billing.

## Do not notify on everything

This is the most common mistake. A channel that fires on every inbound call becomes noise within a day, and then gets muted — at which point the alerts you actually needed are also unread.

Notify on the things requiring a human decision:

* missed calls, because someone should call back,
* high-scoring leads, because speed matters,
* usage alerts, because running out is expensive.

Ordinary answered calls do not need a Slack message. They are in the dashboard.

## Acting from Slack

Notifications link back to the conversation or lead in LimeCall, so someone can pick it up in one click.

## Missed calls are the highest-value alert

If you configure only one thing here, make it missed calls.

A missed call is a person who wanted to speak to you and could not. Getting it in front of a human within minutes — while they are still thinking about the problem — converts dramatically better than a callback the next morning.

## Usage alerts

Route AI minute and credit alerts to Slack as well as email. Running out of AI minutes silently stops your receptionist answering — see [AI minutes & usage](/ai-receptionist/ai-minutes-and-usage).

## Disconnecting

Disconnecting stops all notifications to the workspace. If alerts stop unexpectedly, check whether the authorising user has left or the app was removed from the workspace.


# Google Calendar

Let your assistant book real appointments into your calendar.

## Connect

1. Open **Settings → Scheduling**, or **Settings → Integrations**.
2. Choose **Google Calendar** and **Connect**.
3. Sign in and grant calendar access.
4. Choose which calendar to use.

## What it enables

**Real availability.** The AI receptionist and the widget's scheduling option read your free/busy, so offered times are times you are actually free.

**Booking during the call.** The assistant books the appointment while the caller is on the phone, instead of promising someone will ring back to arrange it.

**Two-way awareness.** An event added directly in Google Calendar blocks that time in LimeCall immediately, so you cannot be double-booked by something you put in yourself.

## Which calendar

If you keep separate work and personal calendars, connect the one holding your actual commitments.

Connecting only a work calendar means a personal appointment in another calendar is invisible, and the assistant will book over it.

You can connect a calendar for availability while creating bookings in a different one — useful where a shared team calendar holds the bookings but each person's own calendar determines when they are free.

## Booking rules

Set duration, buffers, notice period and how far ahead people can book under [Calendar & booking](/ai-receptionist/calendar-and-booking).

## Event details

Set what appears on the event — the caller's name and number, what they are booking, and the fields collected during the call. Putting the phone number in the title is a small thing that saves opening the event when you need to ring ahead.

## Time zones

Check your calendar's time zone matches your LimeCall account's.

A mismatch produces bookings at the right clock time in the wrong zone, which is not obvious until a customer arrives an hour early. This is the most common problem with calendar integrations.

## Multiple team members

Where bookings go to individuals, each person connects their own calendar. Availability is then per-person, and the assistant can offer whoever is free.

## Cancellations and changes

Bookings cancelled or moved in LimeCall update the calendar event, and the assistant can reschedule on request. Changes made directly in Google Calendar update availability but do not notify the customer — if you move an appointment yourself, tell them.

## Verifying

Book a test appointment through your assistant. Check it appears in the right calendar, at the right time in the right zone, with the details you configured. Then cancel it and confirm the slot frees up.


# Zapier, Make & n8n

Connect LimeCall to thousands of apps without writing code.

Automation platforms let you connect LimeCall to tools without a native integration.

## Which to use

**Zapier** — the largest app catalogue and the simplest to learn. Best for straightforward "when this, do that" automation.

**Make** — a visual builder with better handling of branching, loops and error handling. Better value at volume, steeper learning curve.

**n8n** — self-hosted, so your data stays on your infrastructure. Best where you have technical people and data residency requirements.

All three connect the same way and can act on the same events.

## Connecting

1. Open **Settings → Integrations**.
2. Choose your platform and **Connect**.
3. Copy the connection details into the platform.

Each connection issues credentials specific to it. Disconnecting revokes them and stops anything built on them.

## What can trigger an automation

* A call completes.
* A call is missed.
* A lead is created.
* A lead reaches a score threshold.
* A message is received.
* A deal is marked won or lost.
* A booking is made.

## What LimeCall can do as an action

* Send an SMS.
* Create or update a contact.
* Create a lead.
* Update a call's outcome and value.

## Useful automations

**Missed call to a task.** A missed call creates a task in your project tool, assigned to whoever is on duty. Nothing gets forgotten because someone did not check the dashboard.

**Qualified lead to the team.** A lead above your score threshold posts to a channel and creates a CRM record immediately, rather than waiting for a nightly sync.

**Booking to confirmation.** A booking triggers a confirmation email from your own system, with your branding and whatever attachments you send.

**Won deal to revenue.** A deal marked won in your finance system writes the value back to LimeCall, so channel reporting shows actual revenue. See [Conversions](/analytics/conversions).

**Out-of-hours escalation.** A high-priority call outside business hours sends an SMS to whoever is on call.

## Building reliably

**Test with real data** before enabling. Automations that work on a hand-made sample often fail on the messy real thing — missing fields, unexpected characters, empty names.

**Handle failures.** Set up error notifications. A silently failing automation is worse than no automation, because you stop checking the thing it replaced.

**Filter early.** Put conditions at the start of the flow. Running every call through a five-step scenario to discard most of them wastes your task quota.

**Watch your quota.** Zapier and Make bill by task. A trigger on every call on a busy account consumes a plan faster than expected.

## Rate limits

Automation platforms can generate bursts of API calls. If you hit rate limits, batch where you can and add delays between steps. See [Errors, pagination & rate limits](/developers/errors-and-rate-limits).


# Webhooks

Send LimeCall events to your own systems.

A webhook posts JSON to a URL you control whenever something happens in LimeCall.

Use webhooks when you have developers and want full control. For no-code, use [Zapier, Make & n8n](/integrations/zapier-and-make).

## Setting one up

1. Open **Settings → Integrations** for account-wide events, or **AI Receptionist → Actions & Webhooks** for assistant events.
2. Enter your endpoint URL. It must be HTTPS.
3. Set a shared secret so you can verify requests.
4. Choose the events to receive.

## What arrives

A POST with a JSON body describing the event, including call metadata, the contact, collected fields, and — for AI-handled calls — the summary, transcript and qualification result.

See [Webhook events](/developers/webhook-events) for the event list.

## Verify every request

Your endpoint is a public URL. Anyone who discovers it can post to it.

Check the shared secret on every request and reject anything that does not match. An unauthenticated webhook endpoint that creates records is a way for a stranger to create records in your systems.

{% hint style="warning" %}
Never act on a webhook payload without verifying it first, and never trust a URL or instruction contained inside a payload.
{% endhint %}

## Respond quickly

Return a 2xx as soon as you have accepted the payload. Do the actual work asynchronously — queue it and return.

Endpoints that hold the connection open while they process are the usual cause of webhook timeouts and the retry storms that follow.

## Handle duplicates

Delivery is retried on failure, so the same event can arrive more than once. This is normal for any webhook system.

Key on the event or call ID and ignore anything you have already processed. Without this, a retry creates a second record.

## Handle out-of-order delivery

Events are not guaranteed to arrive in the order they happened. If order matters, use the timestamps in the payload rather than arrival order.

## Retries

Failed deliveries are retried with backoff. Persistent failures may result in the webhook being disabled — so monitor your endpoint rather than assuming silence means success.

## Testing

Use **Send test** to fire a sample payload before relying on it.

For local development, use a tunnelling tool to expose your machine, or a request-inspection service to see exactly what arrives.

## Debugging

**Nothing arriving** — check the URL is publicly reachable over HTTPS, and that your firewall is not blocking it.

**Arriving but failing** — log the raw body before parsing. The usual causes are an unexpected field type or a missing optional field.

**Duplicates** — implement idempotency as above.

## Related

* [Actions & webhooks](/ai-receptionist/actions-and-webhooks)
* [Developers](/developers)


# Account & Billing

Plans, credits, invoices, your team and security.

## What is in this section

* [Plans & billing](/account/plans) — what each plan includes, and changing plan
* [Usage & credits](/account/usage-and-credits) — what you have used and topping up
* [Team & roles](/account/team-and-roles) — inviting people and what they can do
* [Security](/account/security) — passwords, sessions and closing your account

## The quick answers

**Where is my invoice?** **Settings → Plan & billing**.

**How do I change my card?** **Settings → Plan & billing**.

**Why did my AI stop answering?** Probably out of AI minutes with no credit balance. See [Usage & credits](/account/usage-and-credits).

**Can I get a number on the trial?** No — numbers require a paid plan.

**How do I add a colleague?** **Settings → Team**. See [Team & roles](/account/team-and-roles).


# Plans & billing

What plans include, how to change, and where invoices live.

Open **Settings → Plan & billing**, or **Plan**.

## What a plan governs

Your plan sets the allowances included each billing period and which capabilities are available:

* included call minutes,
* included AI minutes,
* included messages,
* how many phone numbers you can hold,
* how many team members,
* which integrations and features are available.

Current plans and prices are shown on your **Plan** page. That page is authoritative — it reflects your account, including anything negotiated.

## Trial

The trial gives a working account with limited allowances so you can test everything end to end.

You can install and publish the widget, build and test an AI receptionist, make and receive test calls, and connect integrations.

You cannot buy or port a phone number on a trial. That requires a paid plan.

## Upgrading

Upgrade from the **Plan** page. Changes take effect immediately — you get the new allowances at once, with the cost prorated for the remainder of your period.

## Downgrading

Downgrades generally take effect at the end of the current period, so you keep what you paid for.

Before downgrading, check you are within the lower plan's limits. If you hold more numbers or seats than the new plan allows, resolve that first rather than discovering it at renewal.

## Payment method

Add or change your card under **Settings → Plan & billing**.

Keep a valid card on file. A failed payment eventually suspends the account, which stops calls being answered — an expensive way to discover an expired card.

## Invoices

Invoices are listed under **Settings → Plan & billing**, with downloadable copies.

To have them emailed to accounts rather than to you, set a billing contact there.

## What is billed separately

Your plan covers included allowances. These are charged on top:

* phone number rental, monthly per number,
* usage beyond included allowances,
* calls and messages to destinations outside your plan's coverage,
* enrichment lookups, where enabled.

See [Usage & credits](/account/usage-and-credits).

## Cancelling

Cancel from **Settings → Plan & billing**. You keep access until the end of the period you have paid for.

{% hint style="warning" %}
Cancelling releases your phone numbers. Once released they return to the carrier's pool and are extremely unlikely to be recoverable. If you may return, or the number is printed anywhere, port it out before cancelling rather than after.
{% endhint %}

## Closing the account

Closing is separate from cancelling and deletes your data. See [Security](/account/security).


# Usage & credits

What you have used, what it costs, and how to avoid running out.

Open **Settings → Usage & credits**.

## What is metered

| Meter             | What it counts                             |
| ----------------- | ------------------------------------------ |
| **Call minutes**  | Time on calls handled by people.           |
| **AI minutes**    | Time your AI receptionist spends on calls. |
| **Messages**      | SMS and MMS, per segment.                  |
| **Number rental** | Monthly, per number held.                  |
| **Enrichment**    | Per lookup, where enabled.                 |

AI minutes are metered separately from call minutes. A call the AI answers and transfers uses both.

## Allowances and credits

Your plan includes an allowance per billing period. It resets each period and does not roll over.

Usage beyond the allowance draws on **credits** — a prepaid balance. With credits, service continues and draws down. Without them, service stops.

## What stops when you run out

**AI minutes exhausted** — the assistant stops answering. Calls fall through to whatever else the number is configured to do, or nowhere if nothing is set.

**Call minutes exhausted** — outbound calling is restricted.

**Messages exhausted** — sending stops.

{% hint style="warning" %}
Nothing announces this to your callers. A number whose AI has run out and which has no fallback simply fails to help anyone who rings it. Set a fallback destination on every number.
{% endhint %}

## Set an alert

Under **Settings → Notifications**, set a usage alert at around 80% of your allowance.

Send it to email and to Slack. Finding out from a customer that your phone has not been answered since Friday is avoidable for the cost of one checkbox.

## Auto-recharge

Where available, auto-recharge tops credits up automatically when the balance falls below a threshold. This is the most reliable way to avoid interruption.

Set a sensible cap so an unexpected spike — a spam wave, a runaway automation — cannot run up a large bill.

## What costs more than expected

**Spam calls.** Every robocall your AI answers is metered. Enable screening — see [Spam & blocking](/ai-receptionist/spam-and-blocking).

**Long message content.** Messages bill per segment. Emoji and other non-GSM characters sharply reduce characters per segment.

**International destinations.** Rates vary considerably by country.

**Held calls.** A caller who sets the phone down without hanging up keeps the call open. Set a maximum call length.

**Testing.** Test calls are metered like real ones.

## Reducing usage

* Screen spam aggressively.
* Shorten the AI's greeting — seconds saved on every call add up.
* Ask only for fields you will act on.
* Transfer early on calls the AI cannot resolve.
* Release numbers you are not using.

## Reviewing

Check usage against results monthly under **Analytics**. Usage rising alongside conversions is a business growing; usage rising alone is something to investigate.


# Team & roles

Invite colleagues, set what they can do, and decide how calls are shared.

Open **Settings → Team**.

## Inviting someone

1. Open **Settings → Team**.
2. Choose to invite a member.
3. Enter their email and set their role.
4. They receive an invitation to set a password and sign in.

Invite people with their work email. Personal addresses make offboarding harder and muddle your audit trail.

## Roles

Roles decide what someone can see and change. Broadly:

**Owner** — full access, including billing and closing the account.

**Admin** — full operational access, usually including team management.

**Member** — handles calls, messages and leads. Cannot change account-wide settings.

**Viewer** — read-only. Can see conversations and reports but cannot change anything or take calls.

Give people the least access that lets them do their job. In particular, keep billing access to the people who should see invoices, and keep recording access considered — call recordings are personal data and not everyone needs them.

## Teams

Group members into teams, and route numbers to a team rather than a person. That way a departure or a holiday does not require rewiring your routing.

Set how a team rings — everyone at once, in a fixed order, or evenly distributed:

* **All at once** connects fastest.
* **Fixed order** suits seniority or specialism.
* **Even distribution** shares the load.

## Personal settings

Each member controls their own:

* **Settings → My calls** — how calls reach them.
* **Settings → My hours** — when they are available.
* **Settings → Devices** — browser, desk phone or softphone. See [Devices](/virtual-numbers/devices).

A member outside their own hours is not rung, even during business hours. When calls are not reaching someone, check this before anything else.

## Assignment

Conversations and leads are assigned to owners. Unassigned work is nobody's job — see [Working a conversation](/inbox-and-leads/working-a-conversation).

## When someone leaves

Do all of these:

1. **Reassign their open conversations and leads** before removing them, or that work disappears from everyone's queue.
2. **Check integrations they authorised.** OAuth connections — HubSpot, Slack, Google Calendar — authorised under their account stop working when it is deactivated. Reconnect under someone else's first.
3. **Revoke their devices and SIP credentials**, which otherwise keep working. See [Devices](/virtual-numbers/devices).
4. **Check API keys they created**, under **Settings → API keys**.
5. **Remove them** from the team.

{% hint style="warning" %}
Step 2 is the one most often missed. An integration silently stops syncing weeks later and nobody connects it to the departure.
{% endhint %}

## Seats and billing

Your plan includes a number of team members. Adding beyond that may change your bill — see [Plans & billing](/account/plans).


# Security

Passwords, two-step sign-in, sessions and closing your account.

Open **Settings → Security**.

## Password

Change your password here. Use a long, unique one from a password manager rather than something memorable — LimeCall holds your call recordings, customer data and the ability to spend money on calls.

## Two-step sign-in

Enable a second sign-in step if it is available on your account. It is the single most effective protection against a stolen password, and takes a minute to set up.

Store your recovery codes somewhere you can reach without being signed in.

## Sessions

See where your account is signed in, and sign out of sessions you do not recognise.

Sign out everywhere after:

* changing your password,
* losing a device,
* someone leaving with shared access.

Signing out everywhere invalidates existing sessions, so anyone holding one must sign in again.

## API keys

Keys are managed under **Settings → API keys**. Two scopes are available:

* **Read** — list calls, leads and analytics.
* **Write** — place calls, send messages and update records.

Grant read-only unless the integration genuinely needs to write. See [API keys](/developers/api-keys).

Revoke keys you no longer use, and any key created by someone who has left.

## Device and SIP credentials

SIP credentials let a device place calls billed to your account. Treat them as passwords: never share them, and regenerate them if a device is lost or a person leaves. See [Devices](/virtual-numbers/devices).

## Who can see what

Access to recordings, transcripts and customer data follows roles. Review them periodically — access granted for a one-off task tends to stay. See [Team & roles](/account/team-and-roles).

## Personal data

LimeCall holds personal data about your customers: numbers, recordings, transcripts and enrichment results.

If you are subject to GDPR or similar rules:

* have a lawful basis for recording, and disclose it — see [Recording, consent & AI disclosure](/ai-receptionist/recording-consent-and-disclosure),
* be able to honour access and erasure requests — deleting a contact removes its associated history,
* cover enrichment in your privacy notice, since it obtains data from third parties,
* contact support for a data processing agreement or sub-processor details.

## Closing your account

Closing is different from cancelling a plan. Cancelling stops billing; closing deletes your data.

Before closing:

* **Port out any numbers you want to keep.** Closing releases them permanently.
* **Export anything you need** — call records, transcripts, contacts.
* **Disconnect integrations** so they do not fail noisily elsewhere.

{% hint style="warning" %}
Closing is irreversible. Recordings, transcripts, contacts and call history are deleted and cannot be recovered.
{% endhint %}


# Developers

The LimeCall REST API, authentication, webhooks and limits.

LimeCall has two separate surfaces with two separate kinds of key. Mixing them up is the single most common integration mistake, so start here:

```mermaid
flowchart LR
    subgraph B["Browser — your website"]
      W["Widget<br/>window.LimeCall"]
    end
    subgraph S["Your server"]
      A["Your backend"]
    end
    W -- "X-Widget-Key<br/>publishable" --> P["/api/public/callback<br/>Request a call"]
    A -- "Authorization: Bearer<br/>sk_live_ — SECRET" --> R["/api/v1<br/>Calls, contacts, numbers"]
```

The **widget key** is already in your page source and is meant to be public. The **secret key** must never reach a browser. They are not interchangeable, and neither surface accepts the other's key.

## Base URL

```
https://app.limecall.com/api/v1
```

## Authentication

Every request carries a bearer token:

```
Authorization: Bearer sk_live_...
```

Create tokens under **Settings → API keys**, or on the **Developers** page in the dashboard. See [API keys](/developers/api-keys).

## A first request

```bash
curl https://app.limecall.com/api/v1/calls \
  -H "Authorization: Bearer sk_live_..."
```

## Writing an outcome back

The most valuable single call in the API. When a call turns into a booking or a sale, write that back and it appears on the call and in your totals:

```bash
curl -X PATCH https://app.limecall.com/api/v1/calls/{callId} \
  -H "Authorization: Bearer sk_live_..." \
  -H "Content-Type: application/json" \
  -d '{"outcome":"appointment_booked","value":250,"currency":"USD"}'
```

The outcome name is yours — use the same one consistently and calls group by it. Sending `value` is what lets LimeCall report revenue by channel rather than call counts by channel. See [Conversions](/analytics/conversions).

Requires a token with write access.

## Content type

Send `Content-Type: application/json` on requests with a body. Responses are JSON.

## This API is not the dashboard's API

The `/api/v1` surface is the customer-facing API, authenticated with `sk_live_` tokens. The dashboard itself uses a separate internal API with session authentication.

Only `/api/v1` is supported for integration. Anything you find by watching the dashboard's network traffic is internal, undocumented and will change without notice.

## Endpoint reference

| Resource                                   | Endpoints | Covers                                                               |
| ------------------------------------------ | --------- | -------------------------------------------------------------------- |
| [Calls](/developers/calls)                 | 7         | List, inspect, recordings, transcripts, summaries, outcome writeback |
| [Messages](/developers/messages)           | 3         | Send SMS/MMS, list history                                           |
| [Contacts](/developers/contacts)           | 5         | Full CRUD                                                            |
| [Phone numbers](/developers/phone-numbers) | 3         | List and reconfigure your lines                                      |
| [Voicemails](/developers/voicemails)       | 2         | List and mark handled                                                |
| [Users](/developers/users)                 | 5         | Your team, and verified caller-ID numbers                            |
| [Webhooks](/developers/webhooks)           | 5         | Manage subscriptions                                                 |
| [Analytics](/developers/analytics)         | 3         | Usage and breakdowns                                                 |
| [Devices](/developers/devices)             | 2         | Push tokens, for your own client                                     |

## Also in this section

* [API keys](/developers/api-keys) — creating and scoping tokens
* [Webhook events](/developers/webhook-events) — the events and how to handle them
* [Errors, pagination & rate limits](/developers/errors-and-rate-limits) — status codes, paging and limits

## Working in the browser instead

The REST API is for your server. To drive the callback widget from your own page — open it on a button, fire it from a form you already have, listen for events — use the browser API, which needs no secret key:

* [JavaScript API](/callback/javascript-api)
* [Connect your own form](/callback/connect-your-own-form)

## No-code alternatives

If you do not want to write code, Zapier, Make and n8n cover most integration needs. See [Zapier, Make & n8n](/integrations/zapier-and-make).


# API keys

Create, scope and revoke API tokens — and the 14 scopes the API actually enforces.

Open **Settings → API keys**, or the **Developers** page.

## Creating a key

1. Open **Settings → API keys**.
2. Create a key and give it a name.
3. Choose its scopes.
4. Copy the token.

{% hint style="warning" %}
The token is shown once, at creation. It cannot be retrieved afterwards. Store it in your secret manager immediately — if you lose it, revoke it and create another.
{% endhint %}

## Naming

Name keys for where they are used: `zapier-production`, `billing-sync`, `marketing-site`.

A list of keys called "API key 1" through "API key 6" cannot be audited, and nobody will dare revoke any of them.

## Scopes

The dashboard offers two broad choices when you create a key — **Read** and **Write**. The API itself enforces finer-grained scopes, one pair per resource:

| Resource      | Read                 | Write                 |
| ------------- | -------------------- | --------------------- |
| Calls         | `calls:read`         | `calls:write`         |
| Messages      | `messages:read`      | `messages:write`      |
| Contacts      | `contacts:read`      | `contacts:write`      |
| Phone numbers | `phone-numbers:read` | `phone-numbers:write` |
| Users         | `users:read`         | `users:write`         |
| Webhooks      | `webhooks:read`      | `webhooks:write`      |
| Analytics     | `analytics:read`     | —                     |
| Devices       | —                    | `devices:write`       |

Wildcards work: `calls:*` satisfies both `calls:read` and `calls:write`.

Grant the narrowest set that does the job. A reporting dashboard needs `calls:read` and `analytics:read` — not permission to send messages or delete contacts.

A request whose key lacks the required scope returns `403` with the scope it wanted:

```json
{ "error": "Forbidden", "message": "Insufficient permissions. Required scope: calls:write" }
```

That message names exactly what to add, which makes a `403` quick to fix.

## Using a key

```bash
curl https://app.limecall.com/api/v1/calls \
  -H "Authorization: Bearer sk_live_..."
```

The prefix matters. `sk_live_` is the secret API key. A `pk_live_` or `lk_live_` value is the **widget publishable key** — a different credential entirely, and it is rejected at format check before any lookup.

## Keeping keys safe

**Never commit a key to a repository.** Use environment variables or a secret manager. Keys committed to public repositories are found by automated scanners within minutes.

**Never put a key in front-end code.** Anything in a browser is visible to anyone who opens developer tools. If a browser needs data, proxy through your own backend.

**Use separate keys per integration.** Then revoking one does not break the others, and you can tell what a leak touched.

**Rotate periodically.** Create the new key, deploy it, confirm it works, then revoke the old one — in that order, so there is no gap.

{% hint style="warning" %}
A key is organization-wide and carries no IP restriction. Anywhere it leaks, it works. That is the whole reason to scope keys narrowly and rotate them.
{% endhint %}

## Revoking

Revoke a key from the same page. It stops working immediately and anything using it fails.

Revoke at once if a key may have been exposed — committed, pasted into a ticket, or held by someone who has left.

## When someone leaves

Check for keys they created. Keys are not tied to a person's session and keep working after their account is deactivated. See [Team & roles](/account/team-and-roles).

## Live keys only

`sk_live_` keys act on your real account — real calls, real messages, real charges. There is no sandbox that makes a mistake free, so test destructive operations against data you do not mind changing.


# Webhook events

The events LimeCall sends, and how to handle them.

Create and manage subscriptions with the [Webhooks API](/developers/webhooks), or in **Settings → Integrations**.

## The events

| Event                       | Fires when                                                                                      |
| --------------------------- | ----------------------------------------------------------------------------------------------- |
| `call.created`              | A call starts.                                                                                  |
| `call.completed`            | A call ends. Carries duration, outcome and — for AI-handled calls — the summary and transcript. |
| `call.failed`               | A call could not be connected.                                                                  |
| `message.received`          | An inbound SMS or MMS arrives.                                                                  |
| `message.sent`              | An outbound message is accepted by the carrier.                                                 |
| `message.failed`            | An outbound message could not be sent.                                                          |
| `contact.created`           | A new contact is created, including automatically from an inbound call.                         |
| `contact.updated`           | A contact's details change.                                                                     |
| `contact.deleted`           | A contact is removed.                                                                           |
| `number.flagged`            | One of your numbers is flagged — spam labelling or a carrier issue.                             |
| `invoice.payment_succeeded` | A payment goes through.                                                                         |
| `invoice.payment_failed`    | A payment fails.                                                                                |
| `charge.refunded`           | A charge is refunded.                                                                           |

Subscribe to at least one event — a subscription with an empty `events` array is rejected.

## Two worth wiring first

**`call.completed`** is the one most integrations are built on. It is where the summary, the transcript, the collected fields and the qualification result arrive.

**`number.flagged`** and **`invoice.payment_failed`** are the two nobody subscribes to and everybody wishes they had. A spam-labelled number quietly stops being answered; a failed payment eventually suspends the account and stops calls being answered at all. Both are cheap to alert on and expensive to discover late.

## Verify every delivery

Your endpoint is a public URL. Check the secret issued when you created the subscription, on every request, and reject anything that does not match.

{% hint style="warning" %}
Treat payload contents as untrusted data. A transcript contains whatever a caller said, so never execute an instruction or follow a URL found inside a payload.
{% endhint %}

## Respond fast

Return `2xx` as soon as you have accepted the payload, then process asynchronously. Slow endpoints cause timeouts, timeouts cause retries, and retries cause duplicates.

## Be idempotent

The same event can arrive more than once. Key on the event or call id and ignore what you have already processed. Without this, a retry creates a second record.

## Do not assume ordering

Events are not guaranteed to arrive in the order they happened. Where sequence matters, use the timestamps in the payload rather than arrival order.

## Retries

Failed deliveries are retried with backoff, up to the `maxRetries` set on the subscription (`0`–`10`, default `3`). Once exhausted, the delivery is dropped — so monitor your endpoint rather than treating silence as success.

Pause a subscription with `isActive: false` during a deploy instead of letting deliveries fail against a restarting service.

## Testing

For local development, use a tunnelling tool to expose your machine, or a request-inspection service to see exactly what arrives.

## Live lookups are the other direction

Separately, the AI receptionist can call *your* API during a call and speak the answer. Respond in under a second and fail gracefully. See [Actions & webhooks](/ai-receptionist/actions-and-webhooks).


# Errors, pagination & rate limits

Status codes, paging through results, and staying within limits.

## Status codes

| Code  | Meaning           | What to do                                     |
| ----- | ----------------- | ---------------------------------------------- |
| `200` | Success           | —                                              |
| `201` | Created           | —                                              |
| `400` | Bad request       | Fix the request body or parameters.            |
| `401` | Unauthorised      | Missing, malformed or revoked token.           |
| `403` | Forbidden         | Valid token, insufficient scope.               |
| `404` | Not found         | Wrong ID, or a resource in another account.    |
| `422` | Validation failed | Read the response body for the specific field. |
| `429` | Rate limited      | Back off and retry.                            |
| `5xx` | Server error      | Retry with backoff.                            |

## Telling 401 from 403

`401` means the token was not accepted — missing, malformed, or revoked.

`403` means the token is fine but lacks the scope. If you get this on a write, your key is probably read-only. See [API keys](/developers/api-keys).

## Error bodies

Errors return JSON describing what went wrong. Log the whole body when debugging — the message names the specific field on validation failures, which saves guessing.

## Pagination

List endpoints are paginated. Page through using the parameters the endpoint documents rather than requesting a very large page.

Never assume you have everything from the first response. A list that looks complete in testing will silently truncate in production when the account has more data.

## Rate limits

Requests are rate limited per account. Exceeding the limit returns `429`.

Handle it properly:

* **Back off exponentially.** Wait, then double the wait on each subsequent failure.
* **Add jitter.** Randomise the delay so parallel workers do not retry in lockstep.
* **Respect any retry-after header** if one is returned.
* **Cap retries.** Give up eventually and surface the failure.

Retrying immediately in a tight loop makes things worse and can extend the limit.

## Avoiding limits

**Use webhooks instead of polling.** This is the main one. Polling every minute for new calls burns your limit and gives you stale data; a webhook delivers it immediately and costs one request. See [Webhook events](/developers/webhook-events).

**Batch where an endpoint supports it.**

**Cache what does not change.** Team members and numbers do not need refetching every request.

**Filter server-side.** Request what you need rather than fetching everything and filtering locally.

## Retrying safely

Retry `429` and `5xx`. Do not retry `4xx` other than `429` — the request is wrong and will stay wrong.

For writes, make retries safe. A `POST` that times out may have succeeded; retrying blindly creates a duplicate. Where possible, check before retrying.

## Timeouts

Set a sensible client timeout and treat a timeout as an unknown outcome rather than a failure. The request may have been processed.


# Calls API

List and inspect calls, fetch recordings and transcripts, and write outcomes back.

| Method  | Path                        | Scope         |
| ------- | --------------------------- | ------------- |
| `GET`   | `/calls`                    | `calls:read`  |
| `GET`   | `/calls/{id}`               | `calls:read`  |
| `GET`   | `/calls/{id}/recording`     | `calls:read`  |
| `GET`   | `/calls/{id}/transcription` | `calls:read`  |
| `GET`   | `/calls/{id}/summary`       | `calls:read`  |
| `GET`   | `/calls/{id}/voicemail`     | `calls:read`  |
| `PATCH` | `/calls/{id}`               | `calls:write` |

## List calls

```bash
curl "https://app.limecall.com/api/v1/calls?limit=50&page=1" \
  -H "Authorization: Bearer sk_live_..."
```

Newest first. Returns the standard list envelope:

```json
{
  "data": [ { "id": 4812, "from": "+441134960000", "to": "+447700900123", "...": "..." } ],
  "pagination": { "page": 1, "limit": 50, "total": 1284 }
}
```

### Query parameters

| Parameter     | Notes                                                                                                       |
| ------------- | ----------------------------------------------------------------------------------------------------------- |
| `page`        | Defaults to `1`.                                                                                            |
| `limit`       | Defaults to `50`, capped at `200`.                                                                          |
| `userId`      | Only calls belonging to that user.                                                                          |
| `phoneNumber` | Matches **either** leg. Repeatable — pass it more than once to match any of several numbers.                |
| `peer`        | Matches the other party only.                                                                               |
| `since`       | ISO 8601 timestamp, exclusive lower bound on creation. A value that is not a valid timestamp returns `400`. |

`phoneNumber` being repeatable is the useful one: `?phoneNumber=+44113...&phoneNumber=+44114...` returns calls touching either line in one request.

## Get one call

```bash
curl https://app.limecall.com/api/v1/calls/4812 \
  -H "Authorization: Bearer sk_live_..."
```

Returns the call object directly — no envelope. `404` if the id does not exist **or** belongs to another organization; the two are deliberately indistinguishable.

## Recording, transcription, summary, voicemail

Four sub-resources on a call:

```bash
curl https://app.limecall.com/api/v1/calls/4812/transcription \
  -H "Authorization: Bearer sk_live_..."
```

Each returns `404` when that artefact does not exist for the call — a call with recording disabled has no recording, and a call the AI did not handle has no summary. Check rather than assume.

## Write an outcome back

The most valuable call in the API. It is what turns the call log from a record of activity into a record of revenue.

```bash
curl -X PATCH https://app.limecall.com/api/v1/calls/4812 \
  -H "Authorization: Bearer sk_live_..." \
  -H "Content-Type: application/json" \
  -d '{"outcome":"appointment_booked","value":250,"currency":"USD"}'
```

| Field      | Rules                                                                                                           |
| ---------- | --------------------------------------------------------------------------------------------------------------- |
| `outcome`  | Non-empty string, truncated to 120 characters. Your own vocabulary — reuse the same name and calls group by it. |
| `value`    | A number. Strings that parse as numbers are accepted.                                                           |
| `currency` | Three-letter ISO 4217, case-insensitive, stored uppercase.                                                      |
| `metadata` | A JSON object. Not an array, not a scalar.                                                                      |

**At least one** of `outcome`, `value` or `metadata` must be present — an empty body returns `400`.

Validation runs before anything is written, so a rejected request never half-applies.

### Errors

| Response                                                | Cause                                        |
| ------------------------------------------------------- | -------------------------------------------- |
| `400 Invalid call id`                                   | The id is not a number.                      |
| `400 outcome must be a non-empty string`                | `outcome` present but blank or not a string. |
| `400 value must be a number`                            | `value` will not parse.                      |
| `400 currency must be a 3-letter ISO-4217 code`         | Wrong shape.                                 |
| `400 metadata must be an object`                        | An array or scalar was sent.                 |
| `400 Provide at least one of: outcome, value, metadata` | Nothing to apply.                            |

See [Conversions](/analytics/conversions) for what to do with the data once it is flowing.


# Messages API

Send SMS and MMS, and list message history.

| Method | Path             | Scope            |
| ------ | ---------------- | ---------------- |
| `GET`  | `/messages`      | `messages:read`  |
| `GET`  | `/messages/{id}` | `messages:read`  |
| `POST` | `/messages`      | `messages:write` |

## Send a message

```bash
curl -X POST https://app.limecall.com/api/v1/messages \
  -H "Authorization: Bearer sk_live_..." \
  -H "Content-Type: application/json" \
  -d '{
    "to": "+447700900123",
    "from": "+441134960000",
    "body": "Your appointment is confirmed for Thursday at 9:30."
  }'
```

| Field       | Notes                                                     |
| ----------- | --------------------------------------------------------- |
| `to`        | Recipient, international format.                          |
| `from`      | One of **your** numbers, and it must have SMS capability. |
| `body`      | The message text.                                         |
| `mediaUrls` | Optional array of URLs for MMS.                           |

{% hint style="warning" %}
A `200` here means LimeCall accepted the message, **not** that it was delivered. Carriers filter silently — unregistered US traffic is accepted and then dropped with no error anywhere. If delivery looks wrong, check registration before debugging your code. See [US carrier registration (10DLC)](/virtual-numbers/us-carrier-registration).
{% endhint %}

Opt-outs are enforced upstream of this endpoint: a contact who replied STOP will not receive your message regardless of what you send.

## List messages

```bash
curl "https://app.limecall.com/api/v1/messages?peer=%2B447700900123" \
  -H "Authorization: Bearer sk_live_..."
```

Same filters as [Calls](/developers/calls): `page`, `limit`, `userId`, `phoneNumber` (repeatable, matches either leg), `peer`, `since`.

Returns the standard `{ data, pagination }` envelope.

## Get one message

```bash
curl https://app.limecall.com/api/v1/messages/9931 \
  -H "Authorization: Bearer sk_live_..."
```

Use this to check delivery state for a specific message rather than re-listing.


# Contacts API

Full CRUD over the people who contact you.

| Method   | Path             | Scope            |
| -------- | ---------------- | ---------------- |
| `GET`    | `/contacts`      | `contacts:read`  |
| `GET`    | `/contacts/{id}` | `contacts:read`  |
| `POST`   | `/contacts`      | `contacts:write` |
| `PATCH`  | `/contacts/{id}` | `contacts:write` |
| `DELETE` | `/contacts/{id}` | `contacts:write` |

The only resource in the API with full CRUD.

## List contacts

```bash
curl "https://app.limecall.com/api/v1/contacts?page=1&limit=50" \
  -H "Authorization: Bearer sk_live_..."
```

`page` defaults to `1` and `limit` to `50`. Returns the standard `{ data, pagination }` envelope.

## Fields

Accepted on both `POST` and `PATCH`:

`firstName` · `lastName` · `email` · `phone` · `address` · `city` · `state` · `zipCode` · `tags` · `status` · `notes`

## Create

```bash
curl -X POST https://app.limecall.com/api/v1/contacts \
  -H "Authorization: Bearer sk_live_..." \
  -H "Content-Type: application/json" \
  -d '{
    "firstName": "Priya",
    "lastName": "Patel",
    "phone": "+447700900123",
    "email": "priya@example.com",
    "tags": ["import", "leeds"]
  }'
```

Send `phone` in international format. Contacts are matched on phone number throughout LimeCall, so a national-format number creates a duplicate rather than matching the existing person.

## Update

```bash
curl -X PATCH https://app.limecall.com/api/v1/contacts/3310 \
  -H "Authorization: Bearer sk_live_..." \
  -H "Content-Type: application/json" \
  -d '{"status":"customer","notes":"Signed 12 Sept."}'
```

Send only the fields you are changing.

## Delete

```bash
curl -X DELETE https://app.limecall.com/api/v1/contacts/3310 \
  -H "Authorization: Bearer sk_live_..."
```

{% hint style="warning" %}
Deleting a contact removes the person and the history attached to them, including recordings. This is how an erasure request is honoured — and it is not reversible. See [Security](/account/security).
{% endhint %}

## Bulk imports

There is no bulk endpoint. Importing a list means one `POST` per row, so respect the rate limit and back off on `429` rather than firing the whole file at once. See [Errors, pagination & rate limits](/developers/errors-and-rate-limits).

For a one-off import, the CSV importer in the dashboard is easier — see [Contacts](/inbox-and-leads/contacts).


# Phone numbers API

List the numbers you own and change how they are configured.

| Method  | Path                  | Scope                 |
| ------- | --------------------- | --------------------- |
| `GET`   | `/phone-numbers`      | `phone-numbers:read`  |
| `GET`   | `/phone-numbers/{id}` | `phone-numbers:read`  |
| `PATCH` | `/phone-numbers/{id}` | `phone-numbers:write` |

## List your numbers

```bash
curl https://app.limecall.com/api/v1/phone-numbers \
  -H "Authorization: Bearer sk_live_..."
```

Pass `?userId=...` to return only the numbers assigned to one user.

Each number reports its capabilities. **Check these before sending** — not every number can text, and a `from` on a voice-only number fails at send time rather than at configuration time.

## Update a number

Three fields are accepted. Sending none of them returns `400`.

| Field              | Rules                                                                                                                 |
| ------------------ | --------------------------------------------------------------------------------------------------------------------- |
| `forwardingNumber` | **E.164 only** — `+` then 7–15 digits, e.g. `+14155550142`. Anything else returns `400`. `null` turns forwarding off. |
| `voicemailEnabled` | Boolean. A non-boolean returns `400`.                                                                                 |
| `friendlyName`     | String, trimmed, truncated to 120 characters. `null` clears it.                                                       |

```bash
curl -X PATCH https://app.limecall.com/api/v1/phone-numbers/77 \
  -H "Authorization: Bearer sk_live_..." \
  -H "Content-Type: application/json" \
  -d '{"forwardingNumber":"+14155550142","friendlyName":"Google Ads — Leeds"}'
```

Returns the updated number.

### What setting a forwarding number does

Setting `forwardingNumber` routes the line to an external number, and **clears any team or team-member destination** on it. One line cannot hold three contradictory targets, so the other two are removed rather than left stale.

### What clearing it does not do

Sending `"forwardingNumber": null` stops forwarding to that number. It does **not** hand the line to your AI receptionist — that is a much bigger change than the request asked for, and it is deliberately not implied.

If you want the AI to answer the line, set that destination explicitly in the dashboard. See [Call forwarding & routing](/virtual-numbers/call-forwarding-and-routing).

### A legacy alias

`callForwarding` is still accepted, as a string, as `{ target, enabled }`, or as `null`, and lands on the same columns. Prefer `forwardingNumber` in new code.

## What this endpoint will not do

**Buying and porting are not in the API.** Both involve payment and, in most countries, regulatory documents, so they are dashboard-only. See [Buy a number](/virtual-numbers/buy-a-number) and [Bring your number](/virtual-numbers/bring-your-number).

Releasing a number is likewise dashboard-only — it is irreversible and deliberately not one API call away.


# Voicemails API

List voicemails and mark them read.

| Method  | Path               | Scope         |
| ------- | ------------------ | ------------- |
| `GET`   | `/voicemails`      | `calls:read`  |
| `PATCH` | `/voicemails/{id}` | `calls:write` |

## List voicemails

```bash
curl "https://app.limecall.com/api/v1/voicemails?unreadOnly=true" \
  -H "Authorization: Bearer sk_live_..."
```

### Query parameters

| Parameter        | Notes                                 |
| ---------------- | ------------------------------------- |
| `page` / `limit` | Standard paging.                      |
| `unreadOnly`     | Only voicemails nobody has picked up. |
| `status`         | Filter by state.                      |
| `phoneNumber`    | Which of your lines took it.          |
| `userId`         | Whose voicemail.                      |
| `since`          | ISO 8601 timestamp.                   |

`unreadOnly=true` is the one to build on: poll it, or better, subscribe to the event and let the webhook tell you.

## Mark one handled

```bash
curl -X PATCH https://app.limecall.com/api/v1/voicemails/551 \
  -H "Authorization: Bearer sk_live_..." \
  -H "Content-Type: application/json" \
  -d '{"status":"read"}'
```

Update status once your own system has dealt with it, so the unread queue means something.

## Worth knowing

Voicemails are transcribed, so you can route on the text rather than making someone listen first — send the transcript to a triage step and only escalate what matters.

If you are building a voicemail workflow at all, consider whether the AI receptionist removes the need for one: most callers do not leave voicemails, and an AI that answers converts the ones who would have hung up. See [Voicemail](/virtual-numbers/voicemail).


# Users API

Read your team, and manage verified caller-ID numbers.

| Method | Path                                     | Scope         |
| ------ | ---------------------------------------- | ------------- |
| `GET`  | `/users`                                 | `users:read`  |
| `GET`  | `/users/{id}`                            | `users:read`  |
| `GET`  | `/users/{id}/verified-numbers`           | `users:read`  |
| `POST` | `/users/{id}/verified-numbers/send-code` | `users:write` |
| `POST` | `/users/{id}/verified-numbers/verify`    | `users:write` |

## List your team

```bash
curl https://app.limecall.com/api/v1/users \
  -H "Authorization: Bearer sk_live_..."
```

Read-only. Inviting, removing and changing roles are dashboard-only — see [Team & roles](/account/team-and-roles).

## Verified numbers

A user can display a number they own outside LimeCall as caller ID, but only after proving they control it. That is a two-step flow, and it is the one genuinely interesting thing in this resource.

### 1. Send the code

```bash
curl -X POST https://app.limecall.com/api/v1/users/u_2841/verified-numbers/send-code \
  -H "Authorization: Bearer sk_live_..." \
  -H "Content-Type: application/json" \
  -d '{"phoneNumber":"+441134960000"}'
```

LimeCall calls or texts that number with a code.

### 2. Confirm it

```bash
curl -X POST https://app.limecall.com/api/v1/users/u_2841/verified-numbers/verify \
  -H "Authorization: Bearer sk_live_..." \
  -H "Content-Type: application/json" \
  -d '{"phoneNumber":"+441134960000","code":"418293"}'
```

### 3. Check what is verified

```bash
curl https://app.limecall.com/api/v1/users/u_2841/verified-numbers \
  -H "Authorization: Bearer sk_live_..."
```

{% hint style="info" %}
Someone must be able to answer that number to complete step 2. This is a carrier anti-spoofing requirement, not a LimeCall policy, and there is no way around it — including from the API.
{% endhint %}

Use this when onboarding staff programmatically: create the user in your own system, then drive verification from your onboarding flow instead of asking each person to find the setting.

See [Caller ID](/virtual-numbers/caller-id).


# Webhooks API

Manage webhook subscriptions programmatically.

| Method   | Path             | Scope            |
| -------- | ---------------- | ---------------- |
| `GET`    | `/webhooks`      | `webhooks:read`  |
| `GET`    | `/webhooks/{id}` | `webhooks:read`  |
| `POST`   | `/webhooks`      | `webhooks:write` |
| `PATCH`  | `/webhooks/{id}` | `webhooks:write` |
| `DELETE` | `/webhooks/{id}` | `webhooks:write` |

This manages *subscriptions*. For what the deliveries contain and how to handle them, see [Webhook events](/developers/webhook-events).

## Create a subscription

```bash
curl -X POST https://app.limecall.com/api/v1/webhooks \
  -H "Authorization: Bearer sk_live_..." \
  -H "Content-Type: application/json" \
  -d '{
    "url": "https://example.com/hooks/limecall",
    "events": ["call.completed", "message.received"],
    "description": "Production CRM sync",
    "maxRetries": 5
  }'
```

| Field         | Rules                               |
| ------------- | ----------------------------------- |
| `url`         | Must be a valid URL.                |
| `events`      | Array, **at least one** entry.      |
| `description` | Optional, for your own bookkeeping. |
| `maxRetries`  | Integer `0`–`10`. Defaults to `3`.  |

Returns `201` with the created subscription.

{% hint style="warning" %}
The response includes a generated **`secret`**. This is how you verify that a delivery genuinely came from LimeCall. Store it when you create the subscription — treat it like a password, and never skip the verification step, because your endpoint URL is reachable by anyone who learns it.
{% endhint %}

## Update

```bash
curl -X PATCH https://app.limecall.com/api/v1/webhooks/wh_8821 \
  -H "Authorization: Bearer sk_live_..." \
  -H "Content-Type: application/json" \
  -d '{"isActive": false}'
```

`url`, `events`, `description`, `isActive` and `maxRetries` can all be changed. Setting `isActive: false` pauses deliveries without losing the subscription or its secret — the right move during a deploy, rather than deleting and recreating.

## Delete

```bash
curl -X DELETE https://app.limecall.com/api/v1/webhooks/wh_8821 \
  -H "Authorization: Bearer sk_live_..."
```

Permanent, and the secret goes with it.

## Choosing maxRetries

Retries cover a brief outage on your side. They do not fix an endpoint that returns an error for a payload it cannot handle — that will exhaust its retries and be dropped.

Return `2xx` as soon as you have accepted the payload and process asynchronously, so a slow database does not turn into a retry storm.


# Analytics API

Usage totals and call and message breakdowns.

| Method | Path                  | Scope            |
| ------ | --------------------- | ---------------- |
| `GET`  | `/analytics/usage`    | `analytics:read` |
| `GET`  | `/analytics/calls`    | `analytics:read` |
| `GET`  | `/analytics/messages` | `analytics:read` |

## Usage

```bash
curl https://app.limecall.com/api/v1/analytics/usage \
  -H "Authorization: Bearer sk_live_..."
```

```json
{
  "calls": 1284,
  "messages": 3971,
  "apiRequests": 20544
}
```

Lifetime totals for your organization — counts, not billing figures.

{% hint style="warning" %}
Do not reconcile a bill against this endpoint. It counts rows; your invoice reflects billing periods, plan allowances, per-destination rates and credits. Those two numbers are not supposed to match. Billing lives at **Settings → Plan & billing** — see [Usage & credits](/account/usage-and-credits).
{% endhint %}

## Calls and messages breakdowns

```bash
curl https://app.limecall.com/api/v1/analytics/calls \
  -H "Authorization: Bearer sk_live_..."
```

Aggregates for reporting. For anything these do not cover, list the underlying records and aggregate yourself — [Calls](/developers/calls) supports filtering by user, number, peer and time window, which is usually enough to build the cut you actually want.

## Building your own reporting

The combination worth knowing: filter calls with `since` on a schedule, and write outcomes back with `PATCH /calls/{id}`. Once outcomes carry a `value`, you can report revenue per source rather than call volume per source — which is the difference between knowing a channel is busy and knowing it is worth paying for.

See [Conversions](/analytics/conversions).


# Devices API

Register and remove push notification tokens.

| Method   | Path       | Scope           |
| -------- | ---------- | --------------- |
| `POST`   | `/devices` | `devices:write` |
| `DELETE` | `/devices` | `devices:write` |

Narrow by design: this registers push tokens so a mobile client can be woken for an incoming call or message. It is only relevant if you are building your own client.

## Register a device

```bash
curl -X POST https://app.limecall.com/api/v1/devices \
  -H "Authorization: Bearer sk_live_..." \
  -H "Content-Type: application/json" \
  -d '{"token":"<push-token>","platform":"ios"}'
```

| Field      | Notes                                    |
| ---------- | ---------------------------------------- |
| `token`    | The push token from APNs or FCM.         |
| `platform` | Which push service the token belongs to. |

## Remove a device

```bash
curl -X DELETE https://app.limecall.com/api/v1/devices \
  -H "Authorization: Bearer sk_live_..." \
  -H "Content-Type: application/json" \
  -d '{"token":"<push-token>"}'
```

Identified by `token` in the body, not by an id in the path.

## Keep the registry clean

Push tokens rotate — on reinstall, on restore to a new phone, and at the OS's discretion. Re-register on every app launch rather than once at install, and delete the token on sign-out.

Stale tokens are not harmless: they accumulate, and delivery to dead tokens is what gets a sender throttled by the push services.

## If you are not building a client

You do not need this. To take calls on a phone or desk handset, use the supported options in [Devices](/virtual-numbers/devices) — browser, forwarding, or a SIP handset.


# Troubleshooting

Fixes for the problems that come up most.

Start with the symptom.

| Symptom                                            | Page                                                                      |
| -------------------------------------------------- | ------------------------------------------------------------------------- |
| The widget is not on my site                       | [The widget is not showing](/troubleshooting/widget-not-showing)          |
| Calls ring but do not connect, or audio is one-way | [Calls are not connecting](/troubleshooting/calls-not-connecting)         |
| My AI receptionist is not answering                | [The AI receptionist is not answering](/troubleshooting/ai-not-answering) |
| Texts are not being delivered                      | [Texts are not being delivered](/troubleshooting/sms-not-sending)         |
| I cannot sign in                                   | [I cannot sign in](/troubleshooting/signing-in)                           |

## Before you start

Two things solve a surprising share of problems:

**Test in a private/incognito window.** This eliminates cached pages, stale sessions and browser extensions in one step.

**Check the obvious state.** Is the plan active? Is there credit left? Are you inside business hours? Are your personal hours current? Most "it stopped working" reports resolve to one of these.

## Getting help

If you contact support, include:

* what you expected and what happened,
* when it started,
* a specific example — the call ID, the number dialled, the exact time,
* what you have already tried.

A call ID and a timestamp turn a multi-day exchange into a single reply.


# The widget is not showing

Work through this in order.

Work through these in order — they are arranged by how often they are the cause.

## 1. Test in a private window

Open your site in a private/incognito window.

A normal window may serve a cached page, or remember that you dismissed the widget earlier. This alone resolves a large share of reports.

## 2. Wait a few seconds

The widget loads after your page content, deliberately, so it does not delay your page. Give it two or three seconds.

## 3. Confirm the snippet is on the page

View the page source and search for `limecall`.

**Not there** — the snippet is not installed on this page. This is the most common cause: it was added to the homepage only, rather than to a shared template. See [Install with JavaScript](/callback/install-with-javascript).

**There** — continue.

## 4. Clear every cache

Caching is the second most common cause. Purge all of them:

* your caching plugin (WP Rocket, W3 Total Cache, LiteSpeed, WP Super Cache),
* your host's server-side cache,
* Cloudflare or any other CDN.

Then retest in a private window.

## 5. Check display rules

Open **Widget → Display rules**. A rule may be excluding this page.

Remember rules are evaluated in order and the first match wins — an early broad rule can override a later specific one. Also check the device rules, if you are testing on mobile. See [Display rules](/callback/display-rules).

## 6. Check business hours

If the widget is configured to hide outside business hours, it will be absent when you are closed.

Check the time zone on your business hours — hours set in the wrong zone are a frequent cause of a widget missing during the actual working day. See [Hours](/callback/hours).

## 7. Open the browser console

Press F12 and look at the Console tab.

**`Content Security Policy` errors** — your CSP is blocking the script. Allow the widget origins; see [Install with JavaScript](/callback/install-with-javascript).

**`404` on the widget script** — the snippet is malformed. Recopy it from **Widget → Embed**.

**`Blocked by client`** — an ad blocker or privacy extension is blocking it. Test with extensions disabled. Some visitors will block it too; that is unavoidable.

**No errors at all** — the script is probably not on the page. Return to step 3.

## 8. Check optimisation plugins

Plugins that combine, defer or minify JavaScript frequently break third-party widgets. Add `limecall` to the exclusion list. See [Install on WordPress](/callback/install-on-wordpress).

## 9. If you used Google Tag Manager

Confirm you clicked **Submit** and **Publish**. Changes visible in GTM Preview are not live until published — a very common oversight. See [Install with Google Tag Manager](/callback/install-with-google-tag-manager).

## Still nothing

Contact support with the page URL, the browser and device, a screenshot of the console, and confirmation of the steps above.


# Calls are not connecting

Ringing but not answering, one-way audio and poor quality.

## Nobody's phone rings

**Check the destination.** Open **Phone Numbers** and confirm **Who answers your calls** points where you expect. See [Call forwarding & routing](/virtual-numbers/call-forwarding-and-routing).

**Check both availability layers.** Business hours decide whether the company is open; personal hours decide whether an individual is rung. A call inside business hours when everyone is outside their own hours has nobody to ring. Check **Settings → Business hours** and **Settings → My hours**.

**Check the device.** The member's chosen device must actually be reachable — the dashboard open for browser calling, a valid number for forwarding, a registered handset for SIP. See [Devices](/virtual-numbers/devices).

**Check there is a fallback.** A number with no fallback drops calls silently when the destination does not answer.

## The browser does not ring

**Microphone permission.** The most common cause. Click the padlock in the address bar and confirm microphone access is allowed for app.limecall.com.

**The dashboard must be open.** Browser calling needs an open tab.

**Try another browser.** A current Chrome or Edge is the safest test.

**Check notification permission** if you rely on the visual alert.

## One-way audio

Almost always a microphone or network problem on one side.

* Check microphone permission, and that the right input device is selected in your operating system.
* Test with a wired headset — Bluetooth devices frequently connect as an output-only profile.
* Try a wired network connection rather than wi-fi.
* Check a corporate firewall or VPN is not blocking the media path; this is common on locked-down office networks.

## Poor audio quality

* Use a wired headset. Laptop speakers with an open microphone cause echo.
* Prefer wired networking to wi-fi for browser calling.
* Close bandwidth-heavy applications — video calls, large uploads.
* If quality is poor in the browser but fine on a forwarded mobile, the problem is local, not the platform.

## Outbound calls fail

**Verify your phone number** if you have not — outbound is disabled until verification completes. See [Create your account](/start-here/create-your-account).

**Check credit and allowances.** Outbound is restricted when you run out. See [Usage & credits](/account/usage-and-credits).

**Check country permissions.** Calling to some countries is restricted by default. If calls to one country fail while others work, this is why — contact support to enable it.

**Check the caller ID.** An unverified caller ID can cause rejection at the carrier. See [Caller ID](/virtual-numbers/caller-id).

## Callers reach voicemail immediately

The destination is not accepting the call — a device not registered, or personal hours that have ended. Check both, then test by calling the number directly.

## Getting help

Include the call ID from **Calls**, the exact time with time zone, the numbers involved, and which side had the problem.


# The AI receptionist is not answering

Silence, wrong answers and failed transfers.

## It does not pick up at all

**Check AI minutes.** The most common cause. When minutes run out with no credit balance, the assistant stops answering — and nothing announces it. Open **Settings → Usage & credits**. See [AI minutes & usage](/ai-receptionist/ai-minutes-and-usage).

Set a usage alert so this does not recur.

**Check the number's destination.** Open **Phone Numbers** and confirm **Who answers your calls** is set to your AI receptionist on the number you are testing. A perfectly configured assistant on a number pointing elsewhere helps nobody.

**Check the channel is on.** Open **AI Receptionist → Phone Calls** and confirm **Answers phone calls** is enabled.

**Check it is not paused.** A paused assistant sends calls to its **Forward to while paused** destination — or nowhere if that is unset.

## It answers but says the wrong things

Wrong facts are almost always a knowledge problem, not a prompt problem. Fix the fact rather than instructing the assistant around it.

* **Wrong prices** → [Products & services](/ai-receptionist/products-and-services)
* **Wrong hours** → [Contact information](/ai-receptionist/contact-information), and check they match **Settings → Business hours**
* **Services you do not offer** → state the exclusions in [Company details](/ai-receptionist/company-details)
* **Invented answers** → add the missing fact to [Additional knowledge](/ai-receptionist/additional-knowledge)

If you scanned your website at signup, re-read what was imported. Scrapers pick up stale pricing pages.

## It mishears callers

Add the words it gets wrong under **Specialized terms** in [Scenarios & call types](/ai-receptionist/scenarios-and-call-types). This helps recognition as well as pronunciation.

Also check the assistant's **Language** is correct — the wrong language degrades recognition badly, not just output.

## It interrupts people

Move **End-of-speech patience** toward **Patient** under [Phone calls](/ai-receptionist/phone-calls).

Do this if your callers are older, speak slowly, or read out numbers and addresses.

## It will not transfer

Open **AI Receptionist → Transfers & Escalation**.

* Is a **Transfer to** destination set?
* Does that destination actually answer?
* Is there a fallback for when it does not?

An assistant that refuses to fetch a human is the fastest way to make a caller angry. Test this path specifically.

## Transfers fail silently

If the transfer destination does not answer and no fallback is configured, the call drops. Set a fallback — voicemail, a message, or a callback offer.

## It stopped working after an edit

Open **Version history** in the editor, compare against the version that worked, and restore it if needed.

Prompt changes have effects you will not predict from reading them. Always retest after editing. See [Test your assistant](/ai-receptionist/test-your-assistant).

## Spam is eating my minutes

Enable **Screen spam & robocalls** and add repeat offenders to the block list. See [Spam & blocking](/ai-receptionist/spam-and-blocking).


# Texts are not being delivered

Why messages are accepted but never arrive.

## The key distinction

**Sent** and **delivered** are different. Carriers filter messages silently: LimeCall accepts the message, reports it sent, and the recipient never receives it. There is often no error.

If your delivery rate looks wrong, assume filtering before assuming bad numbers.

## 1. Check US carrier registration

If you are texting US numbers, this is the first thing to check and by far the most common cause.

Unregistered application-to-person traffic to US numbers is filtered or blocked by the carriers. Open **Settings → Messaging** and confirm your brand and campaign registration is approved — not submitted, approved.

See [US carrier registration (10DLC)](/virtual-numbers/us-carrier-registration).

Toll-free numbers use a separate verification process. If you are sending from a toll-free number, check that instead.

## 2. Check the number supports SMS

Not every number can text. Open **Phone Numbers** and check the number's capabilities.

If SMS is not listed, it cannot be added — you need a different number. See [Buy a number](/virtual-numbers/buy-a-number).

## 3. Check the recipient is not suppressed

Anyone who replied STOP or similar is suppressed permanently and automatically. Messages to them are not sent.

This is a legal requirement and should not be worked around.

## 4. Check the destination country

Rules vary widely. Some countries require pre-registered sender IDs or message templates, and some do not accept application-originated messages from foreign numbers at all.

If messages to one country fail while others succeed, this is why.

## 5. Check your content

Carrier filters react to:

* **Public link shorteners.** bit.ly and similar are strongly associated with spam. Use your own domain.
* **No sender identification.** Say who you are in the message.
* **No opt-out** on bulk messages.
* **Spam-associated wording** — aggressive urgency, financial promises, all-caps.

## 6. Check allowances and credit

Sending stops when message allowances are exhausted with no credit. See [Usage & credits](/account/usage-and-credits).

## 7. Check the number format

Numbers should be in international format. A national-format number may be rejected or misrouted.

## Inbound messages not arriving

If you can send but not receive:

* Confirm the number supports SMS.
* Check whether the AI receptionist's text channel is on and handling them — they may be answered already and not appear as unread. See [Text messages](/ai-receptionist/text-messages).
* Check your Inbox filters are not hiding them.

## Diagnosing

Send a test to a phone you control on the same carrier as your affected recipients. If your test arrives and customers' do not, the issue is content or list-specific rather than configuration.

Check delivery status on individual messages to distinguish accepted, delivered and failed.


# I cannot sign in

Passwords, lockouts and account access.

## Reset your password

1. Go to [app.limecall.com](https://app.limecall.com).
2. Choose **Forgot password**.
3. Enter the email address on your account.
4. Follow the link sent to you.

The link expires. If it has, request a fresh one rather than reusing the old email.

## The reset email has not arrived

* Wait a couple of minutes.
* Check spam and junk.
* Check you used the right address — the one you registered with, which may not be the one you use daily.
* If your company filters mail, ask IT to allow mail from LimeCall.

## You signed up with Google

If you registered with Google, use **Sign in with Google** rather than a password. There is no password on the account unless you set one.

If you are unsure which you used, try Google first.

## Your email address changed

If you no longer have access to the registered address, you cannot reset the password yourself. Ask an Owner or Admin on your account to update your email, or contact support — expect to verify your identity.

## Two-step sign-in problems

**Lost your device** — use a recovery code.

**Lost your recovery codes too** — contact support. Expect identity verification, and expect it to take time. This is deliberate.

## Your account is locked

Repeated failed attempts temporarily lock sign-in. Wait and try again, using a password reset rather than more guesses.

## You can sign in but see nothing

**Your access may have been changed.** A Viewer sees far less than an Admin. Ask an Owner to check your role. See [Team & roles](/account/team-and-roles).

**Your account may be suspended** for a failed payment. An Owner should check **Settings → Plan & billing**. See [Plans & billing](/account/plans).

**Check you are in the right account** if you belong to more than one.

## Sessions keep ending

**Someone signed out everywhere** — after a password change or a security action, all sessions are invalidated and everyone must sign in again.

**Your browser is clearing cookies** — check privacy settings and extensions.

## Signing out everywhere yourself

Open **Settings → Security** to see active sessions and sign out of any you do not recognise. Do this immediately if you suspect your password is known. See [Security](/account/security).


