User Endpoints
The following outlines the endpoints for posting, updating and managing statuses of users registered within the Orca system. These endpoints do not initiate User risk screening, which must be done using the Onboard request instead of the User request.
If you have any additional fields you capture when onboarding a user, feel free to let us know at support@orca-fraud.com
Create or Update User
Submit user information to create a new user or update an existing one.
Endpoint: POST /v1/user
Request Schema
| Field | Type | Required | Description |
|---|---|---|---|
id | string | Yes | Unique user identifier |
createdAt | number | No | Date user was created, Unix timestamp in milliseconds |
firstName | string | No | User’s first name |
lastName | string | No | User’s last name |
dateOfBirth | string | No | ISO format date (YYYY-MM-DD) |
address | object | No | User’s address details |
company | string | No | Company name for grouping users |
phone.phone | string | No | Phone number in E.164 format |
phone.country | string | No | ISO 3166-1 alpha-2 country code |
phone.isVerified | boolean | No | Whether phone has been verified |
email.email | string | No | User’s email address |
email.isVerified | boolean | No | Whether email has been verified |
documents | array | No | User identification documents |
lastLogin | number | No | Timestamp of last user login |
userDevice | object | No | User’s device information, if not sent using /userDevice endpoint |
status | enum | No | User status: ACTIVE, INACTIVE, BLOCKED |
amlDetail.amlStatus | string | No | AML verification status |
amlDetail.amlSource | string | No | Source of AML verification |
kycDetail.sourceOfIncome | string | No | User’s income source |
kycDetail.kycStatus | string | No | KYC verification status |
kycDetail.kycSource | string | No | Source of KYC verification |
kycDetail.kycStatusMessage | string | No | Additional KYC status details |
salary.cycle | enum | No | Salary payment frequency: weekly, bi-weekly, monthly, if applicable |
salary.amount | number | No | Salary amount, if applicable |
salary.currency | string | No | Salary currency code, if applicable |
referralCode | string | No | Referral code of user, if applicable |
referrerCode | string | No | Referral code used by user to register, if applicable |
Request Body
{
"id": "USER123",
"firstName": "John",
"lastName": "Doe",
"dateOfBirth": "1990-01-01",
"email": {
"email": "john@example.com",
"isVerified": false
},
"lastLogin": 1734167723000
}Responses
200: User processed successfully400: Bad request500: Internal server error
Submit User Feedback
Submit feedback to update user status and details after user onboarding.
Endpoint: POST /v1/user/feedback
Request Body
{
"userId": "USER123",
"onboardingFeedback": {
"id": "FEEDBACK123",
"status": "APPROVED",
"description": "All verification checks passed",
"createdAt": 1734167723000,
"type": "KYC"
},
"kycDetail": {
"sourceOfIncome": "employment",
"kycStatus": "verified",
"kycSource": "jumio",
"kycStatusMessage": "Identity verified successfully"
},
"amlDetail": {
"amlStatus": "cleared",
"amlSource": "refinitiv"
}
}Error Response Format
See the Error Reference section for a full description of API errors. All API errors follow a consistent JSON structure:
{
"error": {
"type": "ERROR_TYPE",
"message": "Human-readable error description",
"details": ["Additional error details (optional)"]
},
"timestamp": 1755602195137
}In the case of a validation error, the format will be as follows:
{
"error": {
"type": "VALIDATION_ERROR",
"message": "Request validation failed",
"details": [
"/id: Expected string"
]
},
"timestamp": 1755602195137
}Get User by ID
Retrieve a specific user’s information by their ID.
Endpoint: GET /v1/users/{userId}
Parameters
| Parameter | Type | Required | Description |
|---|---|---|---|
userId | string | Yes | Unique identifier for the user |
Response Example
{
"user": {
"id": "USER123",
"createdAt": 1734067723000,
"updatedAt": 1734167723000,
"firstName": "John",
"lastName": "Doe",
"status": "active",
"reason": "User previously blocked for suspicious activity"
}
}Responses
200: User retrieved successfully404: User not found500: Internal server error
Get User by Transaction ID
Retrieve user information associated with a specific transaction.
Endpoint: GET /v1/users/transactions/{transactionId}
Parameters
| Parameter | Type | Required | Description |
|---|---|---|---|
transactionId | string | Yes | Unique identifier for the transaction |
Response Example
{
"user": {
"id": "USER123",
"createdAt": 1734067723000,
"updatedAt": 1734167723000,
"firstName": "John",
"lastName": "Doe",
"status": "active",
"reason": "User previously blocked for suspicious activity"
}
}Responses
200: User information retrieved successfully404: Transaction or associated user not found500: Internal server error
Block User
Block a specific user by their ID.
Endpoint: PUT /v1/users/{userId}/block
Request Body
{
"comment": "Suspicious activity detected",
"reviewer": "john.smith"
}Responses
200: User blocked successfully404: User not found500: Internal server error
Unblock User
Unblock a specific user by their ID.
Endpoint: PUT /v1/users/{userId}/unblock
Request Body
{
"comment": "User verified identity",
"reviewer": "jane.doe"
}Responses
200: User unblocked successfully404: User not found500: Internal server error
Update User Status
Update a specific user’s status, this can be used instead of or in addition to the /block and /unblock endpoints.
Endpoint: PUT /v1/users/{userId}/status
Parameters
| Parameter | Type | Required | Description |
|---|---|---|---|
userId | string | Yes | Unique identifier for the user |
Request Schema
| Field | Type | Required | Description |
|---|---|---|---|
status | enum | No | User status: active, inactive |
completedAt | number | No | Timestamp when status change was completed |
closureType | string | No | Closure reason: sling_initiated, user_requested, user_requested_with_data_deletion |
comment | string | No | Additional details about status change |
initiatedBy | string | No | Person or system initiating the status change |
reason | string | No | Predefined reason code: NO_REASON, FINANCIAL_CRIME, RISK_TOLERANCE, FRAUDULENT_ACTIVITY, LINKED_TO_FRAUD |
Request Body Example
{
"status": "inactive",
"closureType": "user_requested",
"comment": "User requested account closure",
"initiatedBy": "support.team",
"reason": "NO_REASON",
"completedAt": 1734167723000
}Responses
200: User status updated successfully404: User not found500: Internal server error
Get Blocked Users
Retrieve a list of blocked users with pagination support.
Endpoint: GET /v1/users/blocked
Query Parameters
start(optional): Cursor for paginationlimit(optional): Number of users to return (1-100, default: 100)
Response Example
{
"users": [
{
"id": "USER123",
"status": "BLOCKED",
"updatedAt": 1734167723000
},
{
"id": "USER456",
"status": "BLOCKED",
"updatedAt": 1734167723000
}
],
"total": 45,
"cursor": "USER456"
}Responses
200: List of blocked users retrieved successfully400: Bad request500: Internal server error
Update Transaction User Status
Update the status of users involved in a specific transaction.
Endpoint: PUT /v1/users/transactions/{transactionId}/status
Parameters
| Parameter | Type | Required | Description |
|---|---|---|---|
transactionId | string | Yes | Unique identifier for the transaction |
Request Schema
| Field | Type | Required | Description |
|---|---|---|---|
status | enum | No | User status to apply: ACTIVE, INACTIVE, BLOCKED |
parties | enum | No | Which parties to update: both, user, recipient (defaults to user) |
comment | string | No | Additional details about status change |
reviewer | string | No | Person or system initiating the status change |
Request Body Example
{
"status": "BLOCKED",
"parties": "user",
"comment": "Fraudulent transaction detected",
"reviewer": "fraud.detection.team"
}Responses
200: User status updated successfully404: Transaction not found500: Internal server error
Update Users by Attribute
Update the status of all users that match a specific attribute. This is useful for blocking users with shared suspicious attributes.
Endpoint: PUT /v1/users/attributes/status
Request Schema
| Field | Type | Required | Description |
|---|---|---|---|
attribute | enum | Yes | Attribute to match: phone, email, ipAddress, deviceFingerprint, bankAccountNumber, cryptoAddress, walletTaxNumberId, walletPhone, cardFingerprint |
value | string | Yes | Value of the attribute to match |
status | enum | No | Status to apply to matching users: ACTIVE, INACTIVE, BLOCKED |
comment | string | No | Additional details about status change |
reviewer | string | No | Person or system initiating the status change |
Request Body Example
{
"attribute": "deviceFingerprint",
"value": "fp_abcdef123456",
"status": "BLOCKED",
"comment": "Device linked to multiple fraudulent accounts",
"reviewer": "risk.team"
}Responses
200: Users updated successfully400: Invalid attribute specified404: No users found matching the attribute500: Internal server error
Schema Definitions
User Schema
interface User {
id: string; // Unique transaction identifier
createdAt?: number; // Unix timestamp in milliseconds
firstName?: string;
lastName?: string;
dateOfBirth?: string; // Required for age-related rules
address?: Address;
company?: string; // Company name for grouping users
phone?: {
phone: string; // E.164 formatted
country: string; // ISO 3166-1 alpha-2
isVerified?: boolean;
};
email?: {
email: string;
isVerified?: boolean;
};
documents?: UserDocument[];
lastLogin?: number;
userDevice?: UserDevice;
status?: 'ACTIVE' | 'INACTIVE' | 'BLOCKED';
amlDetail?: {
amlStatus?: string;
amlSource?: string;
};
kycDetail?: {
sourceOfIncome?: string;
kycStatus?: string;
kycSource?: string;
kycStatusMessage?: string;
};
onboardingFeedback?: {
id?: string;
status: 'ACTIVE' | 'INACTIVE' | 'BLOCKED';
description?: string;
createdAt: number;
type?: string;
};
}UserDocument Schema
interface UserDocument {
country?: string; // Country of document issue
number?: string; // Document identification number
type?: string; // Document type (passport, ID card, driver's license)
source?: string; // Source of document verification
fullName?: string; // Full name as appears on the document
}