<!-- AI agents: this is the Markdown version of a Reception documentation page. Index: /llms.txt -->

# Troubleshooting

Find the symptom you see, check the relevant configuration, and verify the result with a real chat. These checks apply to the current ReceptionKit SDK and Reception's hosted service.

## Check first {#check-first}

For developers and coding agents, before changing code:

1. Find `Reception.configure(appId:)`. It runs once at launch on the main actor, before other Reception calls, with the App ID from **Settings → Apps → your app → Setup**.
2. Reproduce the problem and read the Reception logs of that launch. In Xcode, filter the console for `Reception`. On a simulator:

```sh
xcrun simctl spawn <device> log show --last 2m --info --style compact --predicate 'subsystem == "com.reception.sdk"'
```

3. If messages don't arrive, run the setup check in a Debug simulator build, signed as Xcode normally signs it. It sends one real message, "Hello from setup":

```sh
xcrun simctl launch --terminate-running-process <device> <bundle identifier> -ReceptionSetupCheck <App ID>
```

Read the logs every 10 seconds, for up to 70 seconds. Only a result from this launch counts.

| Result | Meaning |
| --- | --- |
| `Setup check passed` | Reception received the message. |
| `Setup check failed: app_id_mismatch` | The app configures a different App ID than the one you passed. Check which one is right in the dashboard. |
| `Setup check failed: send_not_allowed` | Sending is blocked, for example because only verified users may chat or the device is blocked. |
| `Setup check failed: not_delivered` | The ReceptionKit lines before it name the reason. |
| `Setup check failed: app_not_active` or `timeout` | The app didn't reach the foreground, or Reception didn't answer. |
| No result | The check didn't start: the build isn't a Debug simulator build, or `configure` didn't run. |

The setup check proves only that messages reach Reception. Check the Support button, colors, user details and push on their own. Don't use `logout()` or `deleteData()` to fix a connection problem.

## Chat does not open

`Reception.shared.openChat()` presents the SDK chat sheet over the current screen. Configure Reception before calling it. An entry point such as a settings row or floating button belongs to your app.

If your app presents `ReceptionChatView()` itself, use your own sheet binding or navigation state to open and dismiss it. `Reception.shared.openChat()` and `Reception.shared.closeChat()` control only the SDK-owned sheet.

Check [Entry point](/docs/entry-point) for both presentation patterns. Verify that tapping your entry point shows the chat and that `Reception.shared.isChatOpen` becomes true while it is visible.

## Swift reports a main actor isolation error

The `Reception` facade and `ReceptionChatView` are main-actor isolated. Call SDK APIs from main-actor code. Notification delegate callbacks may need to hop to the main actor; preserve your existing delegate and completion handling.

For a callback that only needs to request presentation, this belongs inside the host app's callback implementation:

```swift
Task { @MainActor in
    Reception.shared.openChat()
}
```

Use the complete notification examples in [Push notifications](/docs/push-notifications) when handling push payloads. See [SDK reference](/docs/sdk-reference) for the public API surface.

## No user or conversation appears in the dashboard

Configuration, identification, metadata updates, and opening an unused chat do not register a new device. Reception starts registration on the first valid send attempt; the first successful message creates a conversation. Fetching remote appearance can happen before this and does not prove registration succeeded.

Send a short message and confirm it reaches Sent. Then check the dashboard's organization, selected app, search, status, and development-device filters. A registered device without a successful message is not a completed chat setup. See [Get started](/docs/get-started) and [Dashboard](/docs/dashboard).

## The first message fails or the chat stays connecting

Check that `Reception.configure(appId:)` ran before SDK use, with the App ID of the intended app from **Settings → Apps → your app → Setup** in the dashboard.

Your simulator and development iPhone connect to the same hosted Reception service, which uses HTTPS in production. Check the device’s internet connection and copy the setup snippet again if needed; replace only the App ID in public documentation examples. See [Get started](/docs/get-started).

An available network doesn't mean chat is connected. Offline and connecting states reflect different conditions. For a previously used chat, keep the app foregrounded and the chat open while restoring connectivity; ReceptionKit reconnects and attempts supported retries automatically. The connection status is hidden for an unused chat.

If the problem persists, tell us what happens when you send a message and any error message you see. You do not need to find an HTTP status or internal error code. A wrong App ID requires updating configuration. Do not use logout or data deletion as a network repair: they change the support session. See [Chat features](/docs/chat-features).

Use the App ID shown in the dashboard. After correcting configuration, relaunch and retry. If the app was deleted or Reception reports it unavailable, contact us; retries cannot restore a deleted app.

## Send is disabled or a message cannot be sent

An empty or whitespace-only message without photos cannot be sent. Wait for photo loading to finish, keep at most five photos, and keep text within 4,000 characters; some emoji count as two.

If the chat says sending is unavailable, inspect the device's blocked state in the dashboard. Blocking prevents customer messages and uploads while retaining access to history. A team member must unblock the device; retrying does not bypass the block. The open chat updates when it synchronizes after unblocking; the draft remains unsent.

For a failed message, use its Retry action after addressing the cause. For a temporary sending limit, follow the chat's waiting notice and retry when it's available; repeated taps don't shorten the wait. See [Chat features](/docs/chat-features).

## The chat asks the customer to sign in

"Sign in to send messages." replaces the composer when your app requires verified users and Reception reports that this device is unverified. The customer can still read any existing conversation. Call `Reception.shared.identify(token:)` after sign-in and on every launch while a user is signed in, and check your event handler for `identityRejected`. To let everyone chat again, turn off **Only verified users can chat** in the dashboard. See [Identity verification](/docs/accounts#only-verified).

## Photos fail while text works

“Could not load this photo.” means ReceptionKit could not read or decode a selected photo. Select another photo that the device can load and wait for processing to finish before sending.

Photo uploads use storage managed by Reception. Check the device's internet connection, then retry the failed message. If it still fails, try a small photo. Tell us whether text messages work, what happens when you send the photo, and any error message you see. You do not need an upload error code. The SDK's picker, image preparation, upload, and message send are separate steps; successful text delivery does not verify photo delivery.

See [Chat features](/docs/chat-features#photos) for photo behavior and limits.

## Unread counts or app badges look stale

Unread monitoring starts with `Reception.configure(appId:)`. The SDK does not poll an unused support session. After support has started, foregrounding refreshes the device and unread state. Opening the chat marks messages read when the server request succeeds; unread checks alone do not mark messages read.

Automatic unread checks run for recently active, open conversations while your app is foregrounded and chat is hidden. They pause when push is configured and notification permission is available. Reception manages the schedule; see [Unread messages](/docs/unread-messages#refresh-timing).

If your host manages the icon badge, set `Reception.shared.updatesAppBadge = false` and implement its combined badge policy. This also disables ReceptionKit's removal of delivered support notifications when the count reaches zero. It does not disable the observable `Reception.shared.unreadCount`. See [Unread messages](/docs/unread-messages).

## Push notifications do not arrive

Verify all three parts of push setup:

1. The host app has push capability and appropriate signing, registers with APNs through its existing flow, and passes the nonempty token to `Reception.shared.setPushToken` after configuration.
2. The app's Apple Push settings contain the matching bundle identifier, Key ID, Team ID, and private key.
3. A real device has started support and reported a token and environment. Check its push state and any rejection reason in the dashboard.

The default `.automatic` environment reads the provisioning profile on a device; it skips registration if it cannot resolve the environment and returns no environment on the simulator. An explicit `.sandbox` or `.production` override is available when automatic detection is unsuitable, but it must match the token's actual environment.

A successful simulator chat does not verify APNs delivery. Verify on a real device with notification permission, then test a reply with the app backgrounded. Inspect any reported APNs rejection instead of changing environments at random. See [Push notifications](/docs/push-notifications).

## A push tap does not open chat, or foreground pushes interrupt it

Forward the notification's `userInfo` to `Reception.shared.handlePushNotification`. A recognized payload must contain a `reception` dictionary with a nonempty string `conversationId`. The return value means the payload was recognized; it does not prove the conversation was displayed or delivered.

Use `openChat: false` for foreground receipt and the default `true` for a notification tap. A tap presents the SDK sheet, including after a cold start. The host decides whether to show foreground notification banners; `Reception.shared.isChatOpen` can inform that decision. Keep routing unrecognized notifications through your existing handling. See [Push notifications](/docs/push-notifications).

## Identity or metadata is missing or belongs to the previous account

Configure before calling `identify` or `setMetadata`; calls before configuration have no session to update. Supply identity again after login and after `Reception.shared.logout()`. Identification labels the current device; it does not authenticate your app's user or merge their other devices.

Metadata values must be strings. `setMetadata` replaces the pending metadata dictionary, so pass the complete intended set. Updates are synchronized through SDK device-update activity; changing pending identity alone does not register a new device or guarantee an immediate dashboard change. See [Identity](/docs/accounts#metadata).

Call `Reception.shared.logout()` when switching away from an account, before identifying the next account. Logout clears local support state and starts a fresh device session on later use; it does not delete the previous server records. See [Login and logout](/docs/accounts#sign-out).

## A customer shows as Unverified

**Unverified** appears in the conversation header and customer details when the app sent a name, email, or user ID without an accepted token. Guests without those fields show no badge. For Owners, its tooltip links to the app’s identity verification section with its setup prompt. Check that your app passes a fresh token to `identify(token:)` after sign-in and on every launch. If Reception rejected the token, your event handler receives `identityRejected` with the reason. See [Identity verification](/docs/accounts#troubleshooting).

## Local colors, fonts, or text are ignored

Remote appearance is enabled by default. Published remote fields can override corresponding local appearance fields. Check the intended app's published configuration. For an app that should use only local values, set `Reception.shared.usesRemoteAppearance = false`.

A custom `fontFamily` takes precedence over `fontDesign`. Verify the font is bundled and registered in the host app, and pass the registered font name used with SwiftUI’s `Font.custom`. Host-supplied text remains host-owned and is not automatically translated. See [Appearance](/docs/appearance) for all 14 properties and their defaults.

## Published appearance does not change an open chat

Saving a draft is different from publishing it. Confirm publication, then keep the configured app active for a refresh and open the chat again. Appearance updates are automatic; reopening does not force a download. A newly fetched snapshot is activated at the next opening so an already visible chat does not restyle midway through a conversation.

Offline or failed refreshes retain the cached appearance. Also verify that `Reception.shared.usesRemoteAppearance` is true and that the App ID matches the app you edited and the configuration matches dashboard setup. See [Remote appearance](/docs/remote-appearance).

## Chat, push, or review text uses an unexpected language

Without an override, ReceptionKit follows the host app's selected localization, not a separate scan of the device's preferred languages. If your app has its own language picker, set `Reception.shared.languageOverride` at startup and whenever the choice changes. Set it to `nil` to restore automatic selection.

Unsupported or invalid identifiers fall back to English; supported regional and script variants follow the matching rules in [Language](/docs/language). Changing the dashboard preview language edits or previews that translation; it does not change a customer's selected language.

The server uses the last successfully reported app language for push and review templates. Offline changes can therefore take time to appear there. Existing messages and notifications are not translated retroactively, and custom host text needs host localization.

## Review requests are unavailable or a review is not recorded

Set the app's numeric App Store ID before sending a review card, reopen closed conversations before replying, and remove attachments from a review draft. Repeating a review request shows a warning that asks you to type **send review**. Reset support does not clear the retained device's review-request history.

If the recipient's language changed while a review draft was open, review the prompt to retain your text or use the current template before sending. A click receipt or `.reviewOpened` event records a review-link action, not submission of an App Store review. See [Reviews](/docs/reviews) and [Events](/docs/events).

## Telegram notifications arrive but replies do not

Use Telegram's Reply action on a recent support notification in the configured chat. Plain text replies are supported; media, edits, forwarded messages, bots, and anonymous senders are not. Check that the notification targets the device's latest conversation, and reopen that conversation in the dashboard if it is closed. A reply to a reopened historical thread can be saved without appearing in the customer's current chat.

Check that the integration is enabled and the bot is dedicated to Reception. Outgoing notification delivery alone does not verify replies. Connecting the same bot to another service can divert replies. If the connection still fails, contact the Reception team with the app and failure time. See [Telegram](/docs/telegram) for setup and verification.

## History disappears after reset or authentication failure

An owner reset clears cached chat state, and the next send starts support again. The SDK also clears the local session when the service no longer accepts its session, for example after the device was deleted in the dashboard. Check whether someone reset support or deleted the device or app before assuming the history was lost through connectivity alone.

Session credentials stay on the device where they were created and do not move with a backup. After someone restores a backup onto a new iPhone, support starts there with a new, empty chat; the earlier conversation remains in your inbox.

Logout also starts a new local device session. Reusing the same external user ID does not restore an earlier device's history. See [Login and logout](/docs/accounts#sign-out) and [Privacy and data](/docs/privacy-and-data).

## Data deletion fails or old records remain

When an account is deleted, await `Reception.shared.deleteData()` instead of calling logout. If deletion fails, the SDK throws `ReceptionError` and preserves local state so you can retry with the current session. Its public `code` and `status` properties help with diagnostics. A status of `0` means no usable HTTP response; inspect `code` as well. `delete_failed` means deletion could not complete; some data may already have been removed.

Do not call logout in a deletion failure handler if you intend to retry. Completion can be local only when there is no stored session, the session has ended, or the App ID is unavailable. It does not prove that earlier server records were erased. After logout, delete the retained device in the dashboard. The API deletes only the current device's support data; it does not find every device sharing the external user ID. See [Delete data](/docs/accounts#delete-data) and [Privacy and data](/docs/privacy-and-data).

## Get help {#collect-a-useful-diagnostic-report}

Something not working? Write to us in the Support chat. We're happy to help. Briefly describe what happens and any error message you see.

Start with what you tried and what happened instead. For example: “Text messages reach Sent, but a photo stays failed after Retry.” If there is no error message, describe the visible state. You do not need technical logs or error codes to ask for help.

If you have them, the app name, approximate time, app/iOS versions, and whether you used a simulator or iPhone can help us investigate. Include relevant presentation or language settings only when they relate to the problem.

### Optional developer details

For a failed `deleteData()` call, you can include its public `ReceptionError.code` and `status`; see [SDK errors](/docs/sdk-reference#reception-error). These details are optional when asking for help.

Remove tokens, secrets, private keys, signed image URLs, and customer message content from details you share.
