Feedback and fraud labels
Ce contenu n’est pas encore disponible dans votre langue.
In short
Section titled “In short”A decision is a prediction. Weeks later you find out whether it was right: a chargeback arrives, a customer complains that money left their wallet, or an investigation clears the payment. Feedback tells SpeculaPro what really happened.
You can send:
| What | Values | Typical source |
|---|---|---|
| Final status | completed, failed, reversed, chargeback, cancelled |
Your payment system, as soon as it knows |
| Fraud label | fraud, legitimate, unknown |
Chargebacks, customer complaints, your fraud team |
Fraud type (with a fraud label) |
account_takeover, card_testing, social_engineering, sim_swap, identity_theft, first_party, mule, merchant, other |
Your fraud team |
| Step-up result | true (passed) or false (failed) |
Your payment system, after a step_up answer |
| Note | Free text, up to 1,000 characters | Anyone |
There are two ways to send it: your systems call POST /api/v1/feedback, or a person labels the
decision on the Decisions page.
Why it matters
Section titled “Why it matters”Labels are how you find out whether a real-time rule catches fraud or only annoys good customers.
Each real-time rule’s page on Rules shows a line like this, over the last 30 days:
- Fired counts the decisions in which the rule fired in its live slot.
- Labelled afterwards counts those that someone labelled
fraudorlegitimate. - Precision is the share of labelled ones that were fraud: fraud ÷ (fraud + legitimate).
You need rules.view to see it. Until something is labelled, the line says None labelled
yet.
Worked example. Over 30 days, New device and new payee fired on 400 decisions. Your fraud team labelled 50 of them: 10 fraud, 40 legitimate. Precision is 20%: four in five of the customers it stopped were genuine. Before tightening it, check what those 40 had in common, for example a segment that changes phones often, and tune the rule.
Labels and statuses also show in the decision’s What really happened box, and the Labelled tab of the Decisions page lists every labelled decision.
How to send feedback from your systems
Section titled “How to send feedback from your systems”You need an API key with the decide or ingest:write scope. Feedback works for
transactions sent through either API, so your chargeback system can use its existing ingest key.
-
Collect the outcomes you have learned since your last call: final statuses, chargebacks, step-up results, your fraud team’s findings.
-
Send them in one batch of up to 500, each identified by the transaction’s
external_id:Terminal window curl -s https://speculapro.example.com/api/v1/feedback \-H "Authorization: Bearer $SPECULAPRO_DECIDE_KEY" \-H 'Content-Type: application/json' \-d '{"items": [{"external_id": "MOMO-2026-10-09-000201117", "status": "failed", "label": "fraud", "fraud_type": "sim_swap"},{"external_id": "CARD-AUTH-88213409", "status": "completed", "step_up_passed": true},{"external_id": "MOMO-2026-10-02-000187340", "status": "chargeback", "label": "fraud", "fraud_type": "account_takeover","note": "Customer reported phone stolen", "reported_at": "2026-10-08T09:15:00Z"}]}' -
Check each result. The answer has one result per item, in order:
{"results": [{"external_id": "MOMO-2026-10-09-000201117", "status": "recorded"},{"external_id": "CARD-AUTH-88213409", "status": "recorded"},{"external_id": "MOMO-2026-10-02-000187340", "status": "not_found"}]}statusMeaning What to do recordedStored Nothing not_foundNo transaction with that external_idin your workspaceCheck the ID. A transaction sent moments ago may not be registered yet: retry later rejectedThe item breaks a rule; errorssays whichFix it. See below
Rules for each item
Section titled “Rules for each item”- Send at least one of
status,label,step_up_passedornote. Otherwise: send at least one of status, label, step_up_passed or note. fraud_typeneeds"label": "fraud". Otherwise: fraud_type needs label fraud.reported_atis when you learned the outcome; it defaults to now.
Sending feedback in stages
Section titled “Sending feedback in stages”Each call adds to what is already known: fields you leave out keep their earlier value. So your
payment system can send status within seconds, and your fraud team a label weeks later, without
overwriting each other.
Two exceptions: a new label replaces the earlier one together with its fraud_type (a
legitimate label clears the type), and the most recent call decides who the box names as the
source (your systems, or a person).
Nothing is lost when a label is replaced: every change, through the API or on screen, is written to
the audit log as decision.feedback, with the feedback before and after and
the API key or person who sent it.