SharklioSharklioDocs Support Log in

DocsIntegration

Reporting API

Pull your clicks, conversions, and earnings into your own dashboards, and check every transaction against the postbacks you received.

The Reporting API gives you the numbers from your dashboard as JSON: statistics for any period, grouped the way you need, and the full list of transactions. Use it to build your own reports, to compare traffic sources, and to check that you received a postback for every transaction.

Authentication

Use the same API key as for the Offers API. You find it in your dashboard under Apps, your app, Integration. Send it in the Authorization header:

Authorization: Bearer shk_your_api_key

Call the API from your server only. Each key only returns data of its own app. Reports work for apps that are live, paused, or still in testing.

Dates and time zone

All dates and times are in Budapest time (Europe/Budapest, CET or CEST), the same as in your dashboard. from and to are whole days in YYYY-MM-DD format, and both are included. Without them you get the last 30 days up to today. One request can cover up to 92 days: split longer periods into several requests.

A transaction belongs to the day it was created, even if it was credited or reversed later. Timestamps in responses are ISO 8601 with the offset, for example 2026-09-23T23:59:49+02:00.

Statistics

GEThttps://api.sharklio.com/v1/stats
Query parameterDescription
fromoptionaldate, YYYY-MM-DDFirst day, in Budapest time. Defaults to 29 days before to.
tooptionaldate, YYYY-MM-DDLast day, in Budapest time. Defaults to today.
group_byoptionalstringday (default), country, offer, integration, or sub1 to sub5. integration is embed, button, link, or api: how the user reached the offer. With day, every day of the period has a row, even without activity. Other groups are sorted by earnings, highest first.

Every row has these fields. The totals object has only the counts (clicks, credited, pending, rejected, reversed), payout_usd, and reward.

FieldDescription
day, country, offer, integration, or sub1 to sub5The group of the row, named after group_by. It is null for traffic without a value, for example clicks without sub1. With offer, the row also has offer_name.
clicksOffers your users started.
credited, pending, rejected, reversedTransactions in each state right now. A transaction that was credited and later reversed counts as reversed.
payout_usdYour earnings from credited transactions, in US dollars.
rewardWhat your users received from credited transactions, in your currency.
conversion_rateOut of 100 clicks, how many led to at least one credited transaction, or null without clicks. A multi-step offer counts once, however many of its steps were credited, so this never goes above 100. credited still counts every credited step.
epc_usdEarnings per click in US dollars, or null without clicks.

Conversions

GEThttps://api.sharklio.com/v1/conversions

Every transaction of the period, oldest first, with the same values you receive in postbacks.

Query parameterDescription
from, tooptionaldate, YYYY-MM-DDThe period, in Budapest time, as for statistics.
statusoptionalstringcredited, pending, rejected, or reversed. Leave it out to get all of them.
user_idoptionalstringOnly transactions of this user, for example to answer a support request.
limitoptionalinteger, 1 to 500Transactions per page. Defaults to 100.
afteroptionalstringThe next_cursor of the previous page. Leave it out for the first page.
{
  "ok": true,
  "from": "2026-09-01",
  "to": "2026-09-07",
  "timezone": "Europe/Budapest",
  "currency": "Coins",
  "count": 1,
  "next_cursor": "1103",
  "conversions": [
    {
      "transaction_id": "9ca45437948f42022b8118b0",
      "user_id": "user_1234",
      "status": "credited",
      "offer_id": 120,
      "offer_name": "Coin Quest - Install and open the app",
      "offer_type": "offer",
      "reward": 146,
      "payout_usd": 0.225,
      "country": "DE",
      "device": "android",
      "sub1": "homepage", "sub2": null, "sub3": null, "sub4": null, "sub5": null,
      "created_at": "2026-09-03T23:59:49+02:00",
      "decided_at": "2026-09-03T23:59:49+02:00",
      "reversed_at": null
    }
  ]
}

When next_cursor is not null, there are more transactions: send the same request again with after set to that value.

Check that you received every postback

Postbacks are retried for hours, but a server outage on your side can still make you miss one. Once a day, compare your records with the API:

  1. Request yesterday with status=credited, and page through all results.
  2. For every transaction_id you have not credited yet, credit the user with reward.
  3. Do the same with status=reversed for transactions you credited but have not taken back.

Use transaction_id as the unique key, exactly as in your postback handler, so a transaction is never credited twice. You can also resend a failed postback from your dashboard under Logs.

Errors

Errors come as JSON with "ok": false, a stable error code, and a message for your logs.

HTTPerrorWhat to do
400invalid_date, invalid_range, range_too_long, invalid_group_by, invalid_status, invalid_limit, invalid_after, invalid_user_idFix the parameter named in the code.
401invalid_api_keySend the key in the Authorization header, and copy it again if you replaced it.
403app_not_availableReports are not available for rejected apps or suspended accounts.
405method_not_allowedUse GET.
429rate_limitedWait for the number of seconds in the Retry-After header.

Limits

  • Each app can make 60 reporting requests per minute. This limit is separate from the Offers API.
  • Numbers for today change as users complete offers and advertisers review them. Figures for past days settle once pending transactions are decided.