Documentation

Platform Admin Accounts

Manage accounts across all tenants from the platform admin context

Overview

Platform admin endpoints for managing accounts across tenants. These endpoints require admin JWT authentication and are not subject to tenant entitlements.

Authentication Context

Understanding how admin vs tenant context works for account endpoints.

ContextAuth TypeTenant ScopeBehavior
Admin JWTBearer tokenOptionalFull access to all tenants. Tenant ID is an optional filter, not a restriction.
Tenant UserBearer tokenRequiredScoped to own tenant only. Subject to tenant entitlements.
API KeyX-API-Key headerRequiredScoped to tenant that owns the key. Subject to entitlements.

Key Differences

Admin endpoints bypass tenant entitlement checks. When an admin JWT calls tenant endpoints, entitlements are bypassed. For tenant-scoped admin routes (/admin/tenants/:tenantID/...), the path parameter determines scope, not the JWT's tenant context.

List All Accounts

Retrieve accounts across all tenants with optional filtering.

Endpoint

GET/api/v1/admin/accounts

List all accounts across the platform. Admin JWT required. Supports filtering by tenant, status, and pagination.

Headers

ParameterTypeRequiredDescription
AuthorizationstringYesBearer {admin_access_token}

Query Parameters

ParameterTypeRequiredDescription
tenant_idstringNoFilter by tenant UUID
statusstringNoFilter by account statusValues: active, blocked, closed
account_typestringNoFilter by account typeValues: savings, current, wallet
searchstringNoSearch by account number or holder name
limitintegerNo (default: 20)Page size (max 100)
offsetintegerNo (default: 0)Page offset

Response- Paginated list of accounts

json
{
  "accounts": [
    {
      "account_id": "acc_550e8400-e29b-41d4-a716-446655440000",
      "account_number": "1234567890",
      "account_type": "savings",
      "status": "active",
      "balance": "50000.00",
      "currency": "NGN",
      "holder_name": "John Doe",
      "tenant_id": "tenant_660e8400-e29b-41d4-a716-446655440001",
      "tenant_name": "Acme Corp",
      "created_at": "2025-01-10T08:00:00Z",
      "updated_at": "2025-01-14T12:30:00Z"
    }
  ],
  "total": 1250,
  "limit": 20,
  "offset": 0
}

Error Responses

StatusCodeDescription
401unauthorizedMissing or invalid admin JWT
403forbiddenAdmin role required

Account Metrics

Platform-wide account creation and status metrics.

Endpoint

GET/api/v1/admin/accounts/metrics

Get aggregated account metrics across all tenants. Useful for platform analytics and dashboards.

Headers

ParameterTypeRequiredDescription
AuthorizationstringYesBearer {admin_access_token}

Query Parameters

ParameterTypeRequiredDescription
tenant_idstringNoFilter metrics by tenant UUID
start_datestringNoStart date for metrics period (ISO 8601)
end_datestringNoEnd date for metrics period (ISO 8601)
granularitystringNo (default: day)Time granularity for time-series dataValues: hour, day, week, month

Response- Account metrics summary

json
{
  "summary": {
    "total_accounts": 125000,
    "active_accounts": 118500,
    "blocked_accounts": 4200,
    "closed_accounts": 2300
  },
  "by_type": {
    "savings": 75000,
    "current": 35000,
    "wallet": 15000
  },
  "creation_trend": [
    {
      "date": "2025-01-13",
      "count": 450
    },
    {
      "date": "2025-01-14",
      "count": 520
    }
  ],
  "top_tenants": [
    {
      "tenant_id": "tenant_660e8400-e29b-41d4-a716-446655440001",
      "tenant_name": "Acme Corp",
      "account_count": 45000
    }
  ]
}

Error Responses

StatusCodeDescription
401unauthorizedMissing or invalid admin JWT
403forbiddenAdmin role required

List Tenant Accounts

List accounts for a specific tenant.

Endpoint

GET/api/v1/admin/tenants/{tenantID}/accounts

List all accounts belonging to a specific tenant. The tenant is identified by the path parameter, not the admin's JWT context.

Headers

ParameterTypeRequiredDescription
AuthorizationstringYesBearer {admin_access_token}

Path Parameters

ParameterTypeRequiredDescription
tenantIDstringYesUUID of the tenant

Query Parameters

ParameterTypeRequiredDescription
statusstringNoFilter by account statusValues: active, blocked, closed
account_typestringNoFilter by account type
searchstringNoSearch by account number or holder name
limitintegerNo (default: 20)Page size
offsetintegerNo (default: 0)Page offset

Response- Paginated list of tenant accounts

json
{
  "accounts": [
    {
      "account_id": "acc_550e8400-e29b-41d4-a716-446655440000",
      "account_number": "1234567890",
      "account_type": "savings",
      "status": "active",
      "balance": "50000.00",
      "currency": "NGN",
      "holder_name": "John Doe",
      "created_at": "2025-01-10T08:00:00Z"
    }
  ],
  "total": 450,
  "limit": 20,
  "offset": 0
}

Error Responses

StatusCodeDescription
401unauthorizedMissing or invalid admin JWT
403forbiddenAdmin role required
404tenant_not_foundTenant does not exist

Block Account

Block or freeze an account to prevent transactions.

Endpoint

PUT/api/v1/admin/tenants/{tenantID}/accounts/{accountID}/block

Block an account. Blocked accounts cannot perform any transactions but remain in the system. This action is reversible via unblock.

Headers

ParameterTypeRequiredDescription
AuthorizationstringYesBearer {admin_access_token}
Content-TypestringYesapplication/json

Path Parameters

ParameterTypeRequiredDescription
tenantIDstringYesUUID of the tenant
accountIDstringYesUUID of the account to block

Request Body- Block reason and metadata

json
{
  "reason": "Suspicious activity detected",
  "notes": "Multiple failed transaction attempts from unusual locations",
  "notify_holder": true
}

Response- Account blocked successfully

json
{
  "account_id": "acc_550e8400-e29b-41d4-a716-446655440000",
  "status": "blocked",
  "blocked_at": "2025-01-14T15:30:00Z",
  "blocked_by": "admin_770e8400-e29b-41d4-a716-446655440002",
  "reason": "Suspicious activity detected"
}

Error Responses

StatusCodeDescription
400already_blockedAccount is already blocked
400account_closedCannot block a closed account
404account_not_foundAccount not found or does not belong to tenant

Request Body Parameters

FieldTypeRequiredDescription
reasonstringYesReason for blocking the account
notesstringNoAdditional internal notes
notify_holderbooleanNoSend notification to account holder (default: false)

Unblock Account

Restore a blocked account to active status.

Endpoint

PUT/api/v1/admin/tenants/{tenantID}/accounts/{accountID}/unblock

Unblock a previously blocked account. The account will return to active status and can resume transactions.

Headers

ParameterTypeRequiredDescription
AuthorizationstringYesBearer {admin_access_token}
Content-TypestringYesapplication/json

Path Parameters

ParameterTypeRequiredDescription
tenantIDstringYesUUID of the tenant
accountIDstringYesUUID of the account to unblock

Request Body- Unblock reason and metadata

json
{
  "reason": "Investigation completed - no fraud detected",
  "notes": "Customer verified identity via support call",
  "notify_holder": true
}

Response- Account unblocked successfully

json
{
  "account_id": "acc_550e8400-e29b-41d4-a716-446655440000",
  "status": "active",
  "unblocked_at": "2025-01-14T16:00:00Z",
  "unblocked_by": "admin_770e8400-e29b-41d4-a716-446655440002",
  "reason": "Investigation completed - no fraud detected"
}

Error Responses

StatusCodeDescription
400not_blockedAccount is not currently blocked
400account_closedCannot unblock a closed account
404account_not_foundAccount not found or does not belong to tenant

Request Body Parameters

FieldTypeRequiredDescription
reasonstringYesReason for unblocking the account
notesstringNoAdditional internal notes
notify_holderbooleanNoSend notification to account holder (default: false)

Close Account

Permanently close an account. This action is irreversible.

Endpoint

PUT/api/v1/admin/tenants/{tenantID}/accounts/{accountID}/close

Close an account permanently. The account balance must be zero before closing. This action cannot be reversed.

Headers

ParameterTypeRequiredDescription
AuthorizationstringYesBearer {admin_access_token}
Content-TypestringYesapplication/json

Path Parameters

ParameterTypeRequiredDescription
tenantIDstringYesUUID of the tenant
accountIDstringYesUUID of the account to close

Request Body- Closure reason and metadata

json
{
  "reason": "Customer requested account closure",
  "notes": "Verified via support ticket #12345",
  "notify_holder": true,
  "force": false
}

Response- Account closed successfully

json
{
  "account_id": "acc_550e8400-e29b-41d4-a716-446655440000",
  "status": "closed",
  "closed_at": "2025-01-14T17:00:00Z",
  "closed_by": "admin_770e8400-e29b-41d4-a716-446655440002",
  "reason": "Customer requested account closure"
}

Error Responses

StatusCodeDescription
400balance_not_zeroAccount balance must be zero before closing
400pending_transactionsAccount has pending transactions
400already_closedAccount is already closed
404account_not_foundAccount not found or does not belong to tenant

Request Body Parameters

FieldTypeRequiredDescription
reasonstringYesReason for closing the account
notesstringNoAdditional internal notes
notify_holderbooleanNoSend notification to account holder (default: false)
forcebooleanNoForce close even with non-zero balance (requires super_admin role)