Channel Partner Reporting - Analytics API
For partners who would prefer to fetch their reporting programmatically, we offer an Analytics API for you to receive lead-level reporting on funnel metrics.
API Endpoints
We provide the following reporting endpoints for real-time insights into the user acquisition to conversion funnel:
GET /leadEvents
Retrieve lead conversion event data (creation, clicks, approvals, rejections, etc.)
GET /leadPayouts
Track payouts per conversion on a per-lead basis
GET /leadClientTags
Retrieve client tags (e.g., subID, clickID, traffic source) for segmentation and attribution
GET /leadsInfo/{leadUuid}
On-demand snapshot of a single lead’s full data (events, payouts, tags)
Basic Request & Response Format
Authentication
All requests require:
Bearer token in the
Authorization
headerAPI-Version header set to
2025-04-01
Example:
Authorization: Bearer {accessToken}
API-Version: 2025-04-01
If the token is missing, expired, or invalid, the API will return a 401 Unauthorized
.
Key Parameters
All streaming endpoints (/leadEvents
, /leadPayouts
, /leadClientTags
) support the following query parameters:
sinceTimestamp – Lower bound for records to include. Use ISO 8601 UTC format with
Z
. Recommended for initial requests.untilTimestamp – Upper bound for records to include (exclusive). Useful for controlled backfills.
paginationToken – Cursor for fetching the next page of results. Obtained from the previous response.
eventType (for
/leadEvents
only) – Optional array filter to return only specific event types. Accepts multiple values (comma-separated).
These parameters apply only to the streaming endpoints above. They do not apply to /leadsInfo/{leadUuid}
, which is a direct lookup endpoint returning a full snapshot for a single lead.
Response Structure
Each request will return a JSON object with the following properties:
{
"data": [...],
"nextUrl": "https://api.engine.tech/...paginationToken=...",
"shouldContinuePolling": true,
"paginationToken": "string"
}
data – Array of records as objects (events, payouts, or client tags depending on the endpoint).
nextUrl – Pre-built URL for the next request. Always follow this rather than constructing your own.
shouldContinuePolling – Boolean indicating whether additional data is available at the next URL.
paginationToken – Cursor used for paging. Already included in
nextUrl
, but exposed separately for convenience.
Important Notes
Responses are subject to a maximum size limit (can be 10s of thousands of records, depending on the endpoint and the volume you send). If more data exists,
shouldContinuePolling
will betrue
and you should immediately follow thenextUrl
untilshouldContinuePolling
isfalse
.Always advance using the
nextUrl
provided to avoid missing or duplicating records.Unless backfilling historical data, polling should be no more than once every 5 minutes - data is only updated every 5 minutes.
Timestamps without an explicit timezone are interpreted as UTC. We recommend including
Z
(e.g.2025-01-01T00:00:00Z
) for consistency.
Lead Events API – /leadEvents
/leadEvents
This endpoint returns events associated with each lead. The event type is indicated by the eventType
property. Each event will also include other data applicable to the eventType (see below). It allows easy consumption of the events into your database so that you can integrate it into your BI framework and compare it alongside data from other systems to assess performance holistically.
Example Request
curl -X GET "https://api.engine.tech/supplyAnalytics/leadEvents?sinceTimestamp=2024-09-01T00:00:00Z" \
-H "Authorization: Bearer {accessToken}" \
-H "API-Version: 2025-04-01"
Example Response
{
"nextUrl": "https://api.engine.tech/supplyAnalytics/leadEvents?paginationToken={paginationToken}",
"shouldContinuePolling": true,
"paginationToken": "{paginationToken}",
"data": [
{
"id": "{eventRecordId1}",
"leadUuid": "{leadUuid1}",
"leadCreatedAt": "2025-01-01T11:24:45Z",
"eventType": "offerClicked",
"eventCreatedAt": "2025-01-01T12:00:00Z",
"financialInstitutionUuid": "{fiUuid1}",
"financialInstitutionName": "FI Partner A",
"productType": "",
"productSubType": "",
"unifiedProductType": "",
"isTest": false,
"paginationTimestamp": "2025-01-01T12:00:00Z"
},
{
"id": "{eventRecordId2}",
"leadUuid": "{leadUuid2}",
"leadCreatedAt": "2025-01-02T09:42:06Z",
"eventType": "apiApproved",
"eventCreatedAt": "2025-01-02T09:44:28Z",
"financialInstitutionUuid": "{fiUuid2}",
"financialInstitutionName": "FI Partner B",
"isTest": false,
"paginationTimestamp": "2025-01-02T09:44:28Z"
}
]
}
Event Types (by product)
Loans:
leadCreated
appSubmitted
apiApproved
apiRejected
offerClicked
applied
approved
funded
listed
Savings:
opened
funded
Credit Cards:
applied
approved
2nd Look Marketplace:
conversion
isContacted
salesQualified
firstPayment
Lead Payouts API – /leadPayouts
/leadPayouts
This endpoint allows you to collect granular payout information for leads you have submitted. It returns a unique identifier for the record (uuid
) payout information (amount and timestamp), the Financial Institution the converted with, the productType
/unifiedProductType
, and the leadUuid
.
Example Request
curl -X GET "https://api.engine.tech/supplyAnalytics/leadPayouts?sinceTimestamp=2019-08-24T14%3A15%3A22Z" \
-H "Authorization: Bearer {accessToken}" \
-H "API-Version: 2025-04-01"
Example Response
{
"nextUrl": "https://api.engine.tech/supplyAnalytics/leadPayouts?paginationToken={paginationToken}",
"shouldContinuePolling": false,
"paginationToken": "{paginationToken}",
"data": [
{
"uuid": "{recordUuid1}",
"leadUuid": "{leadUuid1}",
"bookedAt": "2025-01-01T00:00:00Z",
"payoutInCents": 20000,
"deletedAt": null,
"financialInstitutionUuid": "{fiUuid1}",
"financialInstitutionName": "FI Partner A",
"productType": "savings",
"unifiedProductType": "{OCProductType1}",
"paginationTimestamp": "2025-01-01T00:00:00Z"
},
{
"uuid": "{recordUuid2}",
"leadUuid": "{leadUuid1}",
"bookedAt": "2025-01-02T00:00:00Z",
"payoutInCents": 30000,
"deletedAt": null,
"financialInstitutionUuid": "{fiUuid2}",
"financialInstitutionName": "FI Partner B",
"productType": "savings",
"unifiedProductType": "{OCProductType1}",
"paginationTimestamp": "2025-01-01T00:00:00Z"
},
{
"uuid": "{recordUuid3}",
"leadUuid": "{leadUuid2}",
"bookedAt": "2025-01-02T00:00:00Z",
"payoutInCents": 10000,
"deletedAt": null,
"financialInstitutionUuid": "{fiUuid3}",
"financialInstitutionName": "FI Partner C",
"productType": "savings",
"unifiedProductType": "{OCProductType1}",
"paginationTimestamp": "2025-01-02T00:00:00Z"
}
]
}
Deleted Payouts
If the record's deletedAt
is not null
, you should understand this to be a deletion of a previous payout you would have already received in a previous response (you can identify it by the id
corresponding to the previous record received).
Deleted payouts are not frequent, but they are not rare. A payout may be deleted if:
A funded loan/conversion was canceled
A record was reported in error
A partner contract (either FI or Channel partner) was updated with a retroactive date
In this case, you would receive two records in the same response - one for the deleted payout with a non-null
deletedAt
(with the oldid
), and one for the new payout with a newpayoutInCents
and a nulldeletedAt
(with a newid
).
Financial Institution Payout Events
Each response also contains two fields identifying the Financial Institution the lead monetized with:
financialInstitutionUuid
– stable identifier of the financial institution.financialInstitutionName
– human-readable name of the institution.
These fields help disambiguate which Financial Institution a payout is tied to, especially in cases where multiple payouts exist for a single lead (typically, but not always, with different Financial Institutions). Most, but not all payouts are associated with a specific FI, so these fields may not always be present.
Lead Client Tags API – /leadClientTags
/leadClientTags
This endpoint returns the client tags associated with a lead.
Client tags are your key/value pairs of information that you set up when generating leads (through either a Hosted Integration or Native API Integration) to enable attribution back to your own identifiers, thereby enabling custom segmentation. Client tags provides you a method to be able to segment leads to support uses cases like:
See how various traffic sources on the supply partners site perform
See what preferences their users from different segments have
Please never include PII in the clientTags
object when posting leads into Engine's API.
Example Request
curl -X GET "https://api.engine.tech/supplyAnalytics/leadClientTags?sinceTimestamp=2019-08-24T14%3A15%3A22Z" \
-H "Authorization: Bearer {accessToken}" \
-H "API-Version: 2025-04-01"
Example Response
{
"nextUrl": "https://api.engine.tech/supplyAnalytics/leadClientTags?paginationToken={paginationToken}",
"shouldContinuePolling": true,
"paginationToken": "{paginationToken}",
"data": [
{
"id": "{recordUuid1}",
"leadUuid": "{leadUuid1}",
"key": "subId",
"value": "12345",
"createdAt": "2025-01-05T14:00:00Z"
}
]
}
For more information sending your Client Tags to Engine (for retrieval through this leadClientTags
endpoint, please refer to https://engine.tech/developer-center/references/appendix/appendix-e-appending-client-tags-to-leads-posted-to-engine.
Lead Info API – /leadsInfo/{leadUuid}
/leadsInfo/{leadUuid}
Get a full snapshot of one lead’s lifecycle in a single call: events
, payouts
, and client tags
. It includes all of the same information as the combination of leadEvents
, leadPayouts
and leadClientTags
endpoints on demand, without having to sync responses from 3 endpoints and tie them together using coding logic.
Example Request
curl -X GET "https://api.engine.tech/supplyAnalytics/leadsInfo/{leadUuid}" \
-H "Authorization: Bearer {accessToken}" \
-H "API-Version: 2025-04-01"
Example Response
{
"data": {
"events": [
{
"id": "{eventUuid1}",
"leadUuid": "{leadUuid1}",
"leadCreatedAt": "2025-05-23T21:29:13Z",
"eventType": "leadCreated",
"eventCreatedAt": "2025-05-23T21:29:13Z",
"financialInstitutionUuid": "{fiUuid}",
"financialInstitutionName": "FI Partner A",
"isTest": false,
"paginationTimestamp": "2025-05-23T21:29:13Z"
}
],
"payouts": [
{
"uuid": "{payoutUuid12",
"leadUuid": "{leadUuid2}",
"bookedAt": "2025-05-23T21:29:13Z",
"payoutInCents": 5000,
"deletedAt": null,
"paginationTimestamp": "2025-05-23T21:29:13Z"
}
],
"clientTags": [
{
"hash": "{hashValue}",
"leadUuid": "{leadUuid}",
"key": "campaignId",
"value": "abc123",
"createdAt": "2025-05-23T21:29:13Z",
"paginationTimestamp": "2025-05-23T21:29:13Z"
}
]
},
"warnings": []
}
Timing & Polling
Because reporting data depends on when Financial Institutions send information to Engine, there are important timing rules to follow.
Polling frequency
Poll at least hourly for new data.
Do not poll more than once every 5 minutes — requests made too soon after the last poll may fail due to SLA limits.
shouldContinuePolling
flag
If
shouldContinuePolling
istrue
, call thenextUrl
to obtain more data associated with your query.If
shouldContinuePolling
isfalse
, there are no more records currently available for your query — wait until your next polling interval before trying again.
Timestamps in responses
eventCreatedAt
→ When the event was processed into Engine’s system.bookedAt
→ When the monetization event actually occurred (applies to/leadPayouts
).These may differ from the real-world user action because FIs often report with a minimum 1–2 day delay.
Response idempotency - depends on the query
A request with the same
sinceTimestamp
anduntilTimestamp
will always return the same results.Even if payouts are later deleted, those deletions are logged under the timestamp of the deletion event, not the original creation time.
Two requests with the same
sinceTimestamp
but nountilTimestmap
may not always return the same results - because new records may have been added in that time.
Lag considerations
Leads and conversions may not appear immediately.
Always account for possible reporting delays and backfill windows (e.g., a loan funded on Day 1 may not appear until Day 3 due to FI reporting cycles, and some subverticals may take much longer due to their business cycles).
Example Flow
A loan is funded on 9/15 at 17:30 UTC.
The FI sends the report to Engine on 9/16 at 15:30 UTC.
Engine processes the report and loads it into the data warehouse on 9/17 at 12:30 UTC.
API behavior:
/leadPayouts
will return the event withbookedAt: 2025-09-15T17:30:00Z
.But the record itself is only retrievable when querying with the processing timestamp (9/17 12:30 UTC).
Event Definitions
The list below shows the most common event attributes and types. Not all will be present for every product funnel.
Common Attributes
eventType
leadUuid
leadCreatedAt
eventCreatedAt
financialInstitutionUuid
financialInstitutionName
productType
,productSubType
,unifiedProductType
amountInCents
(for monetary events)
Example Event Types
leadCreated – User enters marketplace funnel
appSubmitted – Lead application completed
apiApproved / apiRejected – Pre-qualification decision
offerClicked / affiliateOfferClicked – User clicks offer
applied – User applied within FI’s experience
approved / funded – User approved and loan funded
opened – User monetized with an offer
Error Handling
200
Success
206
Partial success (result truncated)
400
Bad request
401
Unauthorized (missing/invalid token)
404
Resource not found
422
Invalid request logic
5xx
Server error
Best Practices
If you need to retrieve historical data (e.g., when first enabling the API), set your initial
sinceTimestamp
at 00:00:00Z (midnight UTC) of your go-live date, and you'll be sure to capture all possible events for your account. UseuntilTimestamp
only (or no timestamps at all) to trigger a wider backfill windows, and request there is nonextUrl
in your response.If you want to retrieve all records SINCE a particular date, set only
sinceTimestamp
if you want something up UNTIL a date, set only
untilTimestamp
Poll hourly; avoid polling more than once every 5 minutes
Use
paginationToken
for paging, notsinceTimestamp
after the first requestUse explicit UTC timestamps, ideally with
Z
suffix to avoid any ambiguity.Build flexible integrations (new fields may be added)
NEVER store PII in client tags when sending leads to the Engine API
Historical Data Retrieval & Backfills
Some of our channel partners may wish to pull a large amount of historical data (e.g. a backfill for catch-up). For most partners, the initial call can be made with no parameters to start from the beginning of time and then continuously follow the nextUrl
. For retrieving historical data or performing a backfill:
Set a
sinceTimestamp
if you only want data since a particular date.Optionally, also set an
untilTimestamp
for controlled rangesContinue following the
nextUrl
untilshouldContinuePolling
isfalse
JavaScript Pagination Example
Here's a practical example of how to loop through pagination for data retrieval:
async function fetchAllLeadEvents(apiToken, sinceTimestamp = null) {
const allEvents = [];
let url = 'https://api.engine.tech/supplyAnalytics/leadEvents';
// Add timestamp for backfill if provided
if (sinceTimestamp) {
url += `?sinceTimestamp=${encodeURIComponent(sinceTimestamp)}`;
}
while (url) {
try {
const response = await fetch(url, {
headers: {
'Authorization': `Bearer ${apiToken}`,
'API-Version': '2025-04-01'
}
});
if (!response.ok) {
throw new Error(`HTTP ${response.status}: ${response.statusText}`);
}
const data = await response.json();
allEvents.push(...data.data);
// Follow nextUrl if more data is available
url = data.shouldContinuePolling ? data.nextUrl : null;
// Add delay between requests to respect rate limits
if (url) {
await new Promise(resolve => setTimeout(resolve, 1000));
}
} catch (error) {
console.error('Error fetching lead events:', error);
break;
}
}
return allEvents;
}
// Usage examples:
// Fetch all historical data
const allEvents = await fetchAllLeadEvents(apiToken);
// Fetch data since specific timestamp
const recentEvents = await fetchAllLeadEvents(apiToken, '2025-09-01T00:00:00Z');
Data Timing & Availability
Data appears in the API at different times depending on the source:
Non-monetization event types: Typically available within minutes
Monetization events typically take 1 day to 2 weeks to be returned (since the Financial Institution must wait for the lead to convert, and then Engine must wait for the FI to report the conversion)
Recent data (last 5 minutes): Blocked by blackout window
Support
For help, contact your Partner Manager or email [email protected].
Last updated
Was this helpful?