KulPayAPI Live

API reference

Compliance

Suspicious-activity cases and communications to GIFiM (F3-8), compliance:* only.

GET /v1/admin/compliance/cases

List suspicious-activity cases

Suspicious-activity cases (F3-8) are opened by an operator or by a risk rule marked suspicion, investigated (notes), and decided — report to GIFiM or not — with a justification by one compliance officer and approval by another. They belong to the platform: only keys with compliance:read/compliance:write reach them (admin:* does not), and nothing about a case reaches the customer or the partner (no tipping-off). Requires compliance:read.

Parameters

NameInTypeDescription
statusquerystring

Responses

  • 200 {data, total}, open first.

Request

curl -X GET "$KULPAY_URL/v1/admin/compliance/cases" \
  -H "Authorization: Bearer $KULPAY_KEY"
200 Response application/json
{
  "data": [
    {
      "account_id": "3KZlyE2fG4hI6jK8lM0nO2pQ4rS",
      "created_at": "2026-10-12T09:00:00Z",
      "id": "3KZm0Cs1Dt2Eu3Fv4Gw5Hx6Iy7J",
      "opened_by": "system:risk",
      "rule_id": "structuring",
      "source": "risk_rule",
      "status": "open",
      "subject_id": "3KZlzP9qR1sT3uV5wX7yZ9aB1cD",
      "subject_type": "transaction",
      "summary": "risk rule structuring fired (review): amount 950 MZN at or above 900"
    }
  ],
  "total": 1
}

POST /v1/admin/compliance/cases

Open a case

Requires compliance:write.

Request body application/json required

FieldTypeDescription
account_idstring
subject_id requiredstring
subject_type requiredstring
summary requiredstring

Responses

  • 201 The case.

Request

curl -X POST "$KULPAY_URL/v1/admin/compliance/cases" \
  -H "Authorization: Bearer $KULPAY_KEY" \
  -H "Content-Type: application/json" \
  -d '{
  "subject_id": "3KZlzP9qR1sT3uV5wX7yZ9aB1cD",
  "subject_type": "cash_deposit",
  "summary": "three deposits of 240 000 MZN in a day by the same depositor"
}'
201 Response application/json
{
  "account_id": "3KZlyE2fG4hI6jK8lM0nO2pQ4rS",
  "created_at": "2026-10-12T09:00:00Z",
  "id": "3KZm0Cs1Dt2Eu3Fv4Gw5Hx6Iy7J",
  "opened_by": "system:risk",
  "rule_id": "structuring",
  "source": "risk_rule",
  "status": "open",
  "subject_id": "3KZlzP9qR1sT3uV5wX7yZ9aB1cD",
  "subject_type": "transaction",
  "summary": "risk rule structuring fired (review): amount 950 MZN at or above 900"
}

GET /v1/admin/compliance/cases/{id}

Get a case

Requires compliance:read.

Parameters

NameInTypeDescription
id requiredpathstring

Responses

  • 200 The case.

Request

curl -X GET "$KULPAY_URL/v1/admin/compliance/cases/{id}" \
  -H "Authorization: Bearer $KULPAY_KEY"
200 Response application/json
{
  "account_id": "3KZlyE2fG4hI6jK8lM0nO2pQ4rS",
  "created_at": "2026-10-12T09:00:00Z",
  "id": "3KZm0Cs1Dt2Eu3Fv4Gw5Hx6Iy7J",
  "opened_by": "system:risk",
  "rule_id": "structuring",
  "source": "risk_rule",
  "status": "open",
  "subject_id": "3KZlzP9qR1sT3uV5wX7yZ9aB1cD",
  "subject_type": "transaction",
  "summary": "risk rule structuring fired (review): amount 950 MZN at or above 900"
}

POST /v1/admin/compliance/cases/{id}/approve

Approve a case's decision (checker)

The second compliance officer; the one who decided gets 403 same_approver. Approved, the case is reported or closed. Requires compliance:write.

Parameters

NameInTypeDescription
id requiredpathstring

Request body application/json required

FieldTypeDescription
approve requiredboolean
reason requiredstring

Responses

  • 200 The case.

Request

curl -X POST "$KULPAY_URL/v1/admin/compliance/cases/{id}/approve" \
  -H "Authorization: Bearer $KULPAY_KEY" \
  -H "Content-Type: application/json" \
  -d '{
  "approve": true,
  "reason": "agreed"
}'
200 Response application/json
{
  "account_id": "3KZlyE2fG4hI6jK8lM0nO2pQ4rS",
  "created_at": "2026-10-12T09:00:00Z",
  "id": "3KZm0Cs1Dt2Eu3Fv4Gw5Hx6Iy7J",
  "opened_by": "system:risk",
  "rule_id": "structuring",
  "source": "risk_rule",
  "status": "open",
  "subject_id": "3KZlzP9qR1sT3uV5wX7yZ9aB1cD",
  "subject_type": "transaction",
  "summary": "risk rule structuring fired (review): amount 950 MZN at or above 900"
}

POST /v1/admin/compliance/cases/{id}/decision

Decide a case (maker)

report (with GIFiM's reference of the communication) or no_report, with a justification of at least 10 characters; a second compliance officer approves it (/approve). Requires compliance:write.

Parameters

NameInTypeDescription
id requiredpathstring

Request body application/json required

FieldTypeDescription
decision requiredstring
One of: report, no_report
reason requiredstring
referencestring

Responses

  • 202 Prepared.

Request

curl -X POST "$KULPAY_URL/v1/admin/compliance/cases/{id}/decision" \
  -H "Authorization: Bearer $KULPAY_KEY" \
  -H "Content-Type: application/json" \
  -d '{
  "decision": "report",
  "reason": "structuring below the review threshold over three days",
  "reference": "GIFIM-2026-0099"
}'
202 Response application/json
{
  "approval_id": "3KZm1Ab2Cd3Ef4Gh5Ij6Kl7Mn8O",
  "message": "decision prepared; a second compliance officer must approve it (POST /v1/admin/compliance/cases/{id}/approve)"
}

POST /v1/admin/compliance/cases/{id}/notes

Record a step of the investigation

Requires compliance:write.

Parameters

NameInTypeDescription
id requiredpathstring

Request body application/json required

FieldTypeDescription
text requiredstring

Responses

  • 200 The case.

Request

curl -X POST "$KULPAY_URL/v1/admin/compliance/cases/{id}/notes" \
  -H "Authorization: Bearer $KULPAY_KEY" \
  -H "Content-Type: application/json" \
  -d '{
  "text": "called the partner'\''s compliance officer"
}'
200 Response application/json
{
  "account_id": "3KZlyE2fG4hI6jK8lM0nO2pQ4rS",
  "created_at": "2026-10-12T09:00:00Z",
  "id": "3KZm0Cs1Dt2Eu3Fv4Gw5Hx6Iy7J",
  "opened_by": "system:risk",
  "rule_id": "structuring",
  "source": "risk_rule",
  "status": "open",
  "subject_id": "3KZlzP9qR1sT3uV5wX7yZ9aB1cD",
  "subject_type": "transaction",
  "summary": "risk rule structuring fired (review): amount 950 MZN at or above 900"
}