For the complete documentation index, see llms.txt. This page is also available as Markdown.

Postback Reporting

envelope-open

Overview

Postback Reporting sends near real-time webhook notifications ("postbacks") when a monetizable event occurs for a lead that originated from your traffic. A monetizable event is also known as a funded loan, conversion, or payout event.

  • This unlocks

    • Faster, more accurate conversion tracking and attribution

    • Deeper analytics integrations

    • Dynamic bidding

    • Real-time rewards

  • Today, that means payout events: the same line items you already see in your Looker or invoice reports, sent the moment a payout is recorded in our system.

  • Coming soon: Postbacks for lead events that happen before conversion, like an offer click.

How It Works

  1. Consumer interacts with your experience.

  2. You send Engine a client tag (typically), which triggers a lead UUID.

  3. Consumer converts, e.g. a funded loan.

  4. Engine finds out: for CPA campaigns, the Financial Institution reports the conversion; for CPC campaigns, Engine already knows the moment it logs the click.

  5. Engine sends a postback to the URL you've provided, as soon as the event is recorded.

    1. If a lead converts on multiple offers, you'll get a separate postback for each one, each with its own transaction ID and payout amount.

    2. Every postback includes the payout amount, the transaction ID, and your client tag, if provided.

Example: a user clicks a CPC offer (payout: $0.50) → you get a postback. That same user also converts on a CPA offer (payout: $100) → you get a second postback.

Setup Requirements

exclamation
What We Need
What It's Used For
Format & Examples

Postback URL

The endpoint Engine sends the postback to

Full URL string

yourUrl.com/postbackreporting

HTTP Method

Determines whether Engine fires the postback as a GET or POST request

GET or POST

Payload structure

Tells us where to put the values: in the URL or in a JSON body

GET: Query or path params in the URL ?payout=100.00&clientId=abc123.

POST: Query/path params, or JSON {"payout": "100.00", "clientId": "abc123"}

Payout amount field name

Maps Engine's payout dollar amount to whatever param/field name your system expects

By default, we return dollars with 2 decimals

?payout={payout.payoutInDollars}

Also supported: payout.payoutInCents

payout.payoutInDollars

Transaction ID field name

Maps Engine's internal payout event ID (our "Transaction ID") to your field, so you can reference it back to us

This is Engine's Transaction ID, let us know if you want it called transactionId or if your API expects some other field in order to store it

?yourMappedTransactionId={engineTransactionId}

Your client tag key(s)

Echoes back your own attribution ID(s) - whatever you sent us on the original lead - under the key name(s) you choose

Any identifier(s) you provide when posting the lead that you use for attribution on your end (e.g., you send subId, we echo it as ?userId={subId}).

Please provide the key of the client tag(s) desired, and we will include the value you provided for that lead for that tag.

Sample "known-good" payload

Required to confirm your endpoint returns a success response before we push the report live

A real request with values you confirm returns a 2xx, no invalid-ID errors

Engine Lead UUID

Referencing this speeds up troubleshooting if an issue is encountered

?partnerClientId={engineLeadUuid}

Invalidations

Do you want a follow-up notification if a payout is later reversed/deleted?

Yes/No (Default: No)

Same transaction_id as the original, possibly a negative amount.

Best Practices

⚙️

Treat postbacks as a production data pipeline, not just a notification

🔁

Idempotency

  • Use the Transaction ID as your unique key

  • If you receive the same Transaction ID twice, don't create a duplicate record

🗂️

Store Engine identifiers

  • Keep the Transaction ID (for deduplicating payouts)

  • Keep the Engine Lead UUID (for reconciling issues with our team) on every record

🏷️

Send client tags

  • Review Client Tags for Attribution for structuring & supported tags

  • Include one on every lead you post to Engine (e.g. clientId, campaignId, subid, sourceId) to attribute payouts back to your own users, placements, or campaigns; we'll echo it back on the matching postback.

  • Never send PII in a client tag

Return a clear success response

  • Acknowledge the postback quickly

  • If you need heavier downstream processing, queue it internally rather than doing it synchronously in the request

📝

Log everything

  • Keep the raw inbound request, response status, and receipt timestamp.

  • This makes missing payouts, duplicate deliveries, field-mapping issues, and invoice disputes much faster to investigate

Handling Invalidations

Invalidations happen when a previously recorded payout is later canceled or revised, for example a funded loan cancellation, duplicate or erroneous data from the Financial Institution, or a retroactive contract update.

  • Invalidations are uncommon, and most partners don't opt in to receiving them today.

  • If you skip them, your internal numbers may occasionally drift from Engine's Looker/Invoice reports (which do account for invalidations), requiring manual reconciliation during monthly invoicing.

  • We recommend opting in and building support for invalidations into your ingestion logic.

  • Invalidations can be sent in whatever format works for you, for example: an event field ("converted" vs "invalidated"), a negative payout amount for the same Transaction ID, or a deletedAt timestamp for the same Transaction ID.

Scenario
Payout
Invalidation
New Payout (if any)

Funded loan canceled

$100

-$100

None

Duplicate record sent

$100

-$100

None

Contract updated retroactively

$100

-$100

$110 (new Transaction ID)

Testing & Monitoring

Before go-live, confirm:

💡 Pro Tip to Speed up Launch: Provide a tested sample payload that already returns success.

After go-live, monitor for:

  • Non-2xx responses

  • Authentication failures

  • Timeout errors

  • Drops in expected postback volume

Last updated

Was this helpful?