Skip to content

SAR Management API

API endpoints for creating, managing, and exporting Suspicious Activity Reports (SARs).

Base URL

/admin/aml/sars

Endpoints

List SARs

Retrieves a paginated list of Suspicious Activity Reports.

http
GET /admin/aml/sars

Query Parameters:

ParameterTypeDescription
statusstringFilter by status
pagenumberPage number (default: 1)
limitnumberItems per page (default: 20)

Response:

json
{
  "success": true,
  "data": {
    "sars": [
      {
        "id": "sar-uuid-123",
        "sarId": "SAR-1705750800000-ABC123DEF",
        "status": "PENDING_REVIEW",
        "suspiciousActivityType": "structuring",
        "activityDescription": "Multiple transactions just below reporting threshold",
        "dateOfSuspiciousActivity": "2026-01-15",
        "amountInvolved": 45000.00,
        "entityUser": {
          "id": "user-123",
          "firstName": "John",
          "lastName": "Doe",
          "email": "john@example.com",
          "phoneNumber": "+26878123456"
        },
        "filedBy": {
          "id": "admin-123",
          "firstName": "Admin",
          "lastName": "User",
          "email": "admin@keshless.app"
        },
        "createdAt": "2026-01-20T10:00:00Z",
        "draftedAt": "2026-01-20T10:00:00Z"
      }
    ],
    "pagination": {
      "totalItems": 50,
      "currentPage": 1,
      "itemsPerPage": 20,
      "totalPages": 3,
      "hasNextPage": true,
      "hasPrevPage": false
    }
  }
}

Create SAR

Creates a new Suspicious Activity Report.

http
POST /admin/aml/sars

Request Body:

json
{
  "entityUserId": "user-uuid-123",
  "suspiciousActivityType": "structuring",
  "activityDescription": "Customer made 5 transactions of E9,500 each within 2 hours, appearing to avoid the E10,000 reporting threshold.",
  "dateOfSuspiciousActivity": "2026-01-15",
  "amountInvolved": 47500.00,
  "relatedTransactionIds": ["txn-1", "txn-2", "txn-3", "txn-4", "txn-5"],
  "relatedAlertIds": ["alert-123"],
  "filedById": "admin-uuid"
}

Response:

json
{
  "success": true,
  "message": "SAR created successfully",
  "data": {
    "id": "sar-uuid-456",
    "sarId": "SAR-1705750800000-XYZ789",
    "status": "DRAFT",
    "suspiciousActivityType": "structuring",
    "activityDescription": "Customer made 5 transactions of E9,500 each within 2 hours...",
    "dateOfSuspiciousActivity": "2026-01-15",
    "amountInvolved": 47500.00,
    "entityUserId": "user-uuid-123",
    "relatedTransactionIds": ["txn-1", "txn-2", "txn-3", "txn-4", "txn-5"],
    "relatedAlertIds": ["alert-123"],
    "draftedAt": "2026-01-20T14:30:00Z",
    "createdAt": "2026-01-20T14:30:00Z"
  }
}

Update SAR Status

Updates the status of a SAR, triggering workflow transitions.

http
PUT /admin/aml/sars/:sarId/status

Path Parameters:

ParameterTypeDescription
sarIdstringSAR UUID

Request Body:

json
{
  "status": "PENDING_REVIEW",
  "reviewedBy": "admin-uuid"
}

Status Transitions:

Current StatusNext StatusRequired Fields
DRAFTPENDING_REVIEW-
PENDING_REVIEWPENDING_APPROVALreviewedBy
PENDING_APPROVALSUBMITTEDapprovedBy
SUBMITTEDACKNOWLEDGED-
ACKNOWLEDGEDUNDER_INVESTIGATION-
UNDER_INVESTIGATIONCLOSED-

Response:

json
{
  "success": true,
  "message": "SAR status updated",
  "data": {
    "id": "sar-uuid-123",
    "sarId": "SAR-1705750800000-ABC123DEF",
    "status": "PENDING_REVIEW",
    "reviewedAt": "2026-01-20T15:00:00Z",
    "reviewedBy": "admin-uuid"
  }
}

Export SAR

Downloads a SAR in HTML or text format.

http
GET /admin/aml/sars/:sarId/export

Path Parameters:

ParameterTypeDescription
sarIdstringSAR UUID

Query Parameters:

ParameterTypeDescription
formatstringExport format: html or text (default: html)

Response:

Returns the file content with appropriate headers:

  • Content-Type: text/html or text/plain
  • Content-Disposition: attachment; filename="SAR-{sarId}.{ext}"

SAR Status Flow

DRAFT → PENDING_REVIEW → PENDING_APPROVAL → SUBMITTED → ACKNOWLEDGED → CLOSED
                                                     ↳ UNDER_INVESTIGATION → CLOSED
StatusDescription
DRAFTInitial creation, not yet submitted for review
PENDING_REVIEWAwaiting compliance officer review
PENDING_APPROVALReviewed, awaiting final approval
SUBMITTEDSubmitted to regulatory authority
ACKNOWLEDGEDAuthority acknowledged receipt
UNDER_INVESTIGATIONActive investigation by authority
CLOSEDInvestigation complete

Suspicious Activity Types

TypeDescription
structuringStructuring/Smurfing - breaking transactions to avoid thresholds
large_cashLarge cash transactions
unusual_patternUnusual transaction pattern
money_launderingSuspected money laundering
fraudFraud
terrorist_financingTerrorist financing
sanctions_violationSanctions violation
otherOther suspicious activity

TypeScript Types

typescript
interface SAR {
  id: string;
  sarId: string;
  status: SARStatus;
  entityUserId: string;
  suspiciousActivityType: string;
  activityDescription: string;
  dateOfSuspiciousActivity: string;
  amountInvolved: number;
  relatedTransactionIds: string[];
  relatedAlertIds: string[];
  filedById?: string;
  reviewedBy?: string;
  approvedBy?: string;
  draftedAt: Date;
  reviewedAt?: Date;
  approvedAt?: Date;
  submittedAt?: Date;
  createdAt: Date;
  entityUser?: {
    id: string;
    firstName: string;
    lastName: string;
    email: string;
    phoneNumber: string;
  };
  filedBy?: {
    id: string;
    firstName: string;
    lastName: string;
    email: string;
  };
}

type SARStatus =
  | 'DRAFT'
  | 'PENDING_REVIEW'
  | 'PENDING_APPROVAL'
  | 'SUBMITTED'
  | 'ACKNOWLEDGED'
  | 'UNDER_INVESTIGATION'
  | 'CLOSED';

interface CreateSARInput {
  entityUserId: string;
  suspiciousActivityType: string;
  activityDescription: string;
  dateOfSuspiciousActivity: string;
  amountInvolved: number;
  relatedTransactionIds?: string[];
  relatedAlertIds?: string[];
  filedById?: string;
}

interface UpdateSARStatusInput {
  status: SARStatus;
  reviewedBy?: string;
  approvedBy?: string;
}

Error Responses

SAR Not Found

json
{
  "success": false,
  "message": "SAR not found",
  "statusCode": 404
}

Invalid Format

json
{
  "success": false,
  "message": "Invalid format. Use html or text",
  "statusCode": 400
}

Code Examples

Create a New SAR

typescript
import axios from 'axios';

async function createSAR(sarData: CreateSARInput) {
  const response = await axios.post(
    '/admin/aml/sars',
    sarData,
    {
      headers: {
        Authorization: `Bearer ${token}`,
      },
    }
  );

  return response.data.data;
}

// Usage
const sar = await createSAR({
  entityUserId: 'user-123',
  suspiciousActivityType: 'structuring',
  activityDescription: 'Multiple transactions avoiding threshold',
  dateOfSuspiciousActivity: '2026-01-15',
  amountInvolved: 45000,
  relatedTransactionIds: ['txn-1', 'txn-2'],
});

console.log(`SAR created: ${sar.sarId}`);

Update SAR Status

typescript
async function submitSARForReview(sarId: string) {
  const response = await axios.put(
    `/admin/aml/sars/${sarId}/status`,
    {
      status: 'PENDING_REVIEW',
    },
    {
      headers: {
        Authorization: `Bearer ${token}`,
      },
    }
  );

  return response.data.data;
}

Export SAR as HTML

typescript
async function exportSAR(sarId: string, format: 'html' | 'text' = 'html') {
  const response = await axios.get(
    `/admin/aml/sars/${sarId}/export`,
    {
      params: { format },
      responseType: 'blob',
      headers: {
        Authorization: `Bearer ${token}`,
      },
    }
  );

  // Create download link
  const url = URL.createObjectURL(response.data);
  const a = document.createElement('a');
  a.href = url;
  a.download = `SAR-${sarId}.${format === 'html' ? 'html' : 'txt'}`;
  a.click();
  URL.revokeObjectURL(url);
}

Internal use only - Keshless Payment Platform