> ## Documentation Index
> Fetch the complete documentation index at: https://developers.telnyx.com/llms.txt
> Use this file to discover all available pages before exploring further.

# Push Notification Debugging

> Use the Telnyx Portal's Push Notification Debugging tool to test, diagnose, and troubleshoot push delivery for WebRTC SDK incoming calls on iOS and Android.

## Overview

The Push Notification Debugging tool in the Telnyx Portal lets you test whether push notifications are being delivered to your devices and diagnose why they might fail. It provides a single interface to:

* Send test push notifications to specific devices
* View push delivery metrics (accepted, throttled, rejected)
* Browse a delivery log with detailed failure reasons
* Check credential health (VoIP certificate expiry, FCM configuration)

<Callout type="info">
  The tool requires a SIP Connection with push credentials configured. See the [Push Notifications Overview](/docs/voice/webrtc/push-notifications) for setup instructions.
</Callout>

## Prerequisites

Before using the debugging tool, you need to prepare the following:

1. A [Telnyx account](https://portal.telnyx.com) with a configured SIP Connection
2. Push credentials created for your platform:
   * **Android**: Firebase Cloud Messaging service account JSON ([Android setup](/docs/voice/webrtc/push-notifications/android))
   * **iOS**: VoIP certificate PEM files ([iOS setup](/docs/voice/webrtc/push-notifications/ios))
3. At least one device that has logged in with the Telnyx WebRTC SDK and registered a push token

## Using the tool

The tool is available at [portal.telnyx.com/#/debugging/push](https://portal.telnyx.com/#/debugging/push). It is divided into four sections:

* **Push credential status** — Check the health of your iOS and Android push credentials
* **Test push** — Send a test push notification to a registered device
* **Delivery log** — Browse recent push delivery attempts with status and failure reasons
* **Push metrics** — View aggregate push statistics (accepted, throttled, rejected)

### Push credential status

This section shows the health of your push credentials for both iOS and Android.

First, use the **Connection** dropdown at the top to select which SIP Connection's credentials and devices to debug. If you have multiple SIP Connections, each may have its own push credentials.

Once a connection is selected, the credential status panels display:

* **iOS**: Shows your VoIP certificate status, including expiry date. A warning appears 30 days before expiry. An expired VoIP certificate is a common cause of silent push failures.
* **Android**: Shows your FCM service account configuration status.

<Callout type="warning">
  An expired iOS VoIP certificate will cause all push notifications to fail silently. Renew your certificate before it expires to avoid downtime.
</Callout>

### Test push

The test push panel lets you send a real push notification to a registered device.

1. **Select a device** from the list. Each device shows its platform (iOS/Android), device ID, and last registration time. Devices without a valid push token are marked with a "No token" badge — these need a foreground login before they can receive test pushes.

2. **Enable ringing tests** (if needed). To receive a "Ring device" push, the device must be marked as a diagnostic device. Click "Enable ringing tests" on the device row. This flag permits test pushes to ring the handset.

3. **Choose the environment**:
   * **Use stored**: Uses the environment stored with the device's push token
   * **Sandbox**: Sends via the APNS sandbox (iOS only)
   * **Production**: Sends via the production push service

4. **Choose the mode**:
   * **Silent ack**: Sends a silent push that the SDK acknowledges without ringing the device. Useful for verifying credential and token validity.
   * **Ring device**: Sends a push that rings the device like an incoming call. The device must have ringing tests enabled.

5. **Click Send**. The result appears below the send button.

<Callout type="info">
  There is a cooldown between test pushes to prevent abuse. Wait for the cooldown timer to finish before sending another test.
</Callout>

### Test push results

After sending a test push, the result panel shows:

* **Status chip**: Accepted, Delivered, Throttled, Rejected, or Failed
* **voice\_sdk\_id**: The SDK session identifier for this push attempt (copyable for support tickets)
* **Environment**: Which push environment was used
* **Diagnosis**: When a push fails, the panel displays a detailed breakdown:
  * **What happened**: A plain-language description of the failure
  * **Why**: The root cause explanation
  * **How to fix it**: Actionable steps to resolve the issue
  * **How to confirm it worked**: How to verify the fix

### Delivery log

The delivery log table shows recent push delivery attempts for the selected connection.

| Column | Description |
| - | - |
| Occurred At | When the push was processed |
| Sent At | When the push was sent to the provider |
| Platform | iOS or Android |
| Environment | Sandbox or Production |
| PN Status | Delivery status (Accepted, Delivered, Failed, Throttled, Rejected) |
| Reason | Failure reason code (if applicable) |

**Filters**: Filter by Call ID, Parent Call ID, Device ID, or Voice SDK ID to narrow down specific calls.

Click any row to see full delivery details, including the failure diagnosis with "What happened", "Why", "How to fix it", and "How to confirm it worked" sections.

### Push metrics

The metrics panel shows aggregate push statistics for the selected connection:

* **Accepted**: Pushes successfully accepted by Apple/Google
* **Throttled**: Pushes rate-limited by the provider
* **Rejected**: Pushes rejected by the provider (bad token, expired cert, etc.)

Metrics are shown for the last 7 days with a daily breakdown chart.

## Common failure reasons

| Reason code | Platform | Meaning | Fix |
| - | - | - | - |
| `UNREGISTERED` / `NOTREGISTERED` | Both | Device token is stale or the app was uninstalled | Reinstall the app and perform a foreground login to register a new token |
| `INVALIDREGISTRATION` | Android | FCM token is malformed | Ensure the FCM token is retrieved correctly from `FirebaseMessaging.getInstance().token` |
| `SENDERIDMISMATCH` | Android | FCM project ID doesn't match the service account | Verify the Firebase project in the service account JSON matches the app's `google-services.json` |
| `BADCERTIFICATE` | iOS | VoIP certificate is invalid | Regenerate the certificate from the Apple Developer Portal |
| `BADCERTIFICATEENVIRONMENT` | iOS | Certificate environment mismatch (sandbox vs production) | Ensure the certificate matches the environment selected in the tool |
| `CERTIFICATEEXPIRED` | iOS | VoIP certificate has expired | Renew the certificate and upload the new PEM files to the portal |
| `BADTOPIC` / `DEVICETOKENNOTFORTOPIC` | iOS | Bundle ID mismatch between certificate and app | Verify the app's Bundle ID matches the certificate's topic |
| `TOPICDISALLOWED` | iOS | Certificate is not a VoIP certificate | Use a VoIP Push Certificate, not a standard APNS certificate |
| `TOOMANYREQUESTS` | iOS | APNS rate limit exceeded | Wait and retry. If persistent, contact support |
| `QUOTAEXCEEDED` / `RESOURCEEXHAUSTED` | Android | FCM quota exceeded | Check your Firebase project quotas in the Firebase Console |

## Invalidating a stale token

If a device has been uninstalled or the push token is no longer valid, you can invalidate it:

1. Find the device in the device list
2. Click "Invalidate token" on the device row
3. Confirm the action in the dialog

This marks the token as invalidated. The device will need to perform a foreground login to register a new token.

<Callout type="warning">
  Invalidating a token is irreversible. The device must re-register by logging in with the SDK to receive push notifications again.
</Callout>

## Troubleshooting checklist

If push notifications are not reaching your device, work through this checklist:

1. **Credential health**: Check the credential status panel for expired certificates or misconfigured FCM
2. **Device registration**: Ensure the device appears in the device list with a valid token (not "No token")
3. **Ringing tests**: For "Ring device" mode, ensure the device has ringing tests enabled
4. **Environment**: Verify the environment matches your app's build configuration
5. **Test push**: Send a "Silent ack" push first — if it fails, the credential or token is wrong. If it succeeds but "Ring device" fails, the issue is on the device side
6. **Delivery log**: Check the delivery log for specific failure reason codes
7. **On-device**: Verify notification permissions are granted (Android 13+: `POST_NOTIFICATIONS`), the app is not in Doze mode (Android), and PushKit is initialised (iOS)
