Pull conversions instead (Reporting API)
Call GET / with your publisher API key. It returns the conversions on your account in the window you ask for (the last 90 days if you send no dates), newest first, under the same action_id your postbacks carry, so you can reconcile against what your server received or catch up after downtime.
See also: Signed postbacks
On this page
Postbacks stay the realtime path: a pull only shows what happened before you called. Use it next to postbacks, not as the only way you credit users, unless a few minutes’ delay is fine for you.
- A publisher API key. An owner or admin creates it under My Profile, then API Keys, with Generate Key. It starts with
pk_and is shown once. - Networks: network keys read offers only, so there is no pull endpoint for them today. Use postbacks, and Download CSV under Reporting, then Offer Performance.
Call GET /publisher/conversions
Send the key in the
x-api-keyheader.fromandtoare ISO-8601 timestamps; a date alone, such as2026-10-29, means midnight UTC at the start of that day. Leave both out and you get the last 90 days.curl -G "https://affiliateos.xyz/publisher/conversions" \ -d from=2026-10-29T00:00:00Z \ -d to=2026-10-30T00:00:00Z \ -d limit=500 -d page=1 \ -H "x-api-key: $PEBBLE_PUBLISHER_KEY"Example response, one row, for Pebble Rewards:
{ "data": [ { "actionId": "act_5Kq2Wc", "offerId": "aff_7c2e91b04d3a", "offerName": "Harbor Blocks", "conversionName": "Install", "subId": "u_48213", "status": "completed", "partnerPayoutUsd": 4.2, "userPayoutUsd": 1.5, "reversalReason": null, "country": "US", "createdAt": { "_seconds": 1793300980, "_nanoseconds": 0 }, "clicktimestamp": "2026-10-29T19:06:00Z", "reversedAt": null } ], "pagination": { "page": 1, "limit": 500, "total": 1 } }partnerPayoutUsdis what we pay you for the step.userPayoutUsdis the player’s reward. AddofferIdto the query to read one offer.Page through the window
limittakes 1 to 500 (50 if you leave it out) andpagestarts at 1. Keep asking for the next page untilpagetimeslimitreachespagination.total.Match each row on actionId and status
actionIdis the same value as the postback’saction_id. Store rows underactionIdandstatustogether, as you do for postbacks:completed: the conversion. Credit it if your server never got its postback.reversed: taken back.reversalReasonsays why when we have a reason, andreversedAtsays when the reversal came in.createdAtstays the time of the conversion.rejected: a user our traffic checks blocked. It pays $0 and sends no postback. Held or rejected traffic explains it.
On the Hosted Offerwall,
subIdis theuidyou opened the wall with. For conversions first sent before 10 September 2026, the postback’saction_idcan be longer than the report’sactionId: match those on the end of the ID.Check it worked
Send your own test user through one offer, wait for the postback, then pull the same hour. The row shows your test user’s
subId, and itsactionIdequals theaction_idyour server logged.
| Endpoint | What it returns |
|---|---|
GET / | Conversions and payout per UTC day. from and to are dates (2026-10-01); the last 90 days by default. status=all also counts reversed rows as conversions; the money is the same. |
GET / | The dashboard’s numbers, grouped by day, week, month, quarter, year, offer, platform or country with groupBy, between startDate and endDate. |
GET /publisher/stats | Lifetime clicks, conversions, events and earnings for each offer. |
GET / | Users whose conversions are rejected right now, with the reason and when it expires. |
Payout in every report is net of reversals, and every reversal is dated on its conversion’s day. Why our numbers and yours differ covers what that does to a closed week.
- Nothing is pushed. You see a conversion on your next call, not when it happens.
- No signature to check. Your key proves who you are. Keep it on your server.
- No secret needed to pull. Without a postback secret, we send no postbacks, but every conversion still counts and still shows here.
- Some conversions wait. A conversion waiting for our review doesn’t appear until it’s approved.