> ## Documentation Index
> Fetch the complete documentation index at: https://docs.orbit.devotel.io/llms.txt
> Use this file to discover all available pages before exploring further.

# Apple Messages for Business onboarding: business_id to active agent

> Register an Apple Messages for Business agent end to end — Apple Business Register prerequisites, the MSP partnership, dashboard + API registration, status polling, and the troubleshooting table for HMAC, webhook, and business_id failures.

# Apple Messages for Business Onboarding: business\_id to Active Agent

Apple Messages for Business (AMB) is the channel where customers start a conversation with your business from **iMessage** — tap an entry point in Apple Maps, Spotlight search, Safari, or Siri, and the thread opens in the Messages app on an iPhone or a Mac. Every AMB conversation runs through a **Messaging Service Provider (MSP)** that brokers the traffic between Apple's gateway and your platform; Orbit acts as the MSP on each conversation, so inbound messages land in your unified inbox alongside every other channel.

This guide walks the full agent lifecycle: the Apple-side prerequisites, registration from the dashboard, the matching API calls, status polling until the agent is ready, and how AMB folds into commerce. It complements the [conversational checkout flow](/guides/conversational-commerce-checkout), where AMB is one of the channels that contribute to a buyer's persistent cart.

## 1. What AMB is, and when to pick it

AMB is a **conversational, customer-initiated** channel. The customer starts the thread from an Apple surface; your business replies inside Apple's 24-hour-style messaging window, and replies can carry rich content — interactive lists, forms, time pickers, rich links, and Apple Pay payment requests.

How it compares to the other rich channels you may already run:

|               | AMB                                                                         | RCS                                      | WhatsApp                               |
| ------------- | --------------------------------------------------------------------------- | ---------------------------------------- | -------------------------------------- |
| Reach         | iMessage users on Apple devices                                             | Android (and RCS-capable iOS) handsets   | Cross-platform                         |
| Entry point   | Customer taps Apple Maps, Spotlight, Safari, Siri, or your untruncated link | Phone number on a campaign send          | wa.me link, QR, phone number           |
| Rich content  | Interactive lists, forms, Apple Pay                                         | Rich cards, carousels, suggested actions | Templates, product lists, WhatsApp Pay |
| Approval gate | Apple Business Register + MSP                                               | Carrier verification per network         | Meta WABA review                       |

Pick AMB when support and commerce happen where Apple users already search — a store locator, a booking flow, a "pay without leaving the thread" checkout. Treat it as complementary to RCS and WhatsApp, not a replacement: an iPhone-only rich-messaging audience is the gap AMB fills.

## 2. Prerequisites

Before you can register an agent you need:

* **Apple Business Register approval.** Apply at register.apple.com/business. Apple reviews the business entity behind the registration; nothing in Orbit can be done until this approval exists.
* **A `business_id`** for the approved business — the immutable identifier Apple issues, of the form `com.example.support`. It survives renames and re-registrations, and it is the routing key for inbound webhooks.
* **An MSP partnership.** Apple only accepts traffic brokered by an approved MSP. When Orbit operates as the MSP on your behalf, your account carries an assigned `msp_id`; bring your own MSP only if you have a direct agreement, and store its id on the agent.
* **The HMAC secret key.** Apple Business Register issues a base64-encoded HMAC-SHA256 key per business (≥ 16 bytes after decode, typically 32–64 characters before decode). The same key signs outbound JWTs to Apple's gateway and verifies inbound webhook signatures. Keep it in a password manager — Orbit stores the encrypted form and never shows the plaintext again.

One vs many: a single brand normally registers **one** agent per `business_id`. Register several only when you genuinely run several Apple-registered businesses — separate store brands, or a market-specific entity. Each agent is tenant-scoped and routable independently, so the decision is Apple's (`business_id` count), not Orbit's.

## 3. Register an agent from the dashboard

1. In the dashboard, open **Messages → Apple**.
2. Click **Create agent**.
3. Fill the registration form:

| Field                   | What it does                                                                                                                                                  |
| ----------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| **Business ID**         | The `business_id` Apple issued — the routing key inbound webhooks match on. Must contain only letters, digits, and `: _ . - /` (Apple's identifier alphabet). |
| **Display name**        | The label dashboard users see; shown wherever the channel renders a friendly name.                                                                            |
| **MSP ID** (optional)   | The Messaging Service Provider this business routes through. Leave unset to use Orbit's platform MSP.                                                         |
| **Secret key**          | The base64 HMAC key from Apple Business Register — ≥ 16 characters, validated client- and server-side.                                                        |
| **Logo URL** (optional) | An HTTPS logo shown on the dashboard next to the agent.                                                                                                       |

4. Submit. The form refuses a blank business ID or display name, and any secret shorter than 16 characters; a `422` from the API names the exact field that failed.

The secret is transmitted once over TLS and **encrypted at rest** before it is written; the page reads `has_secret` back — the raw value never returns to the browser. If you lose the plaintext, use **Rotate secret** on the agent row: paste the replacement key Apple issued and the old one is discarded immediately.

## 4. Register, update, and delete over API

The four operations mirror the dashboard:

```bash theme={null}
curl -X POST https://api.orbit.devotel.io/api/v1/channels/amb/agents \
  -H "X-API-Key: dv_live_sk_..." \
  -H "Content-Type: application/json" \
  -d '{
    "business_id": "com.example.support",
    "display_name": "Acme Support",
    "secret_key": "b2HHqW1YxQ==...",
    "msp_id": "orbit-cpaas",
    "logo_url": "https://example.com/logo.png",
    "capabilities": { "text": true, "interactive": true, "applePay": true }
  }'
```

The response is `201` with the agent record. Keep `data.id` — an opaque Orbit-generated UUID — because **every later call addresses the agent by this id**, never by the Apple `business_id`. The `business_id` stays readable on list and single-read calls; the secret itself is replaced by `has_secret: true`.

The same flow from the Node SDK:

```js theme={null}
const agent = await orbit.channels.amb.agents.create({
  business_id: "com.example.support",
  display_name: "Acme Support",
  secret_key: "b2HHqW1YxQ==...",
  msp_id: "orbit-cpaas",
});
console.log(agent.id, agent.status); // e36f1a2b-… "pending"
```

Update any subset of fields — `business_id` is the one value an update cannot move:

```bash theme={null}
curl -X PATCH https://api.orbit.devotel.io/api/v1/channels/amb/agents/e36f1a2b-… \
  -H "X-API-Key: dv_live_sk_..." \
  -H "Content-Type: application/json" \
  -d '{ "display_name": "Acme Support & Orders", "status": "approved" }'
```

Rotate the secret with the same PATCH:

```bash theme={null}
curl -X PATCH https://api.orbit.devotel.io/api/v1/channels/amb/agents/e36f1a2b-… \
  -H "X-API-Key: dv_live_sk_..." \
  -H "Content-Type: application/json" \
  -d '{ "secret_key": "kV1u9nFfQ==..." }'
```

Delete is irreversible and removes the webhook routing entry, so inbound AMB traffic for this business stops resolving to your tenant:

```bash theme={null}
curl -X DELETE https://api.orbit.devotel.io/api/v1/channels/amb/agents/e36f1a2b-… \
  -H "X-API-Key: dv_live_sk_..."
```

List every agent the tenant has registered:

```bash theme={null}
curl https://api.orbit.devotel.io/api/v1/channels/amb/agents \
  -H "X-API-Key: dv_live_sk_..."
```

The page for each agent opens at **Messages → Apple**, and the same list powers the dashboard table. Treat a long list as a misconfigured tenant — agents multiply only when you deliberately register several Apple businesses.

## 5. Status badges: poll until the agent is ready

The dashboard badge renders the agent's `status` field, and every read endpoint returns it:

| `status`    | Meaning                                                                       |
| ----------- | ----------------------------------------------------------------------------- |
| `pending`   | Registration saved — the agent exists but is not cleared for live traffic yet |
| `approved`  | Cleared — the agent can carry live AMB traffic                                |
| `suspended` | Taken down — re-register only after the issue is resolved                     |

A fresh registration starts at `pending`. To drive readiness from code, poll the list endpoint (or re-fetch the agent) until `status` flips to `approved`; poll against exponential backoff rather than a fixed short interval — the transition is Apple-side, not instant. If a status ever regresses — `approved` back to `pending`, or any agent moved to `suspended` — treat the agent as out of the routing set and delete or repair it before the next send; a regressed agent still occupies the tenant's routing registry until removed.

Known statuses are humanized on the badge as **In review**, **Approved**, **Suspended**; an unexpected future status renders its raw value rather than throwing.

## 6. Run AMB inside commerce

AMB is more than a support inbox — it is one of the channels that feed the [conversational checkout flow](/guides/conversational-commerce-checkout). A customer can tap into the thread from Apple Maps, add items into the **persistent cart**, and **check out on Apple Pay without leaving Messages**; the same cart is shareable across channels — an item added over WhatsApp and one over AMB land in one snapshot.

When you design the commerce entry point, register the agent first (this guide), then wire the checkout capability on top: the capability scan lists `amb` among the channels that can take payment natively, so the checkout surface can route the pay step down the AMB thread instead of falling back to a hosted pay-by-link.

## 7. Troubleshooting

| Symptom                                                     | Cause and fix                                                                                                                                                                                             |
| ----------------------------------------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `422` on create with a business\_id complaint               | The id contains characters outside Apple's identifier alphabet (`A–Z`, `0–9`, `: _ . - /`) — copy the id verbatim from Apple Business Register; do not add spaces or slashes a brand slug would carry.    |
| `422` on secret or a dashboard "secret too short" complaint | The HMAC key is shorter than 16 characters after decode — fetch the full base64 value from Apple Business Register and paste it whole; partial pastes look valid but fail the same check.                 |
| HMAC mismatch on inbound webhooks                           | The stored secret does not match the key Apple signs with — rotate via PATCH with the current key from Apple Business Register. The old key stops working the moment the new one is stored.               |
| Webhook payloads never reach the tenant                     | The agent's webhook routing entry is stale — confirm the agent still exists (`GET /channels/amb/agents`); a deleted agent drops routing, so re-register it to make the business resolvable again.         |
| Create succeeds but the agent never becomes routable        | `status` is still `pending` — poll until it flips to `approved`; a deleted-and-recreated agent restarts in `pending`.                                                                                     |
| Dashboard shows "no secret" for an agent created via API    | The create body omitted `secret_key` or sent an empty string — PATCH the agent with a valid key; the create endpoint accepts the field as required, but a partial-over-API body can still leave it empty. |
| `404` on PATCH or DELETE                                    | The `agentId` in the path is wrong — list agents first and use `data.id` (the opaque Orbit UUID), not the Apple `business_id`.                                                                            |
