Skip to content
GET/api/reports/affiliate-daily We call you

DataFlair calls YOUR server. You build a read-only endpoint that returns daily numbers. You do not call DataFlair.

RequiredBuild this. It is part of the contract.

Operator Reporting API ​

You build one read-only endpoint on your server. It returns daily totals for each affiliate. DataFlair Stats calls it on a schedule and stores the numbers. Operators see every affiliate in the app. An affiliate sees only their own rows.

What we send ​

DataFlair sends a GET with a date range and one credential header.

http
GET /api/reports/affiliate-daily?from=2026-02-01&to=2026-02-07 HTTP/1.1
Host: operator.example.com
X-API-Key: YOUR_KEY
Accept: application/json
bash
curl "https://operator.example.com/api/reports/affiliate-daily?from=2026-02-01&to=2026-02-07" \
  -H "X-API-Key: YOUR_KEY" \
  -H "Accept: application/json"
Query parameterTypeRequiredMeaning
fromYYYY-MM-DDyesThe first day, inclusive. A UTC date.
toYYYY-MM-DDyesThe last day, inclusive. A UTC date.

DataFlair calls the URL you save on the program's Integrations page, exactly as saved. It removes any query string from that URL and adds from and to. The path /api/reports/affiliate-daily is the convention. A different path works when you save it.

If your API uses other names for from and to, or nests the rows in a different place, set a field mapping for the pull on the Integrations page. DataFlair reads the mapping for the parameter names and for the location of the rows array.

Authentication ​

Use a read-only credential. DataFlair sends it in one of these headers, according to the type you chose when you saved the connection:

TypeHeader
API key (recommended, the default)X-API-Key: <key>
Bearer tokenAuthorization: Bearer <token>

What you return ​

Status 200 with a JSON body:

json
{
  "from": "2026-02-01",
  "to": "2026-02-07",
  "rows": [
    {
      "date": "2026-02-01",
      "affiliate_id": "AFF-00042",
      "registrations": 28,
      "ftds": 7,
      "deposit_amount": 840.00,
      "commission_amount": 100.80
    }
  ]
}

rows may be empty. An empty array is a valid answer.

Fields ​

The response:

FieldTypeRequiredMeaning
rowsarrayyesOne object for each day and affiliate.
from, tostringnoThe range you answered for. DataFlair reads them when they are present.

Each row:

FieldTypeRequiredMeaning
dateYYYY-MM-DDyesThe reporting day of the row.
affiliate_idstringyesThe affiliate ID from the tracking link, for example AFF-00042. Return it exactly as you captured it.
registrationsintegerone metric is requiredPlayer accounts created.
ftdsintegerone metric is requiredFirst-time depositors.
deposit_amountnumberone metric is requiredThe sum of deposits.
commission_amountnumberone metric is requiredThe commission you attribute to the affiliate for the day. Leave it out or send null when you do not calculate it.
clicksintegernoClicks you track yourself. DataFlair tracks clicks on its own.

At least one of registrations, ftds, clicks, deposit_amount, commission_amount, reported_ngr or kyc_verified_ftds must be on the first row of the response. Without one, DataFlair fails the whole pull as a schema mismatch. DataFlair also reads ggr, but it does not count toward that check. The Metrics page explains each metric.

DataFlair skips a row that has no date, no affiliate_id, or a date that is not in the form YYYY-MM-DD. It stores the other rows.

The affiliate ID must be one DataFlair generated. You do not create affiliate IDs. You capture them from the landing URL, as described on Tracking links.

Errors ​

StatusWhat caused itWhat DataFlair does
200Success.Reads the rows and stores them.
400, and other 4xxA bad request, or a date it could not read.Records the run as failed. Does not retry.
401, 403The credential is wrong or missing.Records the run as failed. Does not retry.
429Rate limited.Waits for the Retry-After header, 10 seconds when the header is missing, at most 60 seconds. Then retries.
5xxA server error.Waits 2 seconds, then 4 seconds, and retries.
200 with no rows array, no date or affiliate_id on the first row, or no metric on the first rowThe body does not match the contract.Records the run as failed with a schema mismatch. Does not retry.

Timeouts and retries ​

DataFlair waits up to 30 seconds for each request. It makes up to 3 attempts in one run. The waits are in the table above.

How DataFlair pulls it ​

Each program picks a schedule on the Integrations page:

ScheduleWhen DataFlair calls your endpoint
DailyOnce a day at 03:00 UTC.
HourlyEvery hour, on the hour.
ManualOnly when an operator clicks Pull now.

Every pull asks for a range of days, not one day. The range and how late data is corrected are on Timezone and backfill.

Test this ​

Save your endpoint and credential in the Pull API connection on the Integrations page. Click Test connection. DataFlair calls your endpoint for yesterday, and it reports what it received. Click Pull now to run a full pull.

Verify ​

Before you save the connection, run the conformance check against your endpoint. It replays the fixtures and links each failure to the section of this page that explains it.

Verify this endpoint

node tools/stats-check/bin/stats-check.mjs https://operator.example.com/api/reports/affiliate-daily --key YOUR_KEY

No playground here: the request would go to your own server. Run the checker.

The checker is not published to npm yet. See how to run it.

Docs version 1.0.1