Create a user event for rules and fraud detection
curl --request POST \
--url http://api.gu1.ai/events/user \
--header 'Authorization: Bearer <token>' \
--header 'Content-Type: application/json' \
--data '
{
"eventType": "<string>",
"userId": "<string>",
"entityId": "<string>",
"entityExternalId": "<string>",
"taxId": "<string>",
"timestamp": "<string>",
"eventDate": "<string>",
"deviceId": "<string>",
"deviceDetails": {},
"ipAddress": "<string>",
"country": "<string>",
"isVpn": true,
"isProxy": true,
"isNewDevice": true,
"sessionId": "<string>",
"sdkSignals": {},
"failedAttemptsCount": 123,
"destinationAccountId": "<string>",
"destinationCuit": "<string>",
"previousValue": "<string>",
"metadata": {},
"userAgent": "<string>"
}
'import requests
url = "http://api.gu1.ai/events/user"
payload = {
"eventType": "<string>",
"userId": "<string>",
"entityId": "<string>",
"entityExternalId": "<string>",
"taxId": "<string>",
"timestamp": "<string>",
"eventDate": "<string>",
"deviceId": "<string>",
"deviceDetails": {},
"ipAddress": "<string>",
"country": "<string>",
"isVpn": True,
"isProxy": True,
"isNewDevice": True,
"sessionId": "<string>",
"sdkSignals": {},
"failedAttemptsCount": 123,
"destinationAccountId": "<string>",
"destinationCuit": "<string>",
"previousValue": "<string>",
"metadata": {},
"userAgent": "<string>"
}
headers = {
"Authorization": "Bearer <token>",
"Content-Type": "application/json"
}
response = requests.post(url, json=payload, headers=headers)
print(response.text)const options = {
method: 'POST',
headers: {Authorization: 'Bearer <token>', 'Content-Type': 'application/json'},
body: JSON.stringify({
eventType: '<string>',
userId: '<string>',
entityId: '<string>',
entityExternalId: '<string>',
taxId: '<string>',
timestamp: '<string>',
eventDate: '<string>',
deviceId: '<string>',
deviceDetails: {},
ipAddress: '<string>',
country: '<string>',
isVpn: true,
isProxy: true,
isNewDevice: true,
sessionId: '<string>',
sdkSignals: {},
failedAttemptsCount: 123,
destinationAccountId: '<string>',
destinationCuit: '<string>',
previousValue: '<string>',
metadata: {},
userAgent: '<string>'
})
};
fetch('http://api.gu1.ai/events/user', options)
.then(res => res.json())
.then(res => console.log(res))
.catch(err => console.error(err));<?php
$curl = curl_init();
curl_setopt_array($curl, [
CURLOPT_URL => "http://api.gu1.ai/events/user",
CURLOPT_RETURNTRANSFER => true,
CURLOPT_ENCODING => "",
CURLOPT_MAXREDIRS => 10,
CURLOPT_TIMEOUT => 30,
CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
CURLOPT_CUSTOMREQUEST => "POST",
CURLOPT_POSTFIELDS => json_encode([
'eventType' => '<string>',
'userId' => '<string>',
'entityId' => '<string>',
'entityExternalId' => '<string>',
'taxId' => '<string>',
'timestamp' => '<string>',
'eventDate' => '<string>',
'deviceId' => '<string>',
'deviceDetails' => [
],
'ipAddress' => '<string>',
'country' => '<string>',
'isVpn' => true,
'isProxy' => true,
'isNewDevice' => true,
'sessionId' => '<string>',
'sdkSignals' => [
],
'failedAttemptsCount' => 123,
'destinationAccountId' => '<string>',
'destinationCuit' => '<string>',
'previousValue' => '<string>',
'metadata' => [
],
'userAgent' => '<string>'
]),
CURLOPT_HTTPHEADER => [
"Authorization: Bearer <token>",
"Content-Type: application/json"
],
]);
$response = curl_exec($curl);
$err = curl_error($curl);
curl_close($curl);
if ($err) {
echo "cURL Error #:" . $err;
} else {
echo $response;
}package main
import (
"fmt"
"strings"
"net/http"
"io"
)
func main() {
url := "http://api.gu1.ai/events/user"
payload := strings.NewReader("{\n \"eventType\": \"<string>\",\n \"userId\": \"<string>\",\n \"entityId\": \"<string>\",\n \"entityExternalId\": \"<string>\",\n \"taxId\": \"<string>\",\n \"timestamp\": \"<string>\",\n \"eventDate\": \"<string>\",\n \"deviceId\": \"<string>\",\n \"deviceDetails\": {},\n \"ipAddress\": \"<string>\",\n \"country\": \"<string>\",\n \"isVpn\": true,\n \"isProxy\": true,\n \"isNewDevice\": true,\n \"sessionId\": \"<string>\",\n \"sdkSignals\": {},\n \"failedAttemptsCount\": 123,\n \"destinationAccountId\": \"<string>\",\n \"destinationCuit\": \"<string>\",\n \"previousValue\": \"<string>\",\n \"metadata\": {},\n \"userAgent\": \"<string>\"\n}")
req, _ := http.NewRequest("POST", url, payload)
req.Header.Add("Authorization", "Bearer <token>")
req.Header.Add("Content-Type", "application/json")
res, _ := http.DefaultClient.Do(req)
defer res.Body.Close()
body, _ := io.ReadAll(res.Body)
fmt.Println(string(body))
}HttpResponse<String> response = Unirest.post("http://api.gu1.ai/events/user")
.header("Authorization", "Bearer <token>")
.header("Content-Type", "application/json")
.body("{\n \"eventType\": \"<string>\",\n \"userId\": \"<string>\",\n \"entityId\": \"<string>\",\n \"entityExternalId\": \"<string>\",\n \"taxId\": \"<string>\",\n \"timestamp\": \"<string>\",\n \"eventDate\": \"<string>\",\n \"deviceId\": \"<string>\",\n \"deviceDetails\": {},\n \"ipAddress\": \"<string>\",\n \"country\": \"<string>\",\n \"isVpn\": true,\n \"isProxy\": true,\n \"isNewDevice\": true,\n \"sessionId\": \"<string>\",\n \"sdkSignals\": {},\n \"failedAttemptsCount\": 123,\n \"destinationAccountId\": \"<string>\",\n \"destinationCuit\": \"<string>\",\n \"previousValue\": \"<string>\",\n \"metadata\": {},\n \"userAgent\": \"<string>\"\n}")
.asString();require 'uri'
require 'net/http'
url = URI("http://api.gu1.ai/events/user")
http = Net::HTTP.new(url.host, url.port)
request = Net::HTTP::Post.new(url)
request["Authorization"] = 'Bearer <token>'
request["Content-Type"] = 'application/json'
request.body = "{\n \"eventType\": \"<string>\",\n \"userId\": \"<string>\",\n \"entityId\": \"<string>\",\n \"entityExternalId\": \"<string>\",\n \"taxId\": \"<string>\",\n \"timestamp\": \"<string>\",\n \"eventDate\": \"<string>\",\n \"deviceId\": \"<string>\",\n \"deviceDetails\": {},\n \"ipAddress\": \"<string>\",\n \"country\": \"<string>\",\n \"isVpn\": true,\n \"isProxy\": true,\n \"isNewDevice\": true,\n \"sessionId\": \"<string>\",\n \"sdkSignals\": {},\n \"failedAttemptsCount\": 123,\n \"destinationAccountId\": \"<string>\",\n \"destinationCuit\": \"<string>\",\n \"previousValue\": \"<string>\",\n \"metadata\": {},\n \"userAgent\": \"<string>\"\n}"
response = http.request(request)
puts response.read_body{
"success": true,
"event": {
"event.id": "<string>",
"event.eventType": "<string>",
"event.userId": "<string>",
"event.entityId": "<string>",
"event.entityExternalId": "<string>",
"event.taxId": "<string>",
"event.timestamp": "<string>",
"event.eventDate": "<string>",
"event.deviceId": "<string>",
"event.ipAddress": "<string>",
"event.country": "<string>",
"event.createdAt": "<string>"
},
"entity": {
"entity.id": "<string>",
"entity.wasCreated": true
},
"rulesResult": {},
"rulesExecutionSummary": {}
}API Reference
Create a user event for rules and fraud detection
Create a user event for fraud detection and rule validation β for user behavior tracking and rule-based fraud detection in gu1, with examples for create use.
POST
/
events
/
user
Create a user event for rules and fraud detection
curl --request POST \
--url http://api.gu1.ai/events/user \
--header 'Authorization: Bearer <token>' \
--header 'Content-Type: application/json' \
--data '
{
"eventType": "<string>",
"userId": "<string>",
"entityId": "<string>",
"entityExternalId": "<string>",
"taxId": "<string>",
"timestamp": "<string>",
"eventDate": "<string>",
"deviceId": "<string>",
"deviceDetails": {},
"ipAddress": "<string>",
"country": "<string>",
"isVpn": true,
"isProxy": true,
"isNewDevice": true,
"sessionId": "<string>",
"sdkSignals": {},
"failedAttemptsCount": 123,
"destinationAccountId": "<string>",
"destinationCuit": "<string>",
"previousValue": "<string>",
"metadata": {},
"userAgent": "<string>"
}
'import requests
url = "http://api.gu1.ai/events/user"
payload = {
"eventType": "<string>",
"userId": "<string>",
"entityId": "<string>",
"entityExternalId": "<string>",
"taxId": "<string>",
"timestamp": "<string>",
"eventDate": "<string>",
"deviceId": "<string>",
"deviceDetails": {},
"ipAddress": "<string>",
"country": "<string>",
"isVpn": True,
"isProxy": True,
"isNewDevice": True,
"sessionId": "<string>",
"sdkSignals": {},
"failedAttemptsCount": 123,
"destinationAccountId": "<string>",
"destinationCuit": "<string>",
"previousValue": "<string>",
"metadata": {},
"userAgent": "<string>"
}
headers = {
"Authorization": "Bearer <token>",
"Content-Type": "application/json"
}
response = requests.post(url, json=payload, headers=headers)
print(response.text)const options = {
method: 'POST',
headers: {Authorization: 'Bearer <token>', 'Content-Type': 'application/json'},
body: JSON.stringify({
eventType: '<string>',
userId: '<string>',
entityId: '<string>',
entityExternalId: '<string>',
taxId: '<string>',
timestamp: '<string>',
eventDate: '<string>',
deviceId: '<string>',
deviceDetails: {},
ipAddress: '<string>',
country: '<string>',
isVpn: true,
isProxy: true,
isNewDevice: true,
sessionId: '<string>',
sdkSignals: {},
failedAttemptsCount: 123,
destinationAccountId: '<string>',
destinationCuit: '<string>',
previousValue: '<string>',
metadata: {},
userAgent: '<string>'
})
};
fetch('http://api.gu1.ai/events/user', options)
.then(res => res.json())
.then(res => console.log(res))
.catch(err => console.error(err));<?php
$curl = curl_init();
curl_setopt_array($curl, [
CURLOPT_URL => "http://api.gu1.ai/events/user",
CURLOPT_RETURNTRANSFER => true,
CURLOPT_ENCODING => "",
CURLOPT_MAXREDIRS => 10,
CURLOPT_TIMEOUT => 30,
CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
CURLOPT_CUSTOMREQUEST => "POST",
CURLOPT_POSTFIELDS => json_encode([
'eventType' => '<string>',
'userId' => '<string>',
'entityId' => '<string>',
'entityExternalId' => '<string>',
'taxId' => '<string>',
'timestamp' => '<string>',
'eventDate' => '<string>',
'deviceId' => '<string>',
'deviceDetails' => [
],
'ipAddress' => '<string>',
'country' => '<string>',
'isVpn' => true,
'isProxy' => true,
'isNewDevice' => true,
'sessionId' => '<string>',
'sdkSignals' => [
],
'failedAttemptsCount' => 123,
'destinationAccountId' => '<string>',
'destinationCuit' => '<string>',
'previousValue' => '<string>',
'metadata' => [
],
'userAgent' => '<string>'
]),
CURLOPT_HTTPHEADER => [
"Authorization: Bearer <token>",
"Content-Type: application/json"
],
]);
$response = curl_exec($curl);
$err = curl_error($curl);
curl_close($curl);
if ($err) {
echo "cURL Error #:" . $err;
} else {
echo $response;
}package main
import (
"fmt"
"strings"
"net/http"
"io"
)
func main() {
url := "http://api.gu1.ai/events/user"
payload := strings.NewReader("{\n \"eventType\": \"<string>\",\n \"userId\": \"<string>\",\n \"entityId\": \"<string>\",\n \"entityExternalId\": \"<string>\",\n \"taxId\": \"<string>\",\n \"timestamp\": \"<string>\",\n \"eventDate\": \"<string>\",\n \"deviceId\": \"<string>\",\n \"deviceDetails\": {},\n \"ipAddress\": \"<string>\",\n \"country\": \"<string>\",\n \"isVpn\": true,\n \"isProxy\": true,\n \"isNewDevice\": true,\n \"sessionId\": \"<string>\",\n \"sdkSignals\": {},\n \"failedAttemptsCount\": 123,\n \"destinationAccountId\": \"<string>\",\n \"destinationCuit\": \"<string>\",\n \"previousValue\": \"<string>\",\n \"metadata\": {},\n \"userAgent\": \"<string>\"\n}")
req, _ := http.NewRequest("POST", url, payload)
req.Header.Add("Authorization", "Bearer <token>")
req.Header.Add("Content-Type", "application/json")
res, _ := http.DefaultClient.Do(req)
defer res.Body.Close()
body, _ := io.ReadAll(res.Body)
fmt.Println(string(body))
}HttpResponse<String> response = Unirest.post("http://api.gu1.ai/events/user")
.header("Authorization", "Bearer <token>")
.header("Content-Type", "application/json")
.body("{\n \"eventType\": \"<string>\",\n \"userId\": \"<string>\",\n \"entityId\": \"<string>\",\n \"entityExternalId\": \"<string>\",\n \"taxId\": \"<string>\",\n \"timestamp\": \"<string>\",\n \"eventDate\": \"<string>\",\n \"deviceId\": \"<string>\",\n \"deviceDetails\": {},\n \"ipAddress\": \"<string>\",\n \"country\": \"<string>\",\n \"isVpn\": true,\n \"isProxy\": true,\n \"isNewDevice\": true,\n \"sessionId\": \"<string>\",\n \"sdkSignals\": {},\n \"failedAttemptsCount\": 123,\n \"destinationAccountId\": \"<string>\",\n \"destinationCuit\": \"<string>\",\n \"previousValue\": \"<string>\",\n \"metadata\": {},\n \"userAgent\": \"<string>\"\n}")
.asString();require 'uri'
require 'net/http'
url = URI("http://api.gu1.ai/events/user")
http = Net::HTTP.new(url.host, url.port)
request = Net::HTTP::Post.new(url)
request["Authorization"] = 'Bearer <token>'
request["Content-Type"] = 'application/json'
request.body = "{\n \"eventType\": \"<string>\",\n \"userId\": \"<string>\",\n \"entityId\": \"<string>\",\n \"entityExternalId\": \"<string>\",\n \"taxId\": \"<string>\",\n \"timestamp\": \"<string>\",\n \"eventDate\": \"<string>\",\n \"deviceId\": \"<string>\",\n \"deviceDetails\": {},\n \"ipAddress\": \"<string>\",\n \"country\": \"<string>\",\n \"isVpn\": true,\n \"isProxy\": true,\n \"isNewDevice\": true,\n \"sessionId\": \"<string>\",\n \"sdkSignals\": {},\n \"failedAttemptsCount\": 123,\n \"destinationAccountId\": \"<string>\",\n \"destinationCuit\": \"<string>\",\n \"previousValue\": \"<string>\",\n \"metadata\": {},\n \"userAgent\": \"<string>\"\n}"
response = http.request(request)
puts response.read_body{
"success": true,
"event": {
"event.id": "<string>",
"event.eventType": "<string>",
"event.userId": "<string>",
"event.entityId": "<string>",
"event.entityExternalId": "<string>",
"event.taxId": "<string>",
"event.timestamp": "<string>",
"event.eventDate": "<string>",
"event.deviceId": "<string>",
"event.ipAddress": "<string>",
"event.country": "<string>",
"event.createdAt": "<string>"
},
"entity": {
"entity.id": "<string>",
"entity.wasCreated": true
},
"rulesResult": {},
"rulesExecutionSummary": {}
}Overview
Creates a new user event to track actions and behaviors within your application. Events are used for fraud detection, compliance monitoring, behavioral analytics, and audit trails. The system automatically registers devices, can optionally create entities when they donβt exist, and runs the rules engine to evaluate risk. The response includesrulesResult and rulesExecutionSummary when rules are triggered.
π Events automatically register devices when
deviceId and deviceDetails are provided, eliminating the need for separate device management.Endpoint
POST https://api.gu1.ai/events/user
Authentication
Requires a valid API key in the Authorization header:Authorization: Bearer YOUR_API_KEY
Query Parameters
boolean
default:"false"
Enable automatic entity creation when an entity with the provided
taxId doesnβt exist. When true, if the event includes a taxId and no entity exists with that tax ID, a new person or company entity will be automatically created.Example: ?withAutoEntity=trueRequest Body
string
required
Type of event being tracked. Must be one of the supported event types (see Event Types section below), including authentication, transfers, biometric validation, and more.Example:
"LOGIN_SUCCESS"string
Your internal user identifier. Used to group events by user across different entities.Example:
"user_12345"string
gu1βs entity UUID. Provide this if you have the internal gu1 ID.
Entity Identification: You must provide at least ONE of:
entityId, entityExternalId, or taxId. These fields support OR logic, so the system will find the entity using any of these identifiers. SDK exception: organizations with the SDK enabled may instead send only a sessionId for anonymous pre-login events.string
Your external entity identifier. This is your unique ID for the entity in your system.Example:
"user_12345"string
Tax identification number (CPF, CNPJ, CUIT, etc.). When combined with
?withAutoEntity=true, this will create the entity if it doesnβt exist.Example: "20242455496"string
When the event occurred in ISO 8601 datetime format. If not provided, defaults to the current server time.Example:
"2026-01-30T14:30:00Z"string
Business date for the event. Used by historical rules as the starting point for time windows (e.g. βlast 7 daysβ is calculated backwards from this date).Format: ISO 8601 datetime string with timezone (e.g.
"2026-01-30T14:30:00Z" or "2026-01-30T00:00:00.000Z").If you donβt send it: The system uses the same value as timestamp (or the current server time if neither is sent). So the event is treated as βnowβ for historical rulesβno need to send it when the event is real-time.- Omitted β We set
eventDate = timestamp(or now). Historical rules use that as the starting point. - Format β ISO 8601 with timezone:
"YYYY-MM-DDTHH:mm:ss.sssZ"(e.g."2026-01-30T00:00:00.000Z"). - When to send β When the event actually happened on a different date than when youβre sending it (e.g. backfilled or batch events).
string
Unique identifier for the device. This should be a stable identifier that persists across sessions.Example:
"840e89e4d46efd67"object
Detailed device information. When provided, the device will be automatically registered or updated.Structure:
{
"platform": "android",
"osName": "Android",
"osVersion": "Android 16",
"manufacturer": "samsung",
"model": "SM-A156M",
"brand": "samsung",
"browser": "Chrome",
"browserVersion": "120.0.6099.129",
"latitude": -34.6037,
"longitude": -58.3816,
"city": "Buenos Aires",
"region": "Buenos Aires",
"country": "Argentina",
"countryCode": "AR",
"additionalDetails": {}
}
string
IP address from which the event originated (IPv4 or IPv6).Example:
"10.40.64.231"string
ISO 3166-1 alpha-2 country code where the event occurred.Example:
"AR"boolean
default:"false"
Whether the connection is through a VPN
boolean
default:"false"
Whether the connection is through a proxy
boolean
New device flag stored on the event (
is_new_device in the database). See How isNewDevice works below.string
SDK session identifier (
sess_..., max 64 chars). For organizations with the SDK enabled, an event carrying only a sessionId (no entity identifier) is accepted and persisted as an anonymous pre-login event; it is linked to the entity later on the first event that carries both sessionId and an entity identifier. Without the SDK enabled, an entity identifier is still required.Example: "sess_a1b2c3d4"object
Structured signals emitted by the SDK (kept separate from free-form
metadata). All fields optional: sessionId, sessionDuration, integrityScore (0β100), integrityFlags (fetchHooked, prototypeModified, debuggerAttached, framingDetected), and behavioralSignals (keystrokeAvgMs, pasteDetected, completionTimeMs, touchVelocity).number
default:"0"
Number of failed authentication attempts (for authentication events)Example:
3string
Destination account identifier for transfer events (CBU, CVU, etc.)Example:
"0170042640000004234411"string
Destination CUIT for transfer eventsExample:
"27281455496"string
Previous value for credential change events. This will be automatically hashed using SHA-256 for security.Example:
"old_password_hash"object
Additional event-specific data as key-value pairs. Use this for custom fields specific to your use case.Example:
{
"amount": 5000,
"currency": "ARS",
"concept": "Payment",
"reference": "INV-12345"
}
string
Browser user agent string for web eventsExample:
"Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36..."How isNewDevice works
The persisted value on each event drives fraud rules (for example historical.userEvent.newDevice and filters like isNewDevice: true on user_events).
Priority: your value wins when you send it
| Request | Persisted isNewDevice |
|---|---|
You send isNewDevice: true or false | Exactly what you sent (gu1 does not override it) |
You omit isNewDevice | gu1 computes a value (see below); defaults to false when device data is insufficient |
When you omit isNewDevice (server-side inference)
gu1 only auto-computes when both are present:
deviceIddeviceDetails
- Register or update the device for the resolved entity (
devicestable). - Set
isNewDevicetotrueif either:- No row exists yet for
(organization, entity, deviceId), or - The device exists but
firstSeenAtis within the last 5 minutes (first-seen window).
- No row exists yet for
- Otherwise set
isNewDevicetofalse(device already known to gu1 for that entity).
Send
deviceId + deviceDetails on login and security-sensitive events even when you set isNewDevice yourself, so gu1 keeps the device registry up to date for other rules and audits.Request body field name
POST /events/user uses camelCase in JSON: isNewDevice. The snake_case name is_new_device is not read on this endpoint (use camelCase).
Examples
Client decides (recommended when you already detect new device):{
"eventType": "LOGIN_SUCCESS",
"taxId": "20242455496",
"deviceId": "840e89e4d46efd67",
"isNewDevice": true
}
{
"eventType": "LOGIN_SUCCESS",
"taxId": "20242455496",
"deviceId": "840e89e4d46efd67",
"deviceDetails": { "platform": "android", "manufacturer": "samsung", "model": "SM-A156M" }
}
Event Types
π Choose the most specific event type that matches your use case. Use
OTHER_EVENT only when no specific type applies.Authentication Events
LOGIN_SUCCESS- Successful loginLOGIN_FAILED- Failed login attemptLOGOUT- User logoutTOKEN_GENERATED- Authentication token generated
Credential Change Events
PASSWORD_CHANGE- Password successfully changedPASSWORD_CHANGE_FAILED- Failed password change attemptEMAIL_CHANGE- Email address changedPHONE_CHANGE- Phone number changedPIN_CHANGE- PIN changed
Account Management Events
ACCOUNT_LINKED- Bank account linkedCONTACT_CREATED- Contact createdCONTACT_DELETED- Contact deletedADDRESS_CHANGED- Address updatedDEVICE_ADDED- New device addedDEVICE_DELETED- Device removed
Email Management Events
EMAIL_CREATED- Email createdEMAIL_ELIMINATED- Email eliminated
Navigation Events
NAVIGATION- Page or screen navigation
Transfer Events
TRANSFER_SUCCESS- Successful transferTRANSFER_FAILED- Failed transfer attemptTRANSFER_SCHEDULED- Transfer scheduled for future
Balance Events
BALANCE_CHECK- Account balance checkedBALANCE_CHECK_FAILED- Balance check failed
Account Access Events
ACCOUNTS_VIEW- Accounts list viewedACCOUNTS_VIEW_FAILED- Accounts view failed
Transaction Events
TRANSACTIONS_VIEW- Transaction history viewedTRANSACTIONS_VIEW_FAILED- Transaction view failed
Recipient Events
SEARCH_RECIPIENTS- Recipients searchedSEARCH_RECIPIENTS_FAILED- Recipients search failedSCHEDULE_RECIPIENT_FAILED- Recipient scheduling failed
Profile Events
PROFILE_VIEW- User profile viewedPROFILE_UPDATED- User profile updated
Message Events
MESSAGES_VIEW- Messages viewedMESSAGES_VIEW_FAILED- Messages view failed
Account Holder Events
ACCOUNT_HOLDERS_VIEW- Account holders viewedACCOUNT_HOLDERS_VIEW_FAILED- Account holders view failed
Alias Events
ALIAS_VIEW- Alias viewedALIAS_VIEW_FAILED- Alias view failedALIAS_CHANGE- Alias changedALIAS_CHANGE_FAILED- Alias change failed
Payment / Device Events
CARD_ADDED- Payment card addedDEVICE_CONNECTED- Device connected
Biometric Validation Events
BIOMETRIC_VALIDATION_SUCCESS- Biometric validation succeededBIOMETRIC_VALIDATION_ERROR- Biometric validation failed
SDK Events
SESSION_STARTED- SDK session beacon (pre-login)SESSION_IDENTIFIED- Session bound to an entity (sent with bothsessionIdand an entity identifier)SCREEN_VIEW- Screen/navigation tracked by the SDK
Other Events
OTHER_EVENT- Custom or generic event
Response
boolean
Indicates if the request was successful
object
The created event object
string
gu1βs internal event UUID
string
Type of event created
string
User identifier
string
Associated entity UUID
string
External entity identifier
string
Tax identification number
string
Event timestamp (ISO 8601)
string
Business date used by historical rules for time windows (ISO 8601). Equals timestamp when not sent.
string
Device identifier
string
IP address
string
Country code
string
Event record creation timestamp
object
object
Result of rules execution if the rules engine was triggered for this event. Includes:
- success (boolean) - Whether rules executed successfully
- rulesTriggered (number) - Number of rules that were triggered
- alerts (array) - Alerts generated by rules
- riskScore (number) - Final calculated risk score
- decision (string) - Final decision (APPROVE, REJECT, HOLD, REVIEW_REQUIRED)
- rulesExecutionSummary (object) - Detailed summary; see below.
object
Only present when the rules engine ran for this event. Summary of which rules matched (hit) vs did not match (no hit), executed actions, and total score. See Rules Execution Summary for the full structure and a complete example.
- rulesHit (array) - Rules whose conditions were met. Each item: name, description, score, priority, category, status, conditions, actions.
- rulesNoHit (array) - Rules evaluated but conditions not met. Same structure as rulesHit.
- actionsExecuted (object) - Aggregated executed actions: alerts, suggestion, status, assignedUser, customKeys (array of strings, optional) β custom action keys from rules that matched (e.g.
require_kyc,flag_for_review); for integrations/workflows. - totalScore (number) - Sum of score of all rules that hit (excluding shadow).
Examples
Login Event
curl -X POST https://api.gu1.ai/events/user \
-H "Authorization: Bearer YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"eventType": "LOGIN_SUCCESS",
"entityExternalId": "user_12345",
"userId": "user_12345",
"deviceId": "840e89e4d46efd67",
"ipAddress": "10.40.64.231",
"country": "AR",
"deviceDetails": {
"platform": "android",
"manufacturer": "samsung",
"model": "SM-A156M",
"osVersion": "Android 16"
}
}'
const response = await fetch('https://api.gu1.ai/events/user', {
method: 'POST',
headers: {
'Authorization': 'Bearer YOUR_API_KEY',
'Content-Type': 'application/json'
},
body: JSON.stringify({
eventType: 'LOGIN_SUCCESS',
entityExternalId: 'user_12345',
userId: 'user_12345',
deviceId: '840e89e4d46efd67',
ipAddress: '10.40.64.231',
country: 'AR',
deviceDetails: {
platform: 'android',
manufacturer: 'samsung',
model: 'SM-A156M',
osVersion: 'Android 16'
}
})
});
const data = await response.json();
console.log(data);
import requests
response = requests.post(
'https://api.gu1.ai/events/user',
headers={
'Authorization': 'Bearer YOUR_API_KEY',
'Content-Type': 'application/json'
},
json={
'eventType': 'LOGIN_SUCCESS',
'entityExternalId': 'user_12345',
'userId': 'user_12345',
'deviceId': '840e89e4d46efd67',
'ipAddress': '10.40.64.231',
'country': 'AR',
'deviceDetails': {
'platform': 'android',
'manufacturer': 'samsung',
'model': 'SM-A156M',
'osVersion': 'Android 16'
}
}
)
data = response.json()
print(data)
Transfer Event
curl -X POST https://api.gu1.ai/events/user \
-H "Authorization: Bearer YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"eventType": "TRANSFER_SUCCESS",
"entityExternalId": "user_12345",
"destinationAccountId": "0170042640000004234411",
"destinationCuit": "27281455496",
"metadata": {
"amount": 5000,
"currency": "ARS",
"concept": "Payment"
}
}'
const response = await fetch('https://api.gu1.ai/events/user', {
method: 'POST',
headers: {
'Authorization': 'Bearer YOUR_API_KEY',
'Content-Type': 'application/json'
},
body: JSON.stringify({
eventType: 'TRANSFER_SUCCESS',
entityExternalId: 'user_12345',
destinationAccountId: '0170042640000004234411',
destinationCuit: '27281455496',
metadata: {
amount: 5000,
currency: 'ARS',
concept: 'Payment'
}
})
});
import requests
response = requests.post(
'https://api.gu1.ai/events/user',
headers={'Authorization': 'Bearer YOUR_API_KEY'},
json={
'eventType': 'TRANSFER_SUCCESS',
'entityExternalId': 'user_12345',
'destinationAccountId': '0170042640000004234411',
'destinationCuit': '27281455496',
'metadata': {
'amount': 5000,
'currency': 'ARS',
'concept': 'Payment'
}
}
)
Auto-Create Entity
curl -X POST "https://api.gu1.ai/events/user?withAutoEntity=true" \
-H "Authorization: Bearer YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"eventType": "LOGIN_SUCCESS",
"taxId": "20242455496",
"userId": "user_12345"
}'
const response = await fetch('https://api.gu1.ai/events/user?withAutoEntity=true', {
method: 'POST',
headers: {
'Authorization': 'Bearer YOUR_API_KEY',
'Content-Type': 'application/json'
},
body: JSON.stringify({
eventType: 'LOGIN_SUCCESS',
taxId: '20242455496',
userId: 'user_12345'
})
});
import requests
response = requests.post(
'https://api.gu1.ai/events/user?withAutoEntity=true',
headers={'Authorization': 'Bearer YOUR_API_KEY'},
json={
'eventType': 'LOGIN_SUCCESS',
'taxId': '20242455496',
'userId': 'user_12345'
}
)
Response Example
{
"success": true,
"event": {
"id": "3fa85f64-5717-4562-b3fc-2c963f66afa6",
"eventType": "LOGIN_SUCCESS",
"userId": "user_12345",
"entityId": "550e8400-e29b-41d4-a716-446655440000",
"entityExternalId": "user_12345",
"taxId": "20242455496",
"timestamp": "2026-01-30T14:30:00Z",
"deviceId": "840e89e4d46efd67",
"ipAddress": "10.40.64.231",
"country": "AR",
"createdAt": "2026-01-30T14:30:00Z"
},
"entity": {
"id": "550e8400-e29b-41d4-a716-446655440000",
"wasCreated": false
},
"rulesResult": {
"success": true,
"rulesTriggered": 1,
"alerts": [],
"riskScore": 10,
"decision": "APPROVE",
"rulesExecutionSummary": {
"rulesHit": [
{
"name": "Suspicious Login Pattern",
"score": 10,
"category": "authentication",
"actions": ["create_alert"]
}
],
"rulesNoHit": [],
"actionsExecuted": {
"alerts": 0
},
"totalScore": 10
}
},
"rulesExecutionSummary": {
"rulesHit": [
{
"name": "Suspicious Login Pattern",
"score": 10,
"category": "authentication",
"actions": ["create_alert"]
}
],
"rulesNoHit": [],
"actionsExecuted": {
"alerts": 0
},
"totalScore": 10
}
}
Error Responses
400 Bad Request
{
"success": false,
"error": {
"code": "VALIDATION_ERROR",
"message": "At least one entity identifier is required: entityId, entityExternalId, or taxId"
}
}
401 Unauthorized
{
"success": false,
"error": {
"code": "UNAUTHORIZED",
"message": "Invalid or missing API key"
}
}
403 Forbidden
{
"success": false,
"error": {
"code": "FORBIDDEN",
"message": "Insufficient permissions to create events"
}
}
404 Not Found
{
"success": false,
"error": {
"code": "ENTITY_NOT_FOUND",
"message": "Entity not found. Use ?withAutoEntity=true to auto-create entities."
}
}
500 Internal Server Error
{
"success": false,
"error": {
"code": "EVENT_CREATE_FAILED",
"message": "Failed to create event"
}
}
Use Cases
Track Authentication Patterns
// Track successful and failed logins
await createEvent({
eventType: 'LOGIN_SUCCESS',
entityExternalId: userId,
deviceId: deviceFingerprint,
ipAddress: req.ip
});
// Failed login with attempt count
await createEvent({
eventType: 'LOGIN_FAILED',
entityExternalId: userId,
failedAttemptsCount: 3
});
Monitor Transfer Activity
// Track transfers for fraud detection
await createEvent({
eventType: 'TRANSFER_SUCCESS',
entityExternalId: userId,
destinationAccountId: destinationAccount,
metadata: {
amount: transferAmount,
currency: 'ARS'
}
});
Compliance Audit Trail
// Track all profile changes
await createEvent({
eventType: 'PROFILE_UPDATED',
entityExternalId: userId,
metadata: {
fieldsChanged: ['email', 'phone'],
previousEmail: 'old@example.com',
newEmail: 'new@example.com'
}
});
Best Practices
Always Include Timestamps
Provide explicit timestamps when events are queued or buffered to maintain accurate chronological ordering.Track Both Success and Failure
Always track both successful and failed events for comprehensive fraud detection and analytics.Use Structured Metadata
Keep metadata consistent across similar event types to enable better analysis and querying.Device information and isNewDevice
Always include deviceId and deviceDetails when available so gu1 can maintain the device registry. Set isNewDevice explicitly when your integration already classifies new devices; otherwise omit it and let gu1 infer (see How isNewDevice works).
Handle Auto-Creation Carefully
UsewithAutoEntity=true only when youβre confident the tax ID is valid and you want entities created automatically.
Next Steps
List Events
Query events with filters
Event Statistics
Get aggregated statistics
Devices API
Learn about device integration
Fraud Rules
Build rules using event data
Was this page helpful?