An events and costs API for your app's server

Send page views, app screens, events and costs from your own backend, in one JSON shape. No new app build and no store review: your server already knows who it serves.

MRR · all 5 projects
€3,562
from
+12.9% in 30 days
Last 30 days €4,146 net
In apps 21%On sites 79%
Just came in
  • TimeLoop App Store · in the app · via RevenueCat 🇪🇸 +€4.99
  • Humanize Stripe · on the site 🇯🇵 +€11.04
  • AstroChart Google Play · in the app 🇫🇷 +€9.99
  • AstroChart Stripe · on the site 🇸🇬 +€9.99

The live demo: our own apps, with example numbers.

Sending in three steps

Two keys per project. The public one sends events; the secret one, kept on a server, sends events and costs.

  1. 1

    In Sumly, open Visitors › App users and make the project's secret key (sk_sumly_…). It is shown once: put it in your server's environment as SUMLY_KEY.

  2. 2

    Send POST /api/v1/events with the key as a Bearer token, up to 1,000 events in one call.

  3. 3

    Check the key with GET /api/v1/ping, then see the events arrive on the project's Sources list.

One event or many under "events". type is page, screen or track; user_id is the person, the same id RevenueCat knows.

POST https://sumly.dev/api/v1/events
Authorization: Bearer sk_sumly_…

{
  "events": [
    {
      "type": "screen",
      "screen": "Paywall",
      "user_id": "tl-48213",
      "platform": "ios",
      "app_version": "2.4.0",
      "country": "DE",
      "at": "2026-11-03T10:02:00Z"
    },
    {
      "type": "track",
      "name": "trial_started",
      "user_id": "tl-48213",
      "platform": "ios",
      "props": { "plan": "yearly" }
    },
    {
      "type": "page",
      "url": "https://example.com/pricing?utm_source=newsletter",
      "referrer": "https://news.example.org/",
      "user_id": "tl-48213"
    }
  ]
}

200 { "ok": true, "kept": 3, "refused": [] }

What you see after connecting

Server API next to every other project and provider, on the same pages.

App users

Who is in your app each day, on which platform and from where, and how many of them pay.

Visitors

Screens and pages next to your website's visits, with sources and campaigns.

Funnels and paths, from the first screen to the purchase.

Costs sent from your server, against revenue for profit and ROI.

Screens and purchases, one person

Send the same user_id that RevenueCat knows as the app user id (the one you give Purchases.logIn), and a person's screens and their purchases meet: each payment shows the source and campaign of the first event Sumly kept for them.

How attribution works →

Counts toward your plan

Each page and screen event Sumly keeps counts toward your plan's visits for the month. Track events and costs do not. Plans →

What you don't get

No revenue through the API and no data sent back to your app: Sumly only takes what you send.

The details

What an event carries
  • type: page (a web page, with its full url), screen (an app screen) or track (something done, with a name)
  • user_id: the person, up to 55 letters, digits or _ . : -; use the id RevenueCat knows as the app user id
  • at: when it happened, as an ISO time or milliseconds; left out, it is now
  • platform (web, ios, android, mac, windows, watch), app_version, country, referrer and utm
  • props: a few properties on a track event, such as the plan
What happens to a call
  • Each event is checked on its own. The good ones are kept and the reply lists the refused ones, with their place in the list and why.
  • An event dated more than a week back, or in the future, is kept at the moment it arrives.
  • An app screen's source is your utm source, else the App Store or Google Play by its platform; a page's is its referrer or utm.
  • With the secret key, the country is what you send: Sumly does not take it from your server's address.
  • A call that keeps nothing (a wrong key, a body that does not read, the plan's limit) shows on the Sources list for a day and is kept 30 days.
Good to know
  • At most 1,000 events or costs in one call.
  • The public key (sl_…) can send events only. Costs with it are refused with 403.
  • Revenue does not come this way. It comes from your payment providers, which are its source of truth.
  • Anonymous RevenueCat ids ($RCAnonymousID) do not meet their purchases: log people in with your own id.

Server API questions

Which key do I use?

On a server, the secret key (sk_sumly_…): it sends events and costs. The public key (sl_…, the one in the site line) may sit in a browser or an app, so it can send events only.

What if one event in a batch is wrong?

The rest are kept. The reply says how many were kept and lists up to 20 refused ones with their index and the reason, such as a track event without a name.

Why the same id as RevenueCat?

Sumly reads purchases from RevenueCat by the app user id. When your events use the same id, a person's screens and their payments are one person, and revenue shows where they came from.

Can I send the same cost twice?

Yes, safely. The id you give a cost is its own: sent again it updates that cost, never adds a second one. DELETE /api/v1/costs/{id} removes it, for a cancelled payout.

Where do I see what went wrong?

On the project's Sources list: each source shows when it last sent, how many in the last 24 hours, and how many calls were refused.

How do I stop a key?

On Visitors › App users, press Stop next to the project, or New key to replace it. The old key stops at once.

Other integrations

Try it with your own projects

Sign in with Google or a code by e-mail and connect your first project. Free for one project, and 14 days of a paid plan with no card.

Start free

Or look around first: open the live demo.