GET First Deposits¶
Endpoint¶
GET /api/affiliate/v1/first-deposits
Requires an affiliate API token with transactions:read.
GET /api/affiliate/v1/first-deposits?limit=100&offset=0&from_time=1789344000&to_time=1791936000
Authorization: {JWT_TOKEN}
Returns at most one row per customer: the first credited cashier deposit that customer ever made. This is the FTD figure affiliate commission is normally calculated from, as opposed to Financial Transactions, which returns every transaction.
The server first resolves the customers attributed to the token's affiliate and brand, then reduces each customer's credited deposits to the earliest one.
What counts as a first deposit¶
A transaction qualifies only when all of the following hold:
- it belongs to a customer attributed to the token's affiliate and brand;
typeis0(deposit);statusis3(credited), the status the finance ledger sets once the money has actually reached the account. Created, pending, provider-confirmed, failed, cancelled, refunded, charged-back and manual-review transactions are attempts or reversals, not deposits;processed_timeis greater than zero.
Among the qualifying transactions of one customer the earliest processed_time wins; ties are broken by the lower id.
Refunds drop out for a different reason than the statuses above: a refunded deposit leaves credited for refunded or chargeback and stops qualifying. The consequence is worth planning for — once a first deposit is refunded, the next one in time becomes the first, and the row returned for that customer changes retroactively.
Order of evaluation¶
The order of these steps is part of the contract, not an implementation detail: the figures in the response depend on it.
- Select every qualifying deposit of the affiliate's customers, across the whole history, ignoring
from_timeandto_time. - Reduce to one deposit per customer by the rule above.
- Apply the time window to the deposit already selected, using its
processed_time. - Sort by
processed_timedescending, then byiddescending. - Take
count. - Cut the page with
limitandoffset.
Steps 1 and 3 cannot be swapped. A deposit is a first deposit only if no earlier one exists at all. Filter by the window first, and a customer who deposited last year and again this month reappears as a new first deposit inside the later window — and the affiliate is paid a second time.
Query parameters¶
| Name | Type | Required | Description |
|---|---|---|---|
limit |
int | Yes | Page size from 1 to 500 |
offset |
int | Yes | Number of matching records to skip; minimum 0 |
customer_id |
int | No | Restrict the result to a single customer. Must be positive |
from_time |
int64 | No | Minimum processed_time, inclusive. 0 or omitted means no lower bound |
to_time |
int64 | No | Maximum processed_time, inclusive. 0 or omitted means no upper bound |
type and status are not supported here: the endpoint is fixed to credited deposits. They are ignored rather than refused, so an integration can call this endpoint and /api/affiliate/v1/transactions with one shared set of query parameters.
An invalid bound is refused with 400; see Time filtering.
A customer_id belonging to another affiliate returns an empty result with status 200, not 404. Answering with a not-found code would let a caller probe for the existence of customers outside its own scope.
Ordering and pagination¶
Rows are ordered by processed_time descending, with id descending as the tie-breaker, so the most recent first deposits come first.
count is the number of customers with a qualifying first deposit in the window, not the number of transactions. The reduction to one deposit per customer happens before count is taken and before limit / offset are applied, so paging walks customers, not transactions.
Response¶
{
"rows": [
{
"id": 899,
"customer_id": 12041,
"login": 2000041,
"type": 0,
"type_name": "deposit",
"status": 3,
"status_name": "credited",
"provider": "stripe",
"method": "card",
"amount": 250.0,
"currency": "USD",
"account_currency": "USD",
"converted_amount": 250.0,
"conversion_rate": 1.0,
"created_time": 1789344000,
"processed_time": 1789344012
}
],
"count": 7
}
The row shape is identical to Financial Transactions. The response excludes provider payment identifiers, idempotency keys, raw metadata, internal comments, failure or rejection details, and staff identifiers.
Differences from Financial Transactions¶
/v1/transactions |
/v1/first-deposits |
|
|---|---|---|
| Rows | every matching transaction | at most one per customer |
count |
matching transactions | customers with a first deposit |
| Type and status | selectable through type and status |
fixed to credited deposits; both parameters ignored |
| Time filter applies to | created_time |
processed_time |
| Ordering | id descending |
processed_time descending, then id descending |
Transactions without customer_id |
resolved through the account login | excluded |
The last row matters for older data only. Transactions created without a customer id cannot be grouped by customer, so they take no part in this endpoint; the server has rejected such transactions at creation since the field became mandatory.
Errors¶
| HTTP | Error | Description |
|---|---|---|
401 |
INCORRECT_TOKEN |
JWT signature or format is invalid |
401 |
INVALID_AFFILIATE_API_TOKEN |
Token record, owner, brand, scope, expiration, or active access check failed |
403 |
INVALID_AFFILIATE_API_HOST |
The request origin is not allowed for this token |
400 |
INVALID_DATA |
limit or offset is missing or invalid, customer_id is not a positive integer, or from_time / to_time is not a non-negative integer or forms an inverted range |
An empty rows array with count: 0 and status 200 is a valid successful response, not an error. It is returned both when no attributed customer has a credited deposit and when customer_id names a customer of another affiliate.