Merchant trust signals

Merchant trust signals let you share what you know about your players — tenure, engagement depth, and your own standing verdict — so Breeze can factor real player history into risk decisions, not just payment-instrument and device signals.

This is entirely optional. Send trust signals only if you want to optimise your acceptance rate: established players you vouch for see fewer false-positive declines and step-ups, and players you have flagged are caught earlier.

The merchantTrustSignal object

FieldTypeRequiredDescription
playerIdstring (max 255)YesYour unique, persistent identifier for the player. Send the same value on every request — it is the join key tying your signals to Breeze's transaction record.
trustStatus"GOOD" | "BAD" | nullNoYour verdict on the player's standing. Omit if unknown.
hoursPlayedinteger ≥ 0NoCumulative whole hours the player has played. A proxy for account tenure and genuine usage depth. Omit to keep the stored value; send null to clear it.
playerLevelinteger ≥ 0NoThe player's current level, tier, or progression milestone. A secondary engagement signal where hours alone could be gamed (e.g. idle sessions). Omit to keep the stored value; send null to clear it.

What trustStatus asserts:

  • "GOOD" — established history of legitimate play and spend with no adverse findings (no chargebacks, no fraud flags, verified identity on file).
  • "BAD" — internally flagged for suspicious activity, policy violation, prior chargeback, or confirmed fraud — regardless of dispute status on Breeze's side.
  • Omitted / null — unknown. This is scored as its own state, not as either explicit value.

Where to send it

merchantTrustSignal is an optional object on the customer, accepted by:

  • 📄 Create a customer — set it when the player profile is first created.
  • 📄 Update a customer — refresh it as your signals change (e.g. a new fraud finding → trustStatus: "BAD").
  • 📄 Create a payment page — via the inline create/update variant of the customer field, to submit the signal at transaction time.
  • 📄 S2S direct payment (POST /v1/gateway/payments) — only when the customer is identified by id or referenceId; not available for anonymous shoppers.

The signal is stored on the customer record and returned in customer responses. Payment page and S2S payment responses do not include it.


Adding a signal

curl -X POST 'https://api.breeze.cash/v1/customers' \
  -u "YOUR_API_KEY:" \
  --header 'Content-Type: application/json' \
  --data-raw '{
    "referenceId": "<your-unique-user-id>",
    "email": "[email protected]",
    "signupAt": 1710000000000,
    "merchantTrustSignal": {
      "playerId": "player_8842",
      "trustStatus": "GOOD",
      "hoursPlayed": 412,
      "playerLevel": 37
    }
  }'

A successful response returns the stored signal:

{
  "status": "SUCCEEDED",
  "data": {
    "id": "cus_123abc456",
    "referenceId": "<your-unique-user-id>",
    "email": "[email protected]",
    "merchantTrustSignal": {
      "playerId": "player_8842",
      "trustStatus": "GOOD",
      "hoursPlayed": 412,
      "playerLevel": 37
    }
    ...
  }
}

Updating a signal

Partial objects are accepted — only playerId is required on every write. hoursPlayed, playerLevel, and trustStatus all follow the same contract, per field:

Omit a field to keep its stored value:

{
  "merchantTrustSignal": {
    "playerId": "player_8842",
    "trustStatus": "BAD"
  }
}

This sets trustStatus and leaves the stored hoursPlayed and playerLevel untouched.

Send null to clear a field's stored value:

{
  "merchantTrustSignal": {
    "playerId": "player_8842",
    "hoursPlayed": null
  }
}

Send a value to set it.

A { "playerId": "..." }-only object is also valid — it registers the join key and stores nothing else.


⚠️

Keep playerId stable

playerId must be persistent — the same value on every request for the same player. A rotating or per-session value makes the signal set unreliable for your traffic.

The keep-stored-value behaviour is keyed to playerId: if you send a different playerId than the one stored, none of the previously stored fields — hoursPlayed, playerLevel, or trustStatus — carry over. Set each explicitly on the new signal if you intend it to persist.


How Breeze uses the signals

  • Trust signals are one input among several — "GOOD" is not an automatic approval and "BAD" is not an automatic decline.
  • "BAD" is a high-weight input into step-up (3DS) decisions.
  • Every trustStatus change is recorded with its timestamp and prior value. Status stability is itself a signal: a status that has been steady for months carries more weight than one flipped just before a transaction.


Did this page help you?