---
id: "integrations/attribution/reference/singular"
title: "Singular Event Delivery Reference"
description: "Use this page when you need RevenueCat-specific details about Singular's Event Endpoint V1 and V2 delivery paths. For setup steps, see Singular."
permalink: "/docs/integrations/attribution/reference/singular"
slug: "docs/integrations/attribution/reference/singular"
version: "current"
original_source: "docs/integrations/attribution/reference/singular.mdx"
---

> **AI agents:** This is the Markdown version of a RevenueCat documentation page. For the complete documentation index, see [llms.txt](https://www.revenuecat.com/docs/llms.txt).

Use this page when you need RevenueCat-specific details about Singular's Event Endpoint V1 and V2 delivery paths. For setup steps, see [Singular](https://www.revenuecat.com/docs/integrations/attribution/singular).

Singular exposes two server-to-server Event API versions. RevenueCat routes each integration to the version you select in the dashboard. The version depends on your **Singular account eligibility**, not when you created the RevenueCat integration.

| Event API version | Version requirements | Required identifiers |
| :---------------- | :----------------- | :------------------- |
| **V2**            | Uses SDID-based delivery for Singular accounts created on or after July 15, 2026, and other SDID-enabled accounts. | `$singularDeviceId` customer attribute, sent as `sdid`. |
| **V1 (legacy)**   | Uses platform device identifiers for eligible legacy Singular accounts. | iOS uses `$idfa` and `$idfv`. Android uses `$gpsAdId` and/or `$androidId`. |

## Example Event Endpoint V2 request

RevenueCat sends V2 events as an `application/x-www-form-urlencoded` POST. The example below is shown as JSON for readability.

```json
{
  "headers": {
    "Content-Type": "application/x-www-form-urlencoded"
  },
  "body": {
    "a": "<singular_sdk_key>",
    "n": "<event_name>",
    "sdid": "<singular_device_id>",
    "p": "iOS",
    "i": "<bundle_id_or_package_name>",
    "amt": <usd_revenue>,
    "cur": "USD",
    "umilisec": <event_timestamp_ms>,
    "purchase_product_id": "<product_id>",
    "purchase_transaction_id": "<transaction_id>",
    "partner": "revenuecat",
    "att_authorization_status": <att_authorization_status>,
    "e": "{\"rc_app_user_id\":\"<app_user_id>\",\"pn\":\"\",\"pq\":<quantity>,\"pp\":<usd_revenue>,\"pk\":\"<product_id>\"}"
  }
}
```

V2 events require `sdid`. RevenueCat reads SDID from the `$singularDeviceId` customer attribute that your app sets with `setSingularDeviceID()`. RevenueCat doesn't derive SDID from `collectDeviceIdentifiers()`.

## Example Event Endpoint V1 request

RevenueCat sends V1 events as a GET request with query parameters. The example below is shown as JSON for readability.

```json
{
  "params": {
    "a": "<singular_sdk_key>",
    "n": "<event_name>",
    "p": "iOS",
    "i": "<bundle_id_or_package_name>",
    "idfa": "<idfa>",
    "idfv": "<idfv>",
    "amt": <usd_revenue>,
    "cur": "USD",
    "umilisec": <event_timestamp_ms>,
    "purchase_product_id": "<product_id>",
    "purchase_transaction_id": "<transaction_id>",
    "partner": "revenuecat",
    "att_authorization_status": <att_authorization_status>,
    "e": "{\"rc_app_user_id\":\"<app_user_id>\",\"pn\":\"\",\"pq\":<quantity>,\"pp\":<usd_revenue>,\"pk\":\"<product_id>\"}"
  }
}
```

On Android, RevenueCat sends `aifa` and/or `andi` instead of `idfa` and `idfv`. RevenueCat omits identifier parameters that aren't available on the customer.

## RevenueCat source to Singular request mapping

The table below covers fields shared by both versions unless noted.

| Singular request element | RevenueCat source and behavior |
| :----------------------- | :----------------------------- |
| Endpoint                 | Sends `POST` requests to `https://s2s.singular.net/api/v2/evt` when **V2** is selected, or `GET` requests to `https://s2s.singular.net/api/v1/evt` when **V1 (legacy)** is selected. |
| `a`                      | Uses the production or sandbox Singular SDK key configured in RevenueCat, based on the event environment. |
| `n`                      | Uses the event name configured in RevenueCat for the matching lifecycle event. |
| `sdid` (V2 only)         | Sends the `$singularDeviceId` customer attribute. RevenueCat doesn't create a V2 delivery attempt when SDID is missing. |
| `idfa`, `idfv` (V1 iOS) | Sends available iOS device identifiers collected through RevenueCat customer attributes. Both are required for standard iOS V1 delivery unless a project-specific exception applies. |
| `aifa`, `andi` (V1 Android) | Sends Google's Advertising ID and/or Android ID from RevenueCat customer attributes. At least one Android identifier is required for V1 Android delivery. |
| `p`                      | Sends `iOS` or `Android` based on the purchase platform. Amazon purchases report as `Android`. |
| `i`                      | Sends the app bundle ID or package name for the purchase. |
| `amt`, `cur`             | Sends USD revenue according to the integration's Sales Reporting mode and sends `USD` as the currency. |
| `umilisec`               | Sends the RevenueCat event timestamp in milliseconds. When **Report early renewals** is enabled, early renewals can use the occurrence time instead of the due time. |
| `purchase_product_id`, `purchase_transaction_id` | Sends RevenueCat product and transaction identifiers when available. |
| `ip` or `country`        | Sends the device IP when available; otherwise sends the subscriber's last-seen country for geo resolution. |
| `custom_user_id`         | Sends the RevenueCat app user ID when it isn't an anonymous RevenueCat ID. |
| `att_authorization_status` | Sends the customer's ATT consent status on iOS events. |
| `e`                      | Sends a JSON string of custom attributes, including RevenueCat context such as `rc_app_user_id`, product metadata for purchase events, and optional hashed user data when enabled for the project. Individual attribute keys and values longer than 500 characters are dropped. |
| `partner`                | Sends `revenuecat`. |

## Provider responses

Singular's EVENT endpoint returns **HTTP 200** for both accepted and rejected requests. Inspect the JSON response body to determine the outcome:

```json
{ "status": "ok" }
```

```json
{ "status": "error", "reason": "<error_reason>" }
```

The table below lists `reason` values that commonly appear when RevenueCat sends Singular events. See [Attribution troubleshooting](https://www.revenuecat.com/docs/integrations/attribution/troubleshooting) for setup fixes when you see these in Customer History.

| `reason` | Meaning in RevenueCat integrations |
| :------- | :--------------------------------- |
| `invalid api version: v1` | The Singular account requires Event Endpoint V2, but RevenueCat sent a V1 request. |
| `missing argument: sdid` | A V2 request was sent without the `sdid` parameter, usually because `$singularDeviceId` wasn't set before the event was processed. |
| `missing argument: n` | The configured event name for this lifecycle event is empty in RevenueCat. |
| `missing argument: a` | The production or sandbox SDK key for the event environment is missing in RevenueCat. |
| `no device ID supplied` | A V1 request was sent without the platform device identifiers Singular requires for that store. |
| `platform: iOS should have an idfv param` | A V1 iOS request is missing `$idfv`, or RevenueCat omitted it from the payload. |
| `platform: Android should have an {identifier} param` | A V1 Android request is missing `$gpsAdId` and/or `$androidId`, or RevenueCat omitted them from the payload. |

For the full Singular error catalog, see Singular's [Server-to-Server API response codes and errors](https://support.singular.net/hc/en-us/articles/31542603988379-Server-to-Server-API-Response-Codes-Errors).
