Order Fraud API
Submit orders for real-time fraud scoring, manage anonymous profiles, and monitor cashier activity.
Profiles
Create/Update Profile
POST /v1/profiles
Creates or updates an anonymous integration profile. If the external_id already exists for your org, the profile is updated (last_seen_at bumped, device linked).
Auth: API Key (X-API-Key header)
curl -X POST https://api.simplr-ai.com/v1/profiles \
-H "X-API-Key: sk_live_xxxxx" \
-H "Content-Type: application/json" \
-d '{
"external_id": "user-abc-123",
"profile_type": "customer",
"fingerprint_hash": "a1b2c3d4e5..."
}'
| Field | Type | Required | Description |
|---|---|---|---|
external_id | string | Yes | Your internal user identifier (max 512 chars) |
profile_type | string | No | customer, cashier, employee, system (default: customer) |
fingerprint_hash | string | No | Device fingerprint hash (links device to profile) |
ip_hash | string | No | Hashed IP address for location context |
country_code | string | No | ISO 2-letter country code |
latitude | number | No | Latitude (-90 to 90) |
longitude | number | No | Longitude (-180 to 180) |
Response:
{
"success": true,
"message": "Profile upserted",
"content": {
"profile": {
"id": "uuid",
"external_id": "user-abc-123",
"profile_type": "customer",
"status": "active",
"risk_score": 0,
"risk_level": "low",
"device_count": 1,
"total_orders": 0
},
"is_new": true,
"device_linked": true,
"device_anomaly": null
}
}
If device_anomaly is non-null, it describes a suspicious device pattern (e.g., "Profile seen on 5 new devices in 24h").
Orders
Submit Order
POST /v1/orders
Submit an order for real-time fraud scoring. Returns immediately with a risk assessment.
Auth: API Key (X-API-Key header)
curl -X POST https://api.simplr-ai.com/v1/orders \
-H "X-API-Key: sk_live_xxxxx" \
-H "Content-Type: application/json" \
-d '{
"external_order_id": "ORD-2026-001",
"external_id": "user-abc-123",
"amount_cents": 15999,
"currency": "ZAR",
"order_type": "online",
"payment_method": "card",
"location_latitude": -33.92,
"location_longitude": 18.42,
"fingerprint_hash": "a1b2c3d4e5..."
}'
| Field | Type | Required | Description |
|---|---|---|---|
external_order_id | string | Yes | Your internal order ID (unique per org) |
external_id | string | No | Profile external_id (omit for anonymous POS orders) |
amount_cents | integer | Yes | Order total in cents |
currency | string | No | ISO 4217 currency code (default: USD) |
order_type | string | No | online, in_store, phone, other |
payment_method | string | No | card, cash, mobile, crypto, other |
item_count | integer | No | Number of items |
location_latitude | number | No | Order location latitude |
location_longitude | number | No | Order location longitude |
location_country | string | No | Country name |
location_city | string | No | City name |
location_name | string | No | Store/location name |
fingerprint_hash | string | No | Device fingerprint hash |
ip_hash | string | No | Hashed IP address |
edge_device_id | string | No | POS device ID (for in_store orders) |
cashier_external_id | string | No | Cashier profile external_id |
ordered_at | string | No | ISO 8601 datetime (defaults to now) |
items | array | No | Order line items (max 500) |
Order Item Object:
| Field | Type | Required | Description |
|---|---|---|---|
external_item_id | string | No | Your item ID |
item_category | string | No | Item category |
quantity | integer | Yes | Quantity |
unit_price_cents | integer | Yes | Unit price in cents |
total_price_cents | integer | Yes | Line total in cents |
discount_cents | integer | No | Discount amount in cents |
discount_type | string | No | none, percentage, fixed, override, employee |
Response:
{
"success": true,
"content": {
"order": {
"id": "uuid",
"external_order_id": "ORD-2026-001",
"status": "pending",
"ordered_at": "2026-04-13T10:30:00Z"
},
"risk": {
"risk_score": 67,
"risk_level": "high",
"signals": {
"velocity": 15,
"amount_anomaly": 18,
"location_anomaly": 12,
"device_anomaly": 10,
"time_anomaly": 7,
"pattern": 5
},
"flags": ["high_velocity", "amount_anomaly", "location_anomaly"],
"flagged_for_review": true
}
}
}
Bulk Submit Orders
POST /v1/orders/bulk
Submit up to 100 orders in a single request.
curl -X POST https://api.simplr-ai.com/v1/orders/bulk \
-H "X-API-Key: sk_live_xxxxx" \
-H "Content-Type: application/json" \
-d '{
"orders": [
{ "external_order_id": "ORD-001", "amount_cents": 5000, ... },
{ "external_order_id": "ORD-002", "amount_cents": 12000, ... }
]
}'
Cashier Actions
Submit Cashier Action
POST /v1/cashier/actions
Record a cashier action (void, refund, discount override, etc.) for fraud monitoring.
Auth: API Key (X-API-Key header)
curl -X POST https://api.simplr-ai.com/v1/cashier/actions \
-H "X-API-Key: sk_live_xxxxx" \
-H "Content-Type: application/json" \
-d '{
"cashier_external_id": "cashier-jane",
"action_type": "void",
"edge_device_id": "pos-terminal-42",
"amount_cents": 4500,
"reason": "Customer changed mind"
}'
| Field | Type | Required | Description |
|---|---|---|---|
cashier_external_id | string | Yes | Cashier profile external_id |
action_type | string | Yes | See action types below |
edge_device_id | string | No | POS device ID |
order_external_id | string | No | Related order ID |
amount_cents | integer | No | Amount in cents |
reason | string | No | Reason for the action (max 1000 chars) |
performed_at | string | No | ISO 8601 datetime (defaults to now) |
Action Types:
| Type | Description |
|---|---|
void | Cancel a transaction |
refund | Refund a previous transaction |
discount_override | Override an item's discount |
price_override | Override an item's price |
no_sale | Open cash drawer without a sale |
cash_drop | Remove cash from drawer to safe |
cash_pickup | Manager cash pickup |
drawer_open | Open drawer (other reason) |
shift_start | Cashier clocks in |
shift_end | Cashier clocks out |
Response:
{
"success": true,
"content": {
"action": {
"id": "uuid",
"action_type": "void",
"amount_cents": 4500,
"performed_at": "2026-04-13T14:30:00Z"
},
"fraud": {
"risk_score": 35,
"risk_level": "medium",
"signals": {
"excessive_voids": 15,
"excessive_refunds": 0,
"discount_abuse": 0,
"off_shift": 0,
"velocity_anomaly": 10,
"drawer_anomaly": 0,
"round_number_refund": 0
},
"flags": ["excessive_voids"]
}
}
}
Risk Scores
All risk scores follow the same 0-100 scale:
| Level | Score Range | Meaning |
|---|---|---|
low | 0-24 | Normal activity |
medium | 25-49 | Slightly unusual, monitor |
high | 50-69 | Suspicious, review recommended |
critical | 70-100 | Likely fraud, immediate action needed |
Orders scoring 50+ are automatically flagged for review in the dashboard.
Fraud Flags
When an order or action triggers specific fraud patterns, flags are returned:
| Flag | Meaning |
|---|---|
high_velocity | Too many orders in a short time window |
amount_anomaly | Amount significantly deviates from baseline |
location_anomaly | Unusual location or impossible travel |
device_anomaly | Multiple new devices or device sharing |
time_anomaly | Activity outside typical hours |
pattern_anomaly | Cross-org flags or suspicious payment changes |
excessive_voids | Cashier void count far above average |
excessive_refunds | Cashier refund count far above average |
discount_abuse | Cashier discount rate far above average |
off_shift_activity | Transaction outside shift hours |
drawer_anomaly | Too many no-sale drawer opens |
round_number_refund | Round-amount refund without matching order |
Webhook Events
| Event | Payload |
|---|---|
order.fraud.detected | Fired when an order scores 50+ risk |
order.fraud.alert | Fired when a pattern-based alert is created |
profile.risk.changed | Fired when a profile's risk level changes |
cashier.fraud.detected | Fired when a cashier action triggers fraud flags |
Billing
Each order submitted via POST /v1/orders consumes 1 credit. Cashier actions (POST /v1/cashier/actions) and profile creation (POST /v1/profiles) are free. Credits are deducted from your org balance every 5 minutes.