-
Notifications
You must be signed in to change notification settings - Fork 0
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
/docanddocs/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).
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. │
└────────────────────────────────────────────────────────────────────────────────────────┘
| 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 |
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 grantsGET/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 thedualAuthmiddleware.
| 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) |
| 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):
| 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 |
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 byGET /auth/me(self-profile).
Response 200:
{
"customerAgreementInstanceReference": "uuid-v4",
"customerName": "Luis Fernandez",
"customerSegment": "retail",
"customerAgreementStatus": "active"
}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
}
paymentCardExpirationDateis stored as QE:none (CHD). CVV and PIN are never accepted at any endpoint.
| 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": {}
}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
All gateway endpoints return stub responses. Full persistence scheduled for v5. JWT required on all routes.
| 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. |
| 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
| 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. |
| 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 |
- L1 calls
POST /api/v1/fraud/:id/escalatewith{ escalationReason }. - L2 calls
POST /api/v1/fraud/:id/escalate/approve. - Server calls
generateToken(caseId, 'level2_investigator')and returns{ escalationToken, tokenExpiresAt }. - L2 includes the token in
X-Escalation-Tokenheader on subsequent customer/transaction requests. - RBAC middleware validates the token and grants DEK-sensitive access to QE:none fields.
- Every sensitive field access writes a
field_accessedevent tofraudDiagnosisCaseEvents.
Token TTL: 4 hours (in-memory store, per-process).
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": "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 |
| 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 |
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) gainscustomers:[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.
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.
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).
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.
- 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.
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.