Skip to main content

Send first-party events

Use the SpendDaddy API when your backend sends subscription and attribution events directly instead of using RevenueCat.

Before you start

Choose SpendDaddy API while adding your app, then copy the generated API key into a server-side secret store.

Never embed this key in a mobile app or other downloadable client. Anyone with the key can send events for the connected app.

All requests use:

Authorization: Bearer <spenddaddy_api_key>
Content-Type: application/json

The base URL is https://api.spenddaddy.app.

Identify an install

Call POST https://api.spenddaddy.app/identify when your backend first sees an app user. Send the same stable user ID you will use for later events.

curl https://api.spenddaddy.app/identify \
--request POST \
--header "Authorization: Bearer $SPENDDADDY_API_KEY" \
--header "Content-Type: application/json" \
--data '{
"appUserId": "user_123",
"installedAt": "2026-07-17T12:34:56Z",
"asaToken": "optional_apple_ads_attribution_token"
}'
FieldRequiredDescription
appUserIdYesStable identifier for this app user.
installedAtNoInstall time in ISO 8601 format. Defaults to the time SpendDaddy first sees the user.
asaTokenNoApple Ads attribution token obtained by your app and forwarded to your backend.

Example response:

{
"status": "identified",
"created": true,
"attribution": "fetched"
}

created is true when SpendDaddy created the app user. attribution is fetched, failed, or not_requested depending on whether an Apple Ads token was supplied and resolved.

Send an event

Call POST https://api.spenddaddy.app/event for trials, purchases, renewals, refunds, and cancellations.

curl https://api.spenddaddy.app/event \
--request POST \
--header "Authorization: Bearer $SPENDDADDY_API_KEY" \
--header "Content-Type: application/json" \
--data '{
"appUserId": "user_123",
"eventType": "initial_purchase",
"occurredAt": "2026-07-17T12:40:00Z",
"eventId": "evt_01",
"transactionId": "txn_01",
"productId": "monthly_pro",
"amount": 9.99,
"currency": "USD",
"store": "app_store",
"country": "US"
}'

Event fields

FieldRequiredDescription
appUserIdYesThe same stable user ID used with /identify.
eventTypeYesOne of the supported event types below.
occurredAtYesEvent time in ISO 8601 format.
eventIdRecommendedUnique event identifier used to safely update a previously received event.
transactionIdRecommended for purchasesStore transaction identifier.
renewalNumberNoRenewal sequence number when available.
productIdNoSubscription or product identifier.
amountRequired for revenue eventsPositive revenue amount. Send refunds as a positive amount; SpendDaddy applies the negative sign.
currencyRecommended for revenue eventsThree-letter currency code. Defaults to USD when omitted.
storeNoStore that processed the event, such as app_store.
countryNoTwo-letter country code when available.

Supported event types

Event typeRequires amount
trial_startedNo
trial_convertedYes
initial_purchaseYes
non_renewing_purchaseYes
renewalYes
refundYes
cancellationNo

Example response:

{
"status": "ingested",
"created": false
}

Here, created indicates whether SpendDaddy created the app user while processing the event. It does not indicate whether the event was new.

Retries and duplicate events

Provide a stable eventId or transactionId whenever possible. If a request times out, retry it with the same identifiers and payload so SpendDaddy can recognize the existing event.

Errors

StatusMeaningWhat to do
400Unsupported event type, missing revenue amount, or invalid amount.Correct the request body and retry.
401Missing, invalid, disabled, or rotated API key.Confirm the bearer token or rotate the key in SpendDaddy Settings.
422A required field is missing or has an invalid format.Compare the request with the field tables above.

Rotate the API key

Open the app in SpendDaddy, go to Settings > First-party attribution API, and choose Rotate API key.

Rotation invalidates the previous key immediately. Update the server-side secret used by every event sender before sending more requests.