Reviewing fraud flags
Inspect why a click was flagged and dismiss false alarms.
Partli runs cheap fraud checks at click and sale time and flags suspicious activity rather than blocking it. A flagged click still redirects and still counts for attribution — nothing is silently dropped. As a workspace admin or manager, you review these flags on the partner page, dismiss the false alarms, and ban partners whose pattern actually looks abusive.
What gets flagged
Each flag carries a raw flag_reason that the UI translates into a plain-English label:
- Automated user-agent — the click came from a bot-like user-agent (crawler, script, or headless browser). Raw reason starts with
bot_ua. - Social link preview — a
bot_uaflag whose user-agent matches a social/messaging unfurl crawler. Marked benign: this happens when a partner shares their link. Not fraud. - Missing user-agent — no (or a suspiciously short) user-agent. Raw reason
empty_or_short_user_agent. - Repeated clicks from one IP — the same IP produced N clicks within 10 minutes (possible click inflation). Raw reason
ip_spam:N_in_10m.
In the dashboard
- ●
Spot flagged partners
On
/<workspace>/partners, the Fraud column shows an amber warning icon and anN flagsbadge for any partner with open (unresolved) flags. - ●
Open the partner and read the Flagged activity card
Click into
/<workspace>/partners/<partnerId>. The Flagged activity card lists each flagged click with its label, an explanation, timestamp, country, and the raw user-agent. The badge in the card header readsN open flags. - ●
Dismiss false alarms
Each flagged click has a
Dismissbutton. If a partner has more than one open flag, aDismiss allbutton appears in the card header to resolve them in one shot. Dismissed clicks get a greenDismissedbadge and dim out. - ●
Reopen if you dismissed by mistake
A resolved flag shows a
Reopenbutton that puts it back into the open set. - ●
Ban a genuinely abusive partner
Dismissing a flag never touches the partner's status. If the pattern really is abusive, ban the partner from their status controls instead.
Via the API / for agents
The dashboard buttons all call one endpoint. It requires a manager role (or above) on the workspace — the check is canManage(role), so viewers get a 403.
POST /api/workspaces/<slug>/partners/<partnerId>/resolve-flagsBody (all fields optional):
{
"clickId": "<uuid>", // omit to act on ALL open flags for the partner
"action": "resolve" // "resolve" (default) or "reopen"
}Dismiss one flagged click as a false alarm:
curl -X POST \
https://app.partli.com/api/workspaces/acme/partners/PARTNER_ID/resolve-flags \
-H "content-type: application/json" \
-d '{ "clickId": "CLICK_UUID", "action": "resolve" }'Dismiss every open flag for the partner at once (omit clickId):
curl -X POST \
https://app.partli.com/api/workspaces/acme/partners/PARTNER_ID/resolve-flags \
-H "content-type: application/json" \
-d '{ "action": "resolve" }'The response reports how many click rows were updated:
{ "ok": true, "count": 3 }resolve only touches currently-open flags (rows with flagResolvedAt still null) and records who resolved them in flagResolvedBy. Pass action: "reopen" to undo — that only touches already-resolved flags and clears both fields.
Gotchas
Dismissing is not un-flagging, and it never pays or blocks anyone
Resolving a flag only clears it from the open set for review — the click row stays flagged = true, it's just marked resolved via flagResolvedAt. A few things worth knowing:
- Flags never block: the click already redirected and already counted for attribution before you ever saw the flag.
- The endpoint is scoped to the workspace's own partner — a manager can't touch another workspace's clicks (you get a
404if the partner isn't yours). - Social link-preview crawlers (Facebook, Slack, LinkedIn, etc.) are dropped upstream and never create a flag; a
Social link previewlabel only appears on older data. Real fraud checks arebot_ua,empty_or_short_user_agent,ip_spam, and self-referral (partner converting on their own link). - Dismissing does not pay out or approve anything — commissions follow their own approval flow.