> For clean Markdown of any page, append .md to the page URL.
> For a complete documentation index, see https://docs.messageblue.ai/llms.txt.
> For AI client integration (Claude Code, Cursor, etc.), connect to the MCP server at https://docs.messageblue.ai/_mcp/server.

# Core concepts

## Account and app

An **account** is who you sign in as. An **app** is what owns everything else — credentials, phone numbers, conversations, webhooks, the AI agent and team members all belong to one app.

An account holds **one app**. If you need a second, use a second account.

## Credentials

Three values identify and authenticate you:

| Value          | Purpose                             | Retrievable later?              |
| -------------- | ----------------------------------- | ------------------------------- |
| **Account ID** | Identifies the owning account       | Yes                             |
| **App ID**     | Identifies the app on every request | Yes                             |
| **App Secret** | Signs your API requests             | **No** — shown once at creation |

You can mint a replacement secret at any time, but the old one stops working the moment you do. See [API & secrets](/settings#api-and-secrets).

## Numbers, devices and the Mac agent

MessageBlue does not emulate iMessage — it drives it. Every number is backed by a real, signed-in Apple device: an iMessage-capable Mac running the packaged **MessageBlue agent**, which holds a live connection to the gateway.

This has consequences worth internalising:

#### Numbers can go offline

If the Mac behind a number loses its connection, sending fails with *"Sending number is offline"* until it returns. Connectivity is visible in [Analytics](/analytics#agents-and-devices).

#### Devices enrol and can be revoked

Each device holds an ID and secret. Revoking them forces a re-enrol on next connect — useful if a Mac is lost, disruptive otherwise.

You get a number either by [pairing a Mac you own](/create-an-app#bring-your-own-number) or by [requesting one](/dashboard#phone-numbers), which the team provisions for you.

## Contacts and mappings

A **contact** is someone you exchange messages with. A **mapping** ties that contact to one of your numbers — the *agent number* that talks to them. A contact keeps talking to the same number of yours unless you [remap](/messages#remapping-the-agent) them.

Contacts carry state beyond their messages: a name you set, free-text notes, tags, an assigned team member, and a blocked flag.

## Conversations and messages

A **conversation** is the thread between one of your numbers and a contact. **Group chats** are the multi-participant variant, with [their own creation rules](/group-chats).

Every outbound message carries a delivery status:

| Status         | Meaning                                           |
| -------------- | ------------------------------------------------- |
| `sent`         | Handed to Apple                                   |
| `delivered`    | Confirmed delivered to the recipient              |
| `read`         | The recipient opened it                           |
| `SMS_FALLBACK` | Delivered as SMS because iMessage was unavailable |
| `failed`       | Delivery failed                                   |

Messages also record **who sent them** — a person in the web app, your server over the API, or the AI agent. The inbox badges each accordingly.

## Webhooks

Two URLs, set once in [Settings](/settings#webhooks):

* **Inbound** — incoming messages and reactions
* **Status** — delivery-status transitions

Every delivery is signed. Verify the `X-MB-Signature` header, which is `v1=<hex>` where the hex is `HMAC-SHA256(signing_secret, "{X-MB-Timestamp}.{raw body}")`.

Compute the HMAC over the **raw request bytes**. Parsing JSON and re-serializing it reorders keys and changes whitespace, producing a digest that never matches. This is the single most common webhook integration bug.

Respond `2xx` within 10 seconds. Failures are retried, and deliveries that exhaust their retries are **dead-lettered** — kept, listed in [Failed webhooks](/failed-webhooks), and replayable.

## The AI agent

An optional agent that answers incoming messages for you. It combines:

#### A system prompt

Its instructions and personality. Versioned on every save; deploying promotes the latest version.

#### Knowledge

Files, crawled web pages and pasted notes, indexed so the agent answers from your actual business facts rather than guessing.

#### Integrations

Business apps connected through unified.to — either the business's own account, or each customer's own.

#### Memory

Durable per-customer notes carried between conversations. Optional.

An agent has a lifecycle: **Draft** → **Deployed** → **Paused**. Saving is not deploying — only deploying changes what live customers experience. See [AI Agent Studio](/ai-agent-studio).

### Agentic flow

By default the agent answers each message in one pass. With **agentic flow** enabled it can work a request over several steps — looking things up, calling connected tools, then replying once it has an answer — telling the customer up front that it will take a few minutes.

Runs are bounded by a token ceiling. Hitting it is a soft landing: the agent stops researching and replies with what it has.

## Blocking

Blocking stops **the agent** from replying to a contact. It does not stop you messaging them by hand, and the contact is never notified. MessageBlue also auto-blocks contacts it identifies as bots.

Because blocking is silent, it is the first thing to check when an agent appears to be ignoring someone — see [Blocked contacts](/analytics#blocked-contacts).