Resources
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
For developers and coding agents, before changing code:
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.Reproduce the problem and read the Reception logs of that launch. In Xcode, filter the console for
Reception. On a simulator:
xcrun simctl spawn <device> log show --last 2m --info --style compact --predicate 'subsystem == "com.reception.sdk"'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":
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 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:
Task { @MainActor in
Reception.shared.openChat()
}Use the complete notification examples in Push notifications when handling push payloads. See 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 and 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.
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.
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.
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.
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 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.
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.
Push notifications do not arrive
Verify all three parts of push setup:
The host app has push capability and appropriate signing, registers with APNs through its existing flow, and passes the nonempty token to
Reception.shared.setPushTokenafter configuration.The app's Apple Push settings contain the matching bundle identifier, Key ID, Team ID, and private key.
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.
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.
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.
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.
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.
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 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.
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. 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 and 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 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 and 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 and Privacy and data.
Get help
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. These details are optional when asking for help.
Remove tokens, secrets, private keys, signed image URLs, and customer message content from details you share.