Skip to content

API Reference

Antonio Membrides Espinosa edited this page Jul 24, 2026 · 6 revisions

API Reference

Base URL: http://localhost:8081
Swagger UI (interactive): http://localhost:8081/doc
OpenAPI JSON spec: http://localhost:8081/doc/json

This page is a high-level map, not the full contract. The backend now exposes 100+ endpoints across 11+ modules (OAuth/OIDC + CIBA, Integration Hub, bank transfers, checkout, admin, RBAC, notifications). The authoritative, always-current reference is the Swagger UI at /doc and docs/technical-spec.md §6. The sections below summarise the module structure and the main endpoint groups; where this page and Swagger disagree, Swagger wins.

Most routes require a Bearer token:

Authorization: Bearer <token>

Public exceptions include /api/v1/system/health, the OAuth/OIDC endpoints (/.well-known/openid-configuration, /api/v1/auth/jwks, /api/v1/auth/token, /authorize, /userinfo, /introspect, /revoke), and the self-authenticating CIBA routes. A first-party user obtains a session token via POST /api/v1/auth/login; a merchant authenticates as an OAuth confidential client (dualAuth, v23).


Component Map

The backend is structured as domain modules, each owning its BIAN Service Domains, collections, and routes.

┌────────────────────────────────────────────────────────────────────────────────────────┐
│ MODULE: identity  -  SD-16 Party Authentication                                        │
│ Routes: /api/v1/auth/*                                                                 │
│ Collections: partyAuthentication (QE:equality on email)                                │
│              authenticationDomain (plaintext - provider config: local/OIDC/SAML)       │
├────────────────────────────────────────────────────────────────────────────────────────┤
│ MODULE: customer  -  SD-53 Customer Agreement + SD-88 Payment Card                     │
│ Routes: /api/v1/customer  ·  /api/v1/customer/:customerId/cards                        │
│ Collections: customerAgreementProcedure (QE:equality on accountRef;                    │
│                QE:none inline on address/govId/riskNotes)                              │
│              paymentCardManagement (QE:none on expiry date)                            │
├────────────────────────────────────────────────────────────────────────────────────────┤
│ MODULE: transactions  -  SD-254 Card Transaction                                       │
│ Routes: /api/v1/transactions                                                           │
│ Collections: cardTransactionLog (QE:equality on accountRef;                            │
│                QE:none inline on gateway payload/processor metadata)                   │
├────────────────────────────────────────────────────────────────────────────────────────┤
│ MODULE: fraud  -  SD-83 Fraud Diagnosis + SD-60 Customer Credit Rating (HRPC)          │
│ Routes: /api/v1/fraud                                                                  │
│ Collections: fraudDiagnosisCase (plaintext - no CHD)                                   │
│              fraudDiagnosisCaseEvents (plaintext - append-only audit log)              │
│              customerCreditRating (plaintext - HRPC risk classification, SD-60)        │
├────────────────────────────────────────────────────────────────────────────────────────┤
│ MODULE: gateway  -  SD-89+SD-64+SD-65+SD-66+SD-57+SD-15 (implemented)                  │
│ Routes: /api/v1/checkout · /payment/links · /accounts · /executions ·                  │
│         /beneficiaries · /gateway/transfers (bank ACH/SEPA/SWIFT + mandates)           │
│ Collections: merchantAgreementProcedure, paymentOrderProcedure, cardEtokenProcedure,   │
│              payoutAccountArrangement, paymentExecutionProcedure, counterpartyArrangement│
├────────────────────────────────────────────────────────────────────────────────────────┤
│ MODULE: identity (OAuth/OIDC)  -  SD-91 + SD-16                                         │
│ Routes: /api/v1/auth/* (login, users, roles, acl, me) ·                                 │
│         OAuth: /authorize /token /userinfo /introspect /revoke /jwks /keys /grants ·    │
│         CIBA: /auth/enroll* /auth/bc-authorize*                                          │
│ Collections: partyAuthorizationCode, partyIssuedToken, partyAuthenticationKey,         │
│              partyAuthConsent, partyEnrolledCredential, partyBackchannelAuthentication  │
├────────────────────────────────────────────────────────────────────────────────────────┤
│ MODULE: provider (Integration Hub)  -  SD-193                                           │
│ Routes: /api/v1/providers/* (vendors, groups, callback) · /api/v1/events               │
│ Collections: externalProviderArrangement, externalProviderArrangementActionLog,        │
│              capabilityModuleConfiguration, businessProcessEvent, complianceProcessEvent│
├────────────────────────────────────────────────────────────────────────────────────────┤
│ MODULE: admin / domain / notification                                                  │
│ Routes: /api/v1/admin/* · /api/v1/modules/domains/* · /api/v1/notifications/*          │
├────────────────────────────────────────────────────────────────────────────────────────┤
│ MODULE: system  -  Infrastructure                                                      │
│ Routes: /api/v1/system/health · /api/v1/system/simulator/* · /api/v1/system/raw/...    │
│ Health: always available. Raw/simulator: non-production only.                          │
└────────────────────────────────────────────────────────────────────────────────────────┘

PCI CDE scope by module

Module PCI CDE Scope Reason
customer In scope Stores encrypted PII and CHD (expiry date)
transactions In scope Stores encrypted account reference and gateway payload
gateway In scope Stores merchant credentials and payment order references
fraud Adjacent References CDE keys via plaintext FK; no CHD stored
identity Adjacent Only encrypted email for auth lookup
system Non-CDE No data access in production

Newer endpoint groups (summary)

These surfaces post-date the original endpoint map below. See Swagger (/doc) for request/response shapes.

OAuth 2.0 / OIDC (identity):

  • GET /.well-known/openid-configuration, GET /api/v1/auth/jwks
  • GET /api/v1/auth/authorize, POST /api/v1/auth/token, GET /api/v1/auth/userinfo, GET /api/v1/auth/logout
  • POST /api/v1/auth/introspect, POST /api/v1/auth/revoke
  • Key management /api/v1/auth/keys/*; consent grants GET/DELETE /api/v1/auth/grants*

CIBA + passwordless enrollment (identity, v24/v25):

  • POST /api/v1/auth/enroll/challenge, POST/GET /api/v1/auth/enroll, DELETE /api/v1/auth/enroll/:credentialId, POST /api/v1/auth/enroll/:credentialId/rotate
  • POST /api/v1/auth/bc-authorize, GET /api/v1/auth/bc-authorize/pending, GET /api/v1/auth/bc-authorize/:authReqId, POST /api/v1/auth/bc-authorize/:authReqId/approve|deny

RBAC / ACL (identity): GET /api/v1/acl/effective, /api/v1/roles CRUD, /api/v1/users CRUD.

Bank transfers (gateway, v17.1): POST /api/v1/gateway/transfers/preview, POST /api/v1/gateway/transfers/bank, GET /api/v1/gateway/transfers/:ref/status; mandates POST/GET /api/v1/gateway/transfers/mandates, DELETE .../mandates/:ref, POST .../mandates/run-due. Plus /api/v1/beneficiaries/* and /api/v1/accounts/* (with /movements, /iban, /cards, /credit).

Checkout & payment links (gateway, v4): /api/v1/checkout/*, /api/v1/payment/links/*, /api/v1/executions/*.

Integration Hub (provider, SD-193): /api/v1/providers/vendors, /api/v1/providers/groups, /api/v1/providers/callback/*, /api/v1/events.

Admin / domain / notification: /api/v1/admin/* (webhook inspector, runners, restart/reload), /api/v1/modules/domains/*, /api/v1/notifications/*.

v23 note: there is no /api/v1/merchant/* tree. A merchant authenticates as an OAuth client and uses the same shared routes as first-party callers via the dualAuth middleware.


Complete Endpoint Map

system module

Method Route Auth Description
GET / None Redirect to /doc (Swagger UI)
GET /api/v1/system/health None API + Atlas health status
GET /api/v1/system/raw/:collection/:id JWT Raw ciphertext view - non-production only (403 in prod)

auth tag - identity module (SD-16)

Method Route Auth Description
POST /api/v1/auth/login None Authenticate and obtain JWT. QE:equality search on email.
GET /api/v1/auth/users None List pre-seeded demo users (no passwords).
GET /api/v1/auth/domains None List enabled authentication domains (local, OIDC, SAML).
GET /api/v1/auth/me JWT Full profile of the authenticated user. For customer role: includes customerAgreement data with QE:equality fields returned in plaintext. For analyst/auditor roles: returns JWT claims only.
PATCH /api/v1/auth/me JWT Update own profile. Editable fields: customerName, customerMobilePhoneNumber (QE:equality, re-encrypted automatically), customerAgreementPreferredLanguage.

Demo users (all passwords: demo-password):

Email Role Customer Agreement
luis.fernandez@back.es customer ACC-LF-20240115
julia.santos@back.es customer ACC-JS-20231201
sarah.chen@back.es level1_analyst n/a
michael.obi@back.es level2_investigator n/a
diego.sans@back.es security_auditor n/a

customer tag - customer module (SD-53)

RBAC note: The customer role is blocked from all /api/v1/customer endpoints. Customers access their own profile via GET /api/v1/auth/me.

Method Route Auth Description
GET /api/v1/customer?email=<v> JWT (analyst+) QE:equality search on customerEmailAddress
GET /api/v1/customer?phone=<v> JWT (analyst+) QE:equality search on customerMobilePhoneNumber
GET /api/v1/customer?accountRef=<v> JWT (analyst+) QE:equality search on customerAgreementReference
GET /api/v1/customer/by-id/:id JWT (analyst+) Lookup by customerAgreementInstanceReference UUID (plaintext lookup, no QE needed). Used by fraud case detail to auto-load the linked customer profile.

L2 escalation token: Pass X-Escalation-Token: <token> to receive the inline QE:none fields (customerAgreementResidentialAddress, governmentIdentificationReference, customerAgreementRiskNotes) stored in customerAgreementProcedure. Without the token, the Level 1 QE client is used and those fields return as Binary ciphertext, which the API strips from the response.

Encrypted QE:equality fields (customerEmailAddress, customerMobilePhoneNumber, customerAgreementReference) are never echoed in search responses - only used as predicates. They ARE returned by GET /auth/me (self-profile).

Response 200:

{
  "customerAgreementInstanceReference": "uuid-v4",
  "customerName": "Luis Fernandez",
  "customerSegment": "retail",
  "customerAgreementStatus": "active"
}

cards tag - customer module (SD-88)

Cards are a sub-resource of Customer Agreement - they belong to the customer, not to transactions.

Method Route Auth Description
GET /api/v1/customer/:customerId/cards JWT List payment cards for a customer
POST /api/v1/customer/:customerId/cards JWT Register a tokenized card for a customer

:customerId = customerAgreementInstanceReference from the customer search above.

POST body:

{
  "cardToken": "tok_abc123",
  "paymentCardExpirationDate": "12/28",
  "paymentCardMaskedPanDisplay": "****-****-****-1234",
  "paymentCardNetwork": "VISA",
  "paymentCardIsPreferred": false
}

paymentCardExpirationDate is stored as QE:none (CHD). CVV and PIN are never accepted at any endpoint.


transactions tag - transactions module (SD-254)

Method Route Auth Description
POST /api/v1/transactions None (simulator) / JWT Create a card transaction. Auto-triggers fraud case if amount or MCC matches risk criteria.
GET /api/v1/transactions/:id JWT Get transaction by UUID. Returns cardTransactionAccountReference (QE:equality, decrypted) and optionally sensitive fields for L2+ with escalation token.
GET /api/v1/transactions?cardToken=<v> JWT List transactions by card token or masked PAN. Auto-detects format (tok_ prefix vs ****- pattern).
GET /api/v1/transactions/merchants None Distinct merchant + MCC pairs for UI dropdown (Simulator mode).
GET /api/v1/transactions/all JWT (analyst+) Paginated list of all transactions. Filters: status, merchant (regex), cardToken, email (3-step: email -> customer UUID -> card tokens -> transactions).
GET /api/v1/transactions/:id/notes JWT (all roles incl. customer) Customer-safe endpoint: returns only fraudDiagnosisCustomerSubjectNotes, case status, severity, and resolution outcome for the fraud case linked to this transaction. Does NOT return internal analyst notes.

Email search in /transactions/all: Uses a 3-step plaintext path (email -> customerAgreementInstanceReference UUID via QE search -> paymentCard.customerAgreementInstanceReference FK -> cardTransaction.paymentCardReference) to avoid role-inconsistent QE:equality searches.

Auto fraud-case rule: A fraudDiagnosisCase is opened when amount > FRAUD_AMOUNT_THRESHOLD (default 500) OR MCC is in the risk list (5812, 6011, 7995).

POST body:

{
  "cardToken": "tok_abc123",
  "accountReference": "ACC-001",
  "amount": 850.00,
  "currency": "USD",
  "cardTransactionMerchantName": "TechStore Online",
  "cardTransactionMerchantCategoryCode": "5732",
  "cardTransactionChannel": "online",
  "cardTransactionMaskedPanDisplay": "****-****-****-1234",
  "gatewayPayload": {}
}

fraud tag - fraud module (SD-83)

RBAC note: The customer role is blocked from all /api/v1/fraud endpoints. Use GET /api/v1/transactions/:id/notes for customer-visible case information.

Method Route Auth Description
GET /api/v1/fraud JWT (analyst+) Paginated case list. Filters: status, severity, transactionId, customerId, page, limit. L2 default: status=escalated.
POST /api/v1/fraud JWT (analyst+) Manually open an investigation case for a transaction that did not trigger automatic detection. Checks for duplicate (returns existing case if one exists).
GET /api/v1/fraud/:id JWT (analyst+) Full case detail with embedded transactionSnapshot, fraudDiagnosisCaseNotes, fraudDiagnosisCustomerSubjectNotes, and fraudDiagnosisResolutionRecord.
PATCH /api/v1/fraud/:id JWT (analyst+) Update case: fraudDiagnosisCaseStatus, fraudDiagnosisCaseNotes (internal), fraudDiagnosisCustomerSubjectNotes (visible to customer), resolutionOutcome, resolutionNotes. Writes note_added or resolved audit event automatically.
POST /api/v1/fraud/:id/escalate JWT (L1) Escalate to Level 2. Changes status to escalated. Writes escalated audit event.
POST /api/v1/fraud/:id/escalate/approve JWT (L2) FR-v2-11. Approves escalation. Calls generateToken(caseId, 'level2_investigator'). Returns short-lived escalation token (TTL 4h). Writes field_accessed audit event.
GET /api/v1/fraud/:id/events JWT (analyst+) Chronological audit event log from fraudDiagnosisCaseEvents.
GET /api/v1/fraud/audit-events JWT (analyst+) All events across all cases (Security Auditor dashboard). Filters: page, limit. Joins fraudDiagnosisCaseReference via aggregation.
GET /api/v1/fraud/hrpc/check?accountRef=<v> JWT (analyst+) HRPC risk check. Queries customerCreditRating (BIAN SD-60) by account reference. Returns HRPC flags, highest risk level, and review status.

BIAN lifecycle: open - under_review - escalated - resolved_cleared / resolved_fraud - closed

Event types: case_opened - assigned - note_added - field_accessed - escalated - ai_review - resolved - closed

PATCH body:

{
  "fraudDiagnosisCaseStatus": "under_review",
  "fraudDiagnosisCaseNotes": "Suspicious merchant. Verifying with customer.",
  "fraudDiagnosisCustomerSubjectNotes": "Your transaction is under security review. No action needed.",
  "resolutionOutcome": "confirmed_fraud",
  "resolutionNotes": "Confirmed after L2 forensic review."
}

HRPC categories in customerCreditRating (SD-60): pep, sip, hnwi, ubo, terrorism_linked, high_risk_jurisdiction, sanctioned, financial_fraud_history, suspicious_transaction_patterns


gateway tag - gateway module (SD-89 · SD-64 · SD-65 · SD-57) ⚠️ v5 Prototype

All gateway endpoints return stub responses. Full persistence scheduled for v5. JWT required on all routes.

Merchant Relations - SD-89

Method Route Description
GET /api/v1/merchants List merchants. Filters: status, mcc.
POST /api/v1/merchants Onboard merchant. Returns merchantApiKey once (stored as QE:none hash).
GET /api/v1/merchants/:id Merchant profile. merchantApiKeyHash never returned.
PATCH /api/v1/merchants/:id Update limit, webhook URL, settlement schedule, or status.
POST /api/v1/merchants/:id/webhooks Register webhook endpoint for payment event callbacks.

Payment Order - SD-64 + SD-65 (Routing)

Method Route Description
POST /api/v1/gateway/payments Create payment order. X-Idempotency-Key header required.
GET /api/v1/gateway/payments/:id Get order status + routing decision.
POST /api/v1/gateway/payments/:id/confirm Link customer; initiated → confirmed.
POST /api/v1/gateway/payments/:id/authorize SD-65 routing; creates cardTransaction; confirmed → authorized.
POST /api/v1/gateway/payments/:id/capture Capture funds; authorized → captured.
DELETE /api/v1/gateway/payments/:id Void; `authorized
POST /api/v1/gateway/payments/:id/refund Partial or full refund; captured → refunded.

Payment lifecycle:

initiated → confirmed → authorized → captured → settled
                                 ↘ voided
         ↘ voided
                                              ↘ refunded

Token Vault - SD-57

Method Route Description
POST /api/v1/gateway/tokens Create token vault entry. Returns tokenVaultCardToken (surrogate, not CHD).
GET /api/v1/gateway/tokens/:token Token metadata. tokenVaultNetworkToken (QE:none) never returned.

RBAC and Access Control

Role enforcement (backend middleware)

Role Blocked prefixes Allowed via dedicated endpoint
customer /api/v1/fraud, /api/v1/customer /api/v1/auth/me (own profile), /api/v1/transactions/:id/notes (case notes)
level1_analyst None All analyst endpoints
level2_investigator None All analyst endpoints + sensitive fields with escalation token
security_auditor None All endpoints read-only

Escalation token flow (FR-v2-11)

  1. L1 calls POST /api/v1/fraud/:id/escalate with { escalationReason }.
  2. L2 calls POST /api/v1/fraud/:id/escalate/approve.
  3. Server calls generateToken(caseId, 'level2_investigator') and returns { escalationToken, tokenExpiresAt }.
  4. L2 includes the token in X-Escalation-Token header on subsequent customer/transaction requests.
  5. RBAC middleware validates the token and grants DEK-sensitive access to QE:none fields.
  6. Every sensitive field access writes a field_accessed event to fraudDiagnosisCaseEvents.

Token TTL: 4 hours (in-memory store, per-process).

X-Demo-Role header

For simulator mode and testing, the RBAC role can be overridden by sending:

X-Demo-Role: level2_investigator

This header takes precedence over the JWT role claim. Combined with X-Escalation-Token, it enables the simulator to demonstrate L2 access without real authentication.


Error response format

{ "error": "Human-readable message" }
Code Meaning
400 Bad request - missing or invalid fields
401 Missing or invalid Bearer JWT
403 Forbidden - e.g. raw endpoint in production
404 Resource not found
409 Conflict - duplicate idempotency key
422 Invalid state transition
500 Unexpected server error
503 Atlas unavailable - degraded mode

PCI DSS controls enforced by the API

Rule Enforcement mechanism
Full PAN never stored Frontend tokenizes (tok_<uuid>) before calling POST /api/v1/transactions
CVV / PIN never stored Not accepted at any endpoint (no field in any request schema)
SAD never retained after auth cardTransactionLog.rawGatewayPayload stores only the gateway JSON response (QE:none, inline)
QE:equality fields not echoed customerEmailAddress, customerMobilePhoneNumber, customerAgreementReference stripped from all GET responses
merchantApiKeyHash never exposed All GET /merchants responses strip this field
tokenVaultNetworkToken never exposed All GET /gateway/tokens responses strip this field
Level 2 field gating Inline QE:none fields in customerAgreementProcedure and cardTransactionLog only accessible with DEK-sensitive via v2 escalation token

KYC and KYB Built-in Module Administration (Operations Officer)

Two identity/onboarding built-in modules now have a production-grade administration surface, each split into Configuration (built-in engine policy incl. the decision mode) and Administration (the review workbench). Roles:

  • Merchant Officer (merchant_officer, SD-89, merchants:[view,manage]) owns the KYB DECISION (review, approve/reject/suspend) via the merchant review flow.
  • Operations Officer (operations_officer) gains customers:[view,manage] + merchants:[view,manage] for KYC/KYB DATA administration (review + correct KYC/KYB records and beneficial owners). Data correction only, NOT the KYB decision (SoD, PCI Req 7). Both emit the same compliance events; neither replaces the other.

Beneficial owners (UBO)

merchantAgreementProcedure now carries a bounded merchantBeneficialOwners sub-document array (SD-89 + SD-13, FATF/4th AMLD): 1..N owners, numeric ownership participation, exactly one primary/controlling owner (= the legacy merchantOwnerPartyReference derived pointer), sum at most 100, hard cap 25. Owner PII (name, DOB, address, gov ID) lives in the party record (QE tiers), never duplicated in the embed (GDPR Art. 5 minimization). Reverse lookup "which merchants does a party own" is a multikey index; every shareholder sees the merchant. Demo seed adds a 60/40, a 50/30/20 and an 80/15 free-float cap table.

Two-layer KYB risk

KYB screens the BUSINESS (entity layer: merchantAgreementKybCheck gains businessRiskLevel / sanctionsResult / adverseMediaResult / screeningProviderRef) AND every controlling person (owner layer, composed by reference from each UBO KYC verdict). Starting a KYB process fans out on the event bus to kyb_business + hrp_sanctions + aml_monitoring (entity) and kyc_identity per owner; a KybVerificationSaga aggregates, persists the verdict, and resolves per the module decision mode. Every process is reconstructable from its single correlationId (bus milestones + provider wire calls).

Decision mode

Per-module policy in capabilityModuleConfiguration.moduleConfig: manual (officer decides), automated (auto-resolve within thresholds), assisted (rules/AI recommend, human confirms, HITL). Unset defaults to manual (fail-safe). Sanctions/PEP hit never auto-approves. Seeded KYC=automated, KYB=manual.

API (defers to Swagger /doc for the full contract)

  • KYC administration (customer module): GET /customer/kyc, GET/PATCH /customer/:partyRef/kyc, POST /customer/:partyRef/kyc/re-screen, GET /customer/:partyRef/kyc/process.
  • KYB administration (gateway module): GET/PATCH /merchants/:id/kyb, GET/POST/PATCH/DELETE /merchants/:id/kyb/owners[/:partyRef], GET /merchants/:id/kyb/process.

Frontend

Bespoke two-tab pages system/admin/modules/{kyc,kyb} (Configuration + Administration), deep-linkable detail routes with structured verdict, owners/shareholders panel (sum meter, one-primary), field info tooltips, correlated process timeline, responsive mobile-to-wide. An Owners tab is also on the merchant shell (system/merchant/[merchantId]/owners).

Added 2026-07-24. Version 2.5.0. See docs/ for the source of truth.

Clone this wiki locally