{
  "openapi": "3.1.0",
  "info": {
    "title": "Kang Open Banking API",
    "version": "4.54.2",
    "summary": "Unified Open Banking API for Cameroon",
    "description": "COBAC & BEAC compliant Open Banking API providing Account Information (AISP), Payment Initiation (PISP), Credit Scoring, Loans, Savings, Mobile Money, Double-Entry Ledger, Virtual Cards, Custodial Wallets, Escrow, Compliance Screening, SLA Monitoring, POS Commerce, Bank Directory, Bank Connector Kit, Interbank Engine (ISO 20022), and comprehensive financial services for the Central African region. All monetary examples use XAF (Central African CFA Franc). Note: POS, Catalog, and Inventory modules are planned for a future release and are not yet exposed in this version of the API. | v4.3.0 (2026-03-27): Standards remediation release. Fixed PISP required fields, added FAPI x-fapi-interaction-id headers, corrected server URL versioning, moved provider webhook paths under /v1/, added currency enums, corrected amount field types to string, added 4 missing tag declarations, removed 6 unused POS tags, added OIDC discovery mandatory fields, added OAuth2 refreshUrl, enumerated webhook event types, added pagination to 17 list endpoints, added savings account read endpoints, extended KYC schema for FATF R.10 compliance, structured escrow release_conditions, added DCR grant_type enums, added Sunset metadata to deprecated endpoints, secured WooCommerce plugin download endpoint. No breaking changes to existing paths, operationIds, or schema names. | v4.4.0 (2026-03-29): Final compliance release. R1: Removed duplicate inline pagination params. R2: Wired StandardResponse/PaginatedResponse allOf envelopes on 12 operations. R3: Added 6 OBIE-mandated required fields to Account schema. R4: Added 7 OBIE PascalCase aliases with x-obie-mapping to Transaction schema. R5: Added 5 FAPI params (nonce, request_uri, request, acr_values, claims) to /v1/oauth/authorize. R6: Added 8 missing fields to GatewayCharge schema. R7: Added PATCH/DELETE to subscriptions endpoint. R8: Added ProblemDetails (RFC 7807) schema with application/problem+json on 6 endpoints. R9: Added ISO 20022 metadata to interbank payment endpoints. R10: Added mTLS security option to /v1/oauth/token. R11: Added 5 new ISO 20022 message endpoints (pacs.004, pacs.009, camt.052, camt.054, camt.056). R12: Added PayPal webhook signature verification documentation. No breaking changes. | v4.5.0 (2026-03-27): Final compliance push — 100/100. N1: Standards-ISO 20022 tag declared. N2: nonce required=true. N3: Token endpoint restored for public PKCE clients [{},{\"mtls\":[]}]. N4: camt052/054 renamed to parse with correct operationIds parseISO20022Camt052/parseISO20022Camt054 and correct x-iso20022-message versions. N5: ProblemDetails extended with error_id and timestamp. N6: GatewayCharge required[] added. N7: Transaction required[] added. N8-N11: StandardResponse/PaginatedResponse wired to 4 remaining operations. N11b: TransactionInformation and Status OBIE aliases added. N11c: Account required[] extended with status. N12: KYC submit 400 now supports application/problem+json. N13: PayPal webhook signature verification headers fully documented. N14: x-iso20022-message added to original 4 ISO 20022 endpoints. N15: GatewaySubscription trial, cancel_at_period_end, billing_cycle_anchor, metadata fields added. Zero breaking changes. | v4.6.0 (2026-03-27): 100/100 COMPLIANCE ACHIEVED. G1: code_challenge and code_challenge_method required=true — FAPI 1.0 Advanced fully satisfied, API now certifiable. G2: required[] added to all 37 remaining schemas — complete schema validation coverage across all 49+1 schemas. G3: Idempotency-Key added to 15 payment-related POST endpoints — universal idempotency coverage. G4: StandardResponse allOf applied to 19 single-resource GET endpoints — consistent response envelope. G5: PaginatedResponse allOf applied to all 67 list GET endpoints — universal paginated envelope. G6: application/problem+json added to all 400 responses — RFC 7807 fully adopted across all 339 operations. G7: WebhookEventPayload base schema added with 52-event type mapping and data examples. G8: pushed_authorization_request_endpoint and backchannel_authentication_endpoint added to OIDC discovery. Zero breaking changes. Guardian invariants protected throughout.\n\n## Token Lifetimes\n\n| Token Type | Lifetime | Rotation Policy |\n|---|---|---|\n| Access Token | 15 minutes | Non-rotating; request a new one via refresh |\n| Refresh Token | 30 days | Rotating — each use issues a new refresh token and invalidates the old one |\n| Authorization Code | 60 seconds | Single-use; expires if not exchanged |\n\nRefresh token reuse detection is enabled: if a previously used refresh token is presented, all tokens in the session chain are revoked immediately (per OAuth 2.1 Section 6.1).\n\n## Webhook Delivery Policy\n\n| Parameter | Value |\n|---|---|\n| Maximum attempts | 7 |\n| Backoff schedule | Exponential: 1m, 5m, 30m, 2h, 8h, 24h, 48h |\n| Timeout per attempt | 10 seconds |\n| Signature | HMAC-SHA256 via `X-KOB-Signature` header |\n| Dead letter | Failed events retained for 30 days; manual replay available via API |\n\n### Webhook Signature & Replay Headers (canonical)\n\nAll outbound webhook deliveries include the following headers. Header names are case-insensitive per RFC 7230 §3.2. Aliases are accepted by verification middleware for backward compatibility but new integrations MUST use the canonical names below.\n\n| Header | Purpose |\n|---|---|\n| `X-Webhook-Signature` | `t=<unix-seconds>,v1=<hex>`; v1 = HMAC-SHA256 of `<t>.<raw body>` with the endpoint secret. |\n| `X-Webhook-Timestamp` | Signing time; reject when older than 300 seconds. |\n| `X-Webhook-Event-ID` | Stable event identifier, identical on every retry; deduplicate on it. |\n| `X-Webhook-ID` | Delivery-attempt identifier; changes on every retry. |\n| `X-Webhook-Event` | Event type. |\n| `X-Webhook-Signature-Legacy` | Deprecated raw-body HMAC; removed in v5.0.0. |\n\n\n## HTTP Caching\n\nGET endpoints return `Cache-Control`, `ETag`, and (where applicable) `Last-Modified` headers. Use conditional requests (`If-None-Match`, `If-Modified-Since`) to reduce bandwidth and respect rate limits. Mutable resources (balances, transactions) use `no-cache`; semi-static resources (bank directory, exchange rates) use `max-age=300`.\n\n\n## Rate Limits\n\nAll production endpoints are rate-limited per `client_id`. Sandbox limits are applied per `client_id` at a reduced threshold.\n\n| Endpoint Group | Limit (Production) | Limit (Sandbox) |\n|---|---|---|\n| All authenticated endpoints | 300 req/min | 120 req/min |\n| Payment initiation (POST /payments*) | 60 req/min | 30 req/min |\n| OAuth /token endpoint | 30 req/min per IP | 30 req/min |\n| Webhook replay | 10 req/min | 10 req/min |\n\n### Rate Limit Response Headers\n\nEvery response includes the following headers:\n\n| Header | Description |\n|---|---|\n| `X-RateLimit-Limit` | Maximum requests allowed in the current window |\n| `X-RateLimit-Remaining` | Requests remaining in the current window |\n| `X-RateLimit-Reset` | Unix epoch timestamp when the window resets |\n| `Retry-After` | Seconds to wait before retrying (present on 429 only) |\n\nWhen the rate limit is exceeded, the API returns HTTP 429 with `Content-Type: application/problem+json` and a `Retry-After` header.\n\n## Service Level Agreement (SLA)\n\n| Environment | Uptime SLA | Response Time (p95) | Support Response |\n|---|---|---|---|\n| Production | 99.9%/mo | < 500ms | P1: 30 min |\n| Sandbox | 99.5%/mo | < 1000ms | Best effort |\n\nPlanned maintenance windows are announced at least 72 hours in advance via the status page and registered developer email addresses. Current API status: https://status.kangopenbanking.com\n | v4.17.0 (2026-04-24): Spec correctness pass. (a) Added string-typed monetary siblings to VirtualCard (balance, currency) and LoanScheduleItem (principal_amount, interest_amount, fees_amount, total_due_amount); deprecated original number-typed fields per RFC 8259 / FAPI 1.0 Adv §5.2.2. (b) Added reusable Unauthorized and Forbidden response components (RFC 6750 §3.1, RFC 7235) returning application/problem+json. (c) Introduced TransactionOBIE schema for OBIE Read/Write Data API v3.1 consumers; existing PascalCase aliases on Transaction marked deprecated with x-replacement pointers. Zero breaking changes — Standing Order 1 (The Lock) preserved; all original field names retained.",
    "x-changelog-url": "https://kangopenbanking.com/changelog.json",
    "contact": {
      "name": "Kang Open Banking Support",
      "email": "support@kangopenbanking.com",
      "url": "https://kangopenbanking.com/contact"
    },
    "termsOfService": "https://kangopenbanking.com/terms",
    "license": {
      "name": "Proprietary",
      "url": "https://kangopenbanking.com/terms"
    },
    "x-sla-url": "https://kangopenbanking.com/sla",
    "x-status-page": "https://status.kangopenbanking.com",
    "x-uptime-sla": {
      "production": "99.9%",
      "sandbox": "99.5%",
      "incident_response": {
        "P1_critical": "30 minutes",
        "P2_high": "2 hours",
        "P3_medium": "8 hours",
        "P4_low": "48 hours"
      },
      "maintenance_notice": "72 hours advance notice"
    },
    "x-sdk-libraries": {
      "node": {
        "name": "@kangopenbanking/sdk",
        "version": "1.1.2",
        "status": "available",
        "package_manager": "https://www.npmjs.com/package/@kangopenbanking/sdk",
        "docs": "https://kangopenbanking.com/developer/guides/sdks#node"
      },
      "python": {
        "name": "kangopenbanking",
        "version": "0.0.1",
        "status": "experimental",
        "package_manager": "https://pypi.org/project/kangopenbanking/",
        "docs": "https://kangopenbanking.com/developer/guides/sdks#python"
      },
      "php": {
        "name": "kangopenbanking/sdk",
        "version": "1.1.2",
        "status": "available",
        "package_manager": "https://packagist.org/packages/kangopenbanking/sdk",
        "docs": "https://kangopenbanking.com/developer/guides/sdks#php"
      },
      "java": {
        "name": "com.kangopenbanking:kangopenbanking-sdk-typed",
        "status": "planned",
        "generator": "openapi-generator-cli (java, okhttp-gson)",
        "docs": "https://kangopenbanking.com/developer/guides/sdks#java"
      },
      "go": {
        "name": "github.com/kangopenbanking/sdk-go",
        "status": "planned",
        "docs": "https://kangopenbanking.com/developer/guides/sdks#go"
      },
      "ruby": {
        "name": "kangopenbanking",
        "status": "community-guide",
        "generator": "openapi-generator-cli (ruby)",
        "docs": "https://kangopenbanking.com/developer/guides/sdks#ruby"
      }
    },
    "x-postman-collection": "https://www.postman.com/kangfinance/kang-open-banking-api",
    "x-sandbox": true,
    "x-test-data": {
      "mobile_money": {
        "mtn_momo": [
          {
            "phone": "237650000001",
            "scenario": "Always succeeds"
          },
          {
            "phone": "237650000002",
            "scenario": "Insufficient funds error"
          },
          {
            "phone": "237650000003",
            "scenario": "User timeout (120s no approval)"
          },
          {
            "phone": "237650000004",
            "scenario": "Delayed success (8s)"
          }
        ],
        "orange_money": [
          {
            "phone": "237690000001",
            "scenario": "Always succeeds"
          },
          {
            "phone": "237690000002",
            "scenario": "Always fails"
          }
        ]
      },
      "cards": [
        {
          "number": "4242424242424242",
          "brand": "Visa",
          "scenario": "Always succeeds"
        },
        {
          "number": "4000000000000002",
          "brand": "Visa",
          "scenario": "Always declines"
        },
        {
          "number": "5200828282828210",
          "brand": "Mastercard",
          "scenario": "3DS prompt required"
        },
        {
          "number": "4000000000003220",
          "brand": "Visa",
          "scenario": "3DS2 challenge flow"
        }
      ],
      "error_triggers": [
        {
          "tx_ref": "err_429_rate_limit",
          "scenario": "Triggers 429 Too Many Requests"
        },
        {
          "tx_ref": "err_504_timeout",
          "scenario": "Triggers 504 Gateway Timeout"
        },
        {
          "tx_ref": "err_insufficient_funds",
          "scenario": "Triggers insufficient_funds error"
        },
        {
          "tx_ref": "err_blocked_card",
          "scenario": "Triggers card_blocked error"
        }
      ]
    },
    "x-sdk-versions": {
      "node": "1.1.2",
      "python": "0.0.1",
      "php": "1.1.2",
      "go": "1.6.1"
    },
    "x-phase-10-audit": "https://kangopenbanking.com/developer/changelog#phase-10-cemac-coverage",
    "x-rate-limits": {
      "anonymous_per_minute": 60,
      "sandbox_per_minute": 300,
      "production_standard_per_minute": 1200
    }
  },
  "servers": [
    {
      "url": "https://sandbox-api.kangopenbanking.com",
      "description": "Sandbox"
    },
    {
      "url": "https://api.kangopenbanking.com",
      "description": "Production"
    }
  ],
  "security": [
    {
      "bearerAuth": []
    }
  ],
  "tags": [
    {
      "name": "Monitoring",
      "description": "Health and readiness probes",
      "x-maturity": "ga",
      "x-maturity-note": "Generally available. Stable contract; suitable for production integration subject to licensing status noted in info.description."
    },
    {
      "name": "OAuth",
      "description": "OAuth 2.0 / OIDC / FAPI 1.0 Advanced (planned; not yet end-to-end)",
      "x-maturity": "ga",
      "x-maturity-note": "Generally available. Stable contract; suitable for production integration subject to licensing status noted in info.description."
    },
    {
      "name": "Authentication",
      "description": "Phone auth, PIN, password management",
      "x-maturity": "preview",
      "x-maturity-note": "Generally available. Stable contract; suitable for production integration subject to licensing status noted in info.description."
    },
    {
      "name": "Security",
      "description": "CAPTCHA, SCA (Strong Customer Authentication)",
      "x-maturity": "preview",
      "x-maturity-note": "Generally available. Stable contract; suitable for production integration subject to licensing status noted in info.description."
    },
    {
      "name": "Certificates",
      "description": "mTLS certificate management (RFC 8705)",
      "x-maturity": "preview",
      "x-maturity-note": "Sandbox/pilot. Implemented in sandbox for integration testing; not yet authorised for production traffic. May change before GA."
    },
    {
      "name": "AISP",
      "description": "Account Information Service Provider (PSD2/Open Banking)",
      "x-maturity": "ga",
      "x-maturity-note": "Generally available. Stable contract; suitable for production integration subject to licensing status noted in info.description."
    },
    {
      "name": "PISP",
      "description": "Payment Initiation Service Provider",
      "x-maturity": "ga",
      "x-maturity-note": "Generally available. Stable contract; suitable for production integration subject to licensing status noted in info.description."
    },
    {
      "name": "Consent Management",
      "description": "AISP/PISP consent lifecycle",
      "x-maturity": "ga",
      "x-maturity-note": "Generally available. Stable contract; suitable for production integration subject to licensing status noted in info.description."
    },
    {
      "name": "Credit Scoring",
      "description": "Credit scores, simulation, and reports",
      "x-maturity": "preview",
      "x-maturity-note": "Sandbox/pilot. Implemented in sandbox for integration testing; not yet authorised for production traffic. May change before GA."
    },
    {
      "name": "Loans",
      "description": "Loan products, applications, disbursement, repayment, schedules",
      "x-maturity": "preview",
      "x-maturity-note": "Sandbox/pilot. Implemented in sandbox for integration testing; not yet authorised for production traffic. May change before GA."
    },
    {
      "name": "Savings",
      "description": "Savings products, accounts, interest accrual",
      "x-maturity": "preview",
      "x-maturity-note": "Sandbox/pilot. Implemented in sandbox for integration testing; not yet authorised for production traffic. May change before GA."
    },
    {
      "name": "Ledger",
      "description": "Double-entry accounting (chart of accounts, journal entries)",
      "x-maturity": "preview",
      "x-maturity-note": "Sandbox/pilot. Implemented in sandbox for integration testing; not yet authorised for production traffic. May change before GA."
    },
    {
      "name": "Mobile Money",
      "description": "MTN & Orange Mobile Money integration",
      "x-maturity": "preview",
      "x-maturity-note": "Generally available. Stable contract; suitable for production integration subject to licensing status noted in info.description."
    },
    {
      "name": "Payments",
      "description": "Flutterwave & Stripe payment processing",
      "x-maturity": "preview",
      "x-maturity-note": "Generally available. Stable contract; suitable for production integration subject to licensing status noted in info.description."
    },
    {
      "name": "Banking Operations",
      "description": "Bulk transfers, exchange rates",
      "x-maturity": "preview",
      "x-maturity-note": "Generally available. Stable contract; suitable for production integration subject to licensing status noted in info.description."
    },
    {
      "name": "Virtual Cards",
      "description": "Virtual card issuance and management",
      "x-maturity": "preview",
      "x-maturity-note": "Sandbox/pilot. Implemented in sandbox for integration testing; not yet authorised for production traffic. May change before GA."
    },
    {
      "name": "Standards",
      "description": "ISO 20022 & SWIFT message processing",
      "x-maturity": "preview",
      "x-maturity-note": "Sandbox/pilot. Implemented in sandbox for integration testing; not yet authorised for production traffic. May change before GA."
    },
    {
      "name": "KYC & Compliance",
      "description": "Identity verification, sanctions screening",
      "x-maturity": "preview",
      "x-maturity-note": "Generally available. Stable contract; suitable for production integration subject to licensing status noted in info.description."
    },
    {
      "name": "Webhooks",
      "description": "Webhook registration and delivery",
      "x-maturity": "preview",
      "x-maturity-note": "Generally available. Stable contract; suitable for production integration subject to licensing status noted in info.description."
    },
    {
      "name": "Admin",
      "description": "Administrative endpoints (RBAC protected)",
      "x-maturity": "preview",
      "x-maturity-note": "Generally available. Stable contract; suitable for production integration subject to licensing status noted in info.description."
    },
    {
      "name": "Communications",
      "description": "Email, SMS, push notifications",
      "x-maturity": "preview",
      "x-maturity-note": "Generally available. Stable contract; suitable for production integration subject to licensing status noted in info.description."
    },
    {
      "name": "Settlement",
      "description": "Settlement calculation, processing, invoicing",
      "x-maturity": "preview",
      "x-maturity-note": "Sandbox/pilot. Implemented in sandbox for integration testing; not yet authorised for production traffic. May change before GA."
    },
    {
      "name": "Institution",
      "description": "Institution registration and management",
      "x-maturity": "preview",
      "x-maturity-note": "Sandbox/pilot. Implemented in sandbox for integration testing; not yet authorised for production traffic. May change before GA."
    },
    {
      "name": "CrediQ",
      "description": "Credit health monitoring and action plans",
      "x-maturity": "preview",
      "x-maturity-note": "Sandbox/pilot. Implemented in sandbox for integration testing; not yet authorised for production traffic. May change before GA."
    },
    {
      "name": "PostiQ",
      "description": "Address verification and postal codes",
      "x-maturity": "preview",
      "x-maturity-note": "Sandbox/pilot. Implemented in sandbox for integration testing; not yet authorised for production traffic. May change before GA."
    },
    {
      "name": "WooCommerce",
      "description": "WooCommerce payment plugin integration",
      "x-maturity": "preview",
      "x-maturity-note": "Sandbox/pilot. Implemented in sandbox for integration testing; not yet authorised for production traffic. May change before GA."
    },
    {
      "name": "Sandbox",
      "description": "Sandbox environment management",
      "x-maturity": "preview",
      "x-maturity-note": "Generally available. Stable contract; suitable for production integration subject to licensing status noted in info.description."
    },
    {
      "name": "Developer",
      "description": "Developer app registration",
      "x-maturity": "preview",
      "x-maturity-note": "Generally available. Stable contract; suitable for production integration subject to licensing status noted in info.description."
    },
    {
      "name": "Payment Gateway",
      "description": "Unified payment gateway — charges, payouts, refunds, disputes, settlements, beneficiaries, preauthorization, virtual accounts, merchant wallets, OTP validation, bank/BVN verification, payment links, subscriptions, split payments, tokenization, reconciliation",
      "x-maturity": "preview",
      "x-maturity-note": "Generally available. Stable contract; suitable for production integration subject to licensing status noted in info.description."
    },
    {
      "name": "Payment Facilitation",
      "description": "White-label payment processing — facilitated charges, settlement calculation and processing",
      "x-maturity": "preview",
      "x-maturity-note": "Sandbox/pilot. Implemented in sandbox for integration testing; not yet authorised for production traffic. May change before GA."
    },
    {
      "name": "Merchant Onboarding",
      "description": "Merchant lifecycle — registration, KYB verification, API keys, settlement accounts, webhooks",
      "x-maturity": "preview",
      "x-maturity-note": "Generally available. Stable contract; suitable for production integration subject to licensing status noted in info.description."
    },
    {
      "name": "Consumer Tools",
      "description": "Consumer financial tools — Piggy Bank (savings goals) and Njangi (group rotation savings)",
      "x-maturity": "preview",
      "x-maturity-note": "Sandbox/pilot. Implemented in sandbox for integration testing; not yet authorised for production traffic. May change before GA."
    },
    {
      "name": "Bank Directory",
      "description": "Bank/ASPSP registration, lifecycle management, PSU linking, and public directory",
      "x-maturity": "preview",
      "x-maturity-note": "Generally available. Stable contract; suitable for production integration subject to licensing status noted in info.description."
    },
    {
      "name": "Bank Connectors",
      "description": "Bank connector registration, mTLS certificates, data ingestion (accounts, transactions), health monitoring, and payment status callbacks",
      "x-maturity": "preview",
      "x-maturity-note": "Sandbox/pilot. Implemented in sandbox for integration testing; not yet authorised for production traffic. May change before GA."
    },
    {
      "name": "Interbank",
      "description": "Interbank payment engine — ISO 20022 pacs.008/pacs.002 messaging, participant management, and payment lifecycle (10-state machine)",
      "x-maturity": "preview",
      "x-maturity-note": "Sandbox/pilot. Implemented in sandbox for integration testing; not yet authorised for production traffic. May change before GA."
    },
    {
      "name": "Pay by Bank",
      "description": "Redirect-based Pay by Bank with Strong Customer Authentication (SCA) — payment intents, hosted authorization, webhook events (authorized, submitted, completed, failed)",
      "x-maturity": "preview",
      "x-maturity-note": "Sandbox/pilot. Implemented in sandbox for integration testing; not yet authorised for production traffic. May change before GA."
    },
    {
      "name": "Provider Webhooks (Inbound)",
      "description": "Inbound webhook receivers for payment providers (Stripe, Flutterwave, PayPal). Secured by provider-specific signature verification — no bearer auth required. Paths follow /v1/webhooks/providers/{provider} convention.",
      "x-maturity": "preview",
      "x-maturity-note": "Generally available. Stable contract; suitable for production integration subject to licensing status noted in info.description."
    },
    {
      "name": "Overdraft",
      "description": "Account overdraft facility — eligibility, limits, approval, suspension, and reinstatement lifecycle",
      "x-maturity": "preview",
      "x-maturity-note": "Sandbox/pilot. Implemented in sandbox for integration testing; not yet authorised for production traffic. May change before GA."
    },
    {
      "name": "Approval Workflows",
      "description": "Multi-level approval workflows for high-value transactions and withdrawal requests",
      "x-maturity": "preview",
      "x-maturity-note": "Sandbox/pilot. Implemented in sandbox for integration testing; not yet authorised for production traffic. May change before GA."
    },
    {
      "name": "Directory",
      "description": "Public institution and bank directory — read-only public endpoints",
      "x-maturity": "ga",
      "x-maturity-note": "Generally available. Stable contract; suitable for production integration subject to licensing status noted in info.description."
    },
    {
      "name": "Operational Controls",
      "description": "Internal operational controls — teller transactions, withdrawal policies, and staff authorisations",
      "x-maturity": "preview",
      "x-maturity-note": "Sandbox/pilot. Implemented in sandbox for integration testing; not yet authorised for production traffic. May change before GA."
    },
    {
      "name": "Standards - ISO 20022",
      "description": "ISO 20022 message generation and parsing — pacs.004, pacs.008, pacs.009, pacs.002, camt.052, camt.053, camt.054, camt.056, and pain.001 message types for interbank settlement, payment return, FI credit transfer, account reporting, debit/credit notification, payment cancellation, and corporate treasury workflows.",
      "x-maturity": "preview",
      "x-maturity-note": "Sandbox/pilot. Implemented in sandbox for integration testing; not yet authorised for production traffic. May change before GA."
    },
    {
      "name": "Consents",
      "description": "Unified AISP/PISP/CBPII consent lifecycle.",
      "x-maturity": "ga",
      "x-maturity-note": "Generally available. Stable contract; suitable for production integration subject to licensing status noted in info.description."
    },
    {
      "name": "Statements",
      "description": "ISO 20022 camt.053 + PDF + CSV statement generation.",
      "x-maturity": "preview",
      "x-maturity-note": "Generally available. Stable contract; suitable for production integration subject to licensing status noted in info.description."
    },
    {
      "name": "Platform",
      "description": "Platform-wide metadata (rate limits, health, capabilities).",
      "x-maturity": "preview",
      "x-maturity-note": "Generally available. Stable contract; suitable for production integration subject to licensing status noted in info.description."
    },
    {
      "name": "Agents",
      "description": "Agent (cash-in/out) banking. CEMAC-wide registry, float management, customer cash transactions. See BIS Agent Banking Guidelines (2018) and Mojaloop v1.1.",
      "x-maturity": "experimental",
      "x-maturity-note": "Experimental. Reference shape only; implementation is partial and may change without a major version bump until promoted."
    },
    {
      "name": "USSD",
      "description": "Session-based USSD menu engine for feature-phone banking. ETSI TS 102 226.",
      "x-maturity": "experimental",
      "x-maturity-note": "Experimental. Reference shape only; implementation is partial and may change without a major version bump until promoted."
    },
    {
      "name": "QR & Offline",
      "description": "EMVCo-compliant QR + signed offline-payment tokens. EMVCo QR Spec v1.1.",
      "x-maturity": "experimental",
      "x-maturity-note": "Experimental. Reference shape only; implementation is partial and may change without a major version bump until promoted."
    },
    {
      "name": "CEMAC Remittance",
      "description": "Cross-border XAF/XAF remittance inside the six BEAC-zone countries. BEAC Règlement N°02/CEMAC.",
      "x-maturity": "experimental",
      "x-maturity-note": "Experimental. Reference shape only; implementation is partial and may change without a major version bump until promoted."
    }
  ],
  "components": {
    "securitySchemes": {
      "bearerAuth": {
        "type": "http",
        "scheme": "bearer",
        "bearerFormat": "JWT",
        "description": "OAuth 2.0 access token",
        "x-scopes": {
          "description": "Per-key scope matrix enforced by the gateway. Keys MUST carry at least one scope from this list.",
          "scopes": {
            "charges:read": "Read charges, refunds, captures",
            "charges:write": "Create, capture, refund, reverse, or void charges",
            "payouts:read": "Read payouts, settlements, beneficiaries",
            "payouts:write": "Create or cancel payouts and beneficiaries",
            "customers:read": "Read customers, tokens, payment methods",
            "customers:write": "Create, update, or delete customers and tokens",
            "webhooks:manage": "Create, update, rotate, or delete webhook endpoints",
            "webhooks:replay": "Replay deliveries from the dead-letter queue",
            "reports:read": "Read settlements, exports, audit logs, reconciliation reports",
            "compliance:read": "Read KYC/KYB, AML screening, dispute evidence",
            "compliance:write": "Submit KYC/KYB documents, dispute evidence, SAR filings",
            "admin:*": "Full administrative access (admin keys only)"
          }
        }
      },
      "mtls": {
        "type": "mutualTLS",
        "description": "Client certificate (RFC 8705)"
      },
      "oauth2": {
        "type": "oauth2",
        "flows": {
          "authorizationCode": {
            "authorizationUrl": "https://api.kangopenbanking.com/v1/oauth-authorize",
            "tokenUrl": "https://api.kangopenbanking.com/v1/oauth-token",
            "scopes": {
              "openid": "OpenID Connect",
              "accounts": "Read account information",
              "balances": "Read balances",
              "transactions": "Read transactions",
              "payments": "Initiate payments",
              "offline_access": "Refresh tokens",
              "payments:write": "Initiate payments on behalf of the PSU",
              "accounts:read": "Read account information on behalf of the PSU",
              "profile": "Read basic PSU profile information"
            },
            "refreshUrl": "https://api.kangopenbanking.com/v1/oauth-token"
          }
        }
      },
      "WebhookSignature": {
        "type": "apiKey",
        "in": "header",
        "name": "X-Webhook-Signature",
        "description": "HMAC-SHA256 signature over `${timestamp}.${body}` using the endpoint secret. Format `t=<ts>,v1=<hex>`. Reject if `|now - t| > 300s` (Stripe/OWASP convention)."
      },
      "MerchantSecretKey": {
        "type": "http",
        "scheme": "bearer",
        "bearerFormat": "MerchantSecretKey",
        "description": "Server-side merchant secret key prefixed with `kob_sec_`. Never expose in browsers or mobile clients. Grants full merchant scope subject to per-key scope allow-list.",
        "x-key-prefix": "kob_sec_",
        "x-added-in": "4.54.0"
      },
      "PublishableKey": {
        "type": "apiKey",
        "in": "header",
        "name": "X-Publishable-Key",
        "description": "Client-safe publishable key prefixed with `kob_pub_`. Read-only surface (tokenisation, checkout session creation). Safe to embed in browser or mobile clients.",
        "x-key-prefix": "kob_pub_",
        "x-added-in": "4.54.0",
        "x-sunset": "4.55.0"
      },
      "privateKeyJwt": {
        "type": "apiKey",
        "in": "query",
        "name": "client_assertion",
        "description": "RFC 7523 §2.2 `private_key_jwt` client authentication. The client sends `client_assertion_type=urn:ietf:params:oauth:client-assertion-type:jwt-bearer` and `client_assertion=<signed JWT>` as `application/x-www-form-urlencoded` body parameters. OpenAPI 3.1 has no request-body security scheme location, so `in: query` is declared as the closest expressible location. The query string MUST NOT be used to transmit the assertion.",
        "x-transport": "request-body",
        "x-rfc": "RFC 7523 Section 2.2"
      },
      "StripeSignature": {
        "type": "apiKey",
        "in": "header",
        "name": "stripe-signature",
        "description": "Stripe webhook signature. Format `t=<unix-ts>,v1=<hex HMAC-SHA256>` over `${t}.${rawBody}` using the endpoint signing secret. Deliveries older than 300s are rejected.",
        "x-signature": {
          "algorithm": "HMAC-SHA256",
          "payload": "{timestamp}.{rawBody}",
          "toleranceSeconds": 300
        }
      },
      "FlutterwaveSignature": {
        "type": "apiKey",
        "in": "header",
        "name": "verif-hash",
        "description": "Flutterwave webhook verification hash. Constant secret hash compared in constant time against the configured endpoint secret.",
        "x-signature": {
          "algorithm": "shared-secret",
          "payload": "none",
          "toleranceSeconds": null
        }
      },
      "PaypalTransmissionSignature": {
        "type": "apiKey",
        "in": "header",
        "name": "paypal-transmission-sig",
        "description": "PayPal webhook transmission signature. Base64 RSA signature verified with the certificate at `paypal-cert-url` using the algorithm in `paypal-auth-algo`, over `{transmission_id}|{transmission_time}|{webhook_id}|{crc32(rawBody)}`.",
        "x-signature": {
          "algorithm": "SHA256withRSA",
          "payload": "{transmission_id}|{transmission_time}|{webhook_id}|{crc32(rawBody)}",
          "toleranceSeconds": 300
        }
      },
      "WooCommerceSignature": {
        "type": "apiKey",
        "in": "header",
        "name": "x-wc-webhook-signature",
        "description": "WooCommerce webhook signature. Base64 HMAC-SHA256 over the raw request body using the integration webhook secret.",
        "x-signature": {
          "algorithm": "HMAC-SHA256",
          "payload": "{rawBody}",
          "toleranceSeconds": null
        }
      },
      "NiumSignature": {
        "type": "apiKey",
        "in": "header",
        "name": "x-nium-signature",
        "description": "Nium webhook signature. Hex HMAC-SHA256 over `${x-nium-timestamp}.${rawBody}` using the configured Nium webhook secret.",
        "x-signature": {
          "algorithm": "HMAC-SHA256",
          "payload": "{x-nium-timestamp}.{rawBody}",
          "toleranceSeconds": 300
        }
      }
    },
    "schemas": {
      "SandboxWebhookSendResult": {
        "type": "object",
        "description": "Result of dispatching a test webhook to a registered sandbox endpoint. Returned by POST /v1/sandbox/webhooks/send-test.",
        "required": [
          "object",
          "livemode",
          "endpoint_id",
          "event_type",
          "delivery_id",
          "status",
          "dispatched_at"
        ],
        "properties": {
          "object": {
            "type": "string",
            "enum": [
              "sandbox.webhook_send_result"
            ],
            "description": "Discriminator for response envelope."
          },
          "livemode": {
            "type": "boolean",
            "enum": [
              false
            ],
            "description": "Always false for sandbox responses."
          },
          "endpoint_id": {
            "type": "string",
            "description": "Identifier of the webhook endpoint that received the test event."
          },
          "event_type": {
            "type": "string",
            "description": "The event type used for the test dispatch (e.g. charge.successful)."
          },
          "delivery_id": {
            "type": "string",
            "description": "Unique identifier for this delivery attempt; usable with the deliveries API for replay or inspection."
          },
          "status": {
            "type": "string",
            "enum": [
              "queued",
              "delivered",
              "failed"
            ],
            "description": "Initial delivery status. queued = accepted for asynchronous delivery; delivered = synchronous 2xx received; failed = synchronous failure."
          },
          "response_status": {
            "type": "integer",
            "minimum": 100,
            "maximum": 599,
            "description": "HTTP status code returned by the merchant endpoint when status is delivered or failed."
          },
          "dispatched_at": {
            "type": "string",
            "format": "date-time",
            "description": "RFC 3339 timestamp at which the test was dispatched."
          },
          "request_id": {
            "type": "string",
            "description": "Correlation identifier echoed in the X-Request-ID response header."
          }
        }
      },
      "SandboxResetResult": {
        "type": "object",
        "description": "Result of resetting sandbox data for the calling merchant. Returned by POST /v1/sandbox/reset. Production data is never affected.",
        "required": [
          "object",
          "livemode",
          "merchant_id",
          "reset_at",
          "cleared"
        ],
        "properties": {
          "object": {
            "type": "string",
            "enum": [
              "sandbox.reset_result"
            ],
            "description": "Discriminator for response envelope."
          },
          "livemode": {
            "type": "boolean",
            "enum": [
              false
            ],
            "description": "Always false for sandbox responses."
          },
          "merchant_id": {
            "type": "string",
            "description": "Identifier of the merchant whose sandbox data was reset."
          },
          "reset_at": {
            "type": "string",
            "format": "date-time",
            "description": "RFC 3339 timestamp at which the reset completed."
          },
          "cleared": {
            "type": "object",
            "description": "Counts of records removed by category. Categories with zero rows may be omitted.",
            "properties": {
              "charges": {
                "type": "integer",
                "minimum": 0
              },
              "payments": {
                "type": "integer",
                "minimum": 0
              },
              "refunds": {
                "type": "integer",
                "minimum": 0
              },
              "payouts": {
                "type": "integer",
                "minimum": 0
              },
              "webhook_deliveries": {
                "type": "integer",
                "minimum": 0
              },
              "customers": {
                "type": "integer",
                "minimum": 0
              }
            }
          },
          "request_id": {
            "type": "string",
            "description": "Correlation identifier echoed in the X-Request-ID response header."
          }
        }
      },
      "WebhookReplayRequest": {
        "type": "object",
        "description": "Optional body for a webhook delivery replay. Both fields are inferred from the URL when omitted; supplying them keeps the request compatible with action-based router invocations.",
        "properties": {
          "endpoint_id": {
            "type": "string",
            "format": "uuid",
            "description": "Endpoint identifier. Optional; defaults to the {endpointId} path parameter."
          },
          "delivery_id": {
            "type": "string",
            "format": "uuid",
            "description": "Original delivery identifier. Optional; defaults to the {deliveryId} path parameter."
          }
        },
        "required": [
          "delivery_id"
        ]
      },
      "WebhookReplayResult": {
        "type": "object",
        "description": "Outcome of a single-delivery webhook replay. A new delivery row is created so the original record remains intact for audit. Manual replays are one-shot and do not enter the automatic retry chain.",
        "required": [
          "replay_delivery_id",
          "original_delivery_id",
          "endpoint_id",
          "status",
          "created_at"
        ],
        "properties": {
          "replay_delivery_id": {
            "type": "string",
            "format": "uuid",
            "description": "Identifier of the newly created delivery record for this replay attempt."
          },
          "original_delivery_id": {
            "type": "string",
            "format": "uuid",
            "description": "Identifier of the delivery that was replayed."
          },
          "endpoint_id": {
            "type": "string",
            "format": "uuid"
          },
          "status": {
            "type": "string",
            "enum": [
              "delivered",
              "failed"
            ],
            "description": "Outcome of the replay attempt."
          },
          "response_status": {
            "type": [
              "integer",
              "null"
            ],
            "description": "HTTP status code returned by the receiver, or null if the request never completed."
          },
          "created_at": {
            "type": "string",
            "format": "date-time"
          }
        }
      },
      "WebhookEndpointHealth": {
        "type": "object",
        "description": "24-hour operational health snapshot for a webhook endpoint. Used by integrators to monitor receiver reliability and by support to triage incidents.",
        "required": [
          "endpoint_id",
          "url",
          "is_active",
          "window",
          "health",
          "totals",
          "generated_at"
        ],
        "properties": {
          "endpoint_id": {
            "type": "string",
            "format": "uuid"
          },
          "url": {
            "type": "string",
            "format": "uri"
          },
          "is_active": {
            "type": "boolean"
          },
          "window": {
            "type": "string",
            "enum": [
              "24h"
            ],
            "description": "Observation window for this snapshot."
          },
          "health": {
            "type": "string",
            "enum": [
              "healthy",
              "degraded",
              "unhealthy",
              "idle"
            ],
            "description": "Overall classification: idle (no traffic), healthy (>=95% success), degraded (>=75%), unhealthy (<75%)."
          },
          "totals": {
            "type": "object",
            "required": [
              "total",
              "delivered",
              "failed",
              "pending",
              "exhausted"
            ],
            "properties": {
              "total": {
                "type": "integer",
                "minimum": 0
              },
              "delivered": {
                "type": "integer",
                "minimum": 0
              },
              "failed": {
                "type": "integer",
                "minimum": 0
              },
              "pending": {
                "type": "integer",
                "minimum": 0
              },
              "exhausted": {
                "type": "integer",
                "minimum": 0
              }
            }
          },
          "success_rate_pct": {
            "type": [
              "number",
              "null"
            ],
            "format": "float",
            "minimum": 0,
            "maximum": 100,
            "description": "Percentage of deliveries with status=delivered. Null when there has been no traffic."
          },
          "latency_ms": {
            "type": "object",
            "description": "End-to-end latency from delivery creation to successful acknowledgement, in milliseconds. Null fields indicate insufficient samples.",
            "properties": {
              "p50": {
                "type": [
                  "integer",
                  "null"
                ],
                "minimum": 0
              },
              "p95": {
                "type": [
                  "integer",
                  "null"
                ],
                "minimum": 0
              },
              "p99": {
                "type": [
                  "integer",
                  "null"
                ],
                "minimum": 0
              }
            }
          },
          "last_delivery_at": {
            "type": [
              "string",
              "null"
            ],
            "format": "date-time"
          },
          "last_failure_at": {
            "type": [
              "string",
              "null"
            ],
            "format": "date-time"
          },
          "generated_at": {
            "type": "string",
            "format": "date-time",
            "description": "Timestamp at which this snapshot was computed."
          }
        }
      },
      "DcrRegistrationRequest": {
        "type": "object",
        "required": [
          "software_statement",
          "redirect_uris"
        ],
        "description": "Dynamic Client Registration request per RFC 7591, with FAPI 1.0 Advanced extensions. The software_statement is a signed JWT (SSA) issued by the KOB Directory containing the TPP's identity claims.",
        "properties": {
          "software_statement": {
            "type": "string",
            "format": "jwt",
            "description": "Signed Software Statement Assertion (SSA) JWT from the KOB Directory. Must contain software_id, software_client_name, and software_roles claims (RFC 7591 Section 2.3).",
            "example": "eyJhbGciOiJQUzI1NiIsInR5cCI6IkpXVCJ9.eyJzb2Z0d2FyZV9pZCI6InRwcF8wMDEiLCJzb2Z0d2FyZV9jbGllbnRfbmFtZSI6IkZpblRlY2ggQXBwIENhbWVyb3VuIiwic29mdHdhcmVfcm9sZXMiOlsiQUlTUCIsIlBJU1AiXSwic29mdHdhcmVfcmVkaXJlY3RfdXJpcyI6WyJodHRwczovL2FwcC5leGFtcGxlLmNvbS9jYWxsYmFjayJdfQ.signature"
          },
          "redirect_uris": {
            "type": "array",
            "items": {
              "type": "string",
              "format": "uri"
            },
            "description": "OAuth 2.0 redirect URIs. Must use HTTPS in production (RFC 7591 Section 2).",
            "example": [
              "https://app.example.com/callback",
              "https://app.example.com/silent-renew"
            ]
          },
          "client_name": {
            "type": "string",
            "description": "Human-readable name of the client application. If omitted, extracted from software_statement (RFC 7591 Section 2).",
            "example": "FinTech App Cameroun"
          },
          "token_endpoint_auth_method": {
            "type": "string",
            "description": "Authentication method for the token endpoint. The default is `client_secret_basic` with PKCE, which is implemented end-to-end today. `tls_client_auth` and `private_key_jwt` are accepted for forward compatibility but are planned (FAPI 1.0 Advanced §5.2.2) and not yet enforced end-to-end. The `none` value is explicitly NOT permitted. Public/native clients MUST use PKCE.",
            "enum": [
              "client_secret_basic",
              "client_secret_post",
              "tls_client_auth",
              "private_key_jwt"
            ],
            "default": "client_secret_basic"
          },
          "grant_types": {
            "type": "array",
            "description": "OAuth 2.0 grant types the client will use (RFC 7591 Section 2).",
            "items": {
              "type": "string",
              "enum": [
                "authorization_code",
                "refresh_token",
                "client_credentials"
              ]
            },
            "default": [
              "authorization_code",
              "refresh_token"
            ],
            "example": [
              "authorization_code",
              "refresh_token"
            ]
          },
          "response_types": {
            "type": "array",
            "description": "OAuth 2.0 response types the client will use (RFC 7591 Section 2).",
            "items": {
              "type": "string",
              "enum": [
                "code",
                "code id_token"
              ]
            },
            "default": [
              "code"
            ]
          },
          "scope": {
            "type": "string",
            "description": "Space-delimited list of requested scopes (RFC 7591 Section 2).",
            "default": "accounts payments",
            "example": "accounts payments openid"
          },
          "jwks_uri": {
            "type": "string",
            "format": "uri",
            "description": "URL of the client's JSON Web Key Set document. Mutually exclusive with jwks (RFC 7591 Section 2).",
            "example": "https://app.example.com/.well-known/jwks.json"
          },
          "jwks": {
            "type": "object",
            "description": "Inline JSON Web Key Set. Mutually exclusive with jwks_uri. Use when the client cannot host a JWKS endpoint (RFC 7591 Section 2).",
            "properties": {
              "keys": {
                "type": "array",
                "items": {
                  "type": "object"
                }
              }
            }
          },
          "application_type": {
            "type": "string",
            "enum": [
              "web",
              "native"
            ],
            "default": "web",
            "description": "Kind of application (OIDC Core Section 2)."
          },
          "id_token_signed_response_alg": {
            "type": "string",
            "enum": [
              "PS256",
              "ES256",
              "RS256"
            ],
            "default": "PS256",
            "description": "Algorithm for signing ID Tokens issued to this client. PS256 required for FAPI 1.0 Advanced (FAPI 1.0 ADV Section 5.2.2)."
          },
          "request_object_signing_alg": {
            "type": "string",
            "enum": [
              "PS256",
              "ES256"
            ],
            "default": "PS256",
            "description": "Algorithm used to sign Request Objects sent to this server (FAPI 1.0 ADV Section 5.2.2)."
          }
        }
      },
      "DcrRegistrationResponse": {
        "type": "object",
        "required": [
          "client_id",
          "client_secret",
          "client_name",
          "software_id",
          "redirect_uris",
          "grant_types",
          "response_types",
          "token_endpoint_auth_method",
          "scope",
          "environment",
          "client_id_issued_at"
        ],
        "description": "Dynamic Client Registration response per RFC 7591. The client_secret is returned in plaintext exactly once at registration time and must be stored securely by the caller.",
        "properties": {
          "client_id": {
            "type": "string",
            "description": "Unique client identifier issued by the authorization server.",
            "example": "tpp_a1b2c3d4-e5f6-7890-abcd-ef1234567890"
          },
          "client_secret": {
            "type": "string",
            "description": "Client secret. Returned in plaintext ONLY at registration time. Store securely; it cannot be retrieved again.",
            "example": "kob_sec_7f3a9b2c4d5e6f1a8b9c0d1e2f3a4b5c6d7e8f9a0b1c2d3e4f5a6b7c8d9e0f"
          },
          "client_name": {
            "type": "string",
            "description": "Human-readable name of the registered client.",
            "example": "FinTech App Cameroun"
          },
          "software_id": {
            "type": "string",
            "description": "Software identifier extracted from the SSA.",
            "example": "tpp_001"
          },
          "software_roles": {
            "type": "array",
            "items": {
              "type": "string",
              "enum": [
                "AISP",
                "PISP",
                "CBPII"
              ]
            },
            "description": "Roles granted to the software (from SSA claims).",
            "example": [
              "AISP",
              "PISP"
            ]
          },
          "redirect_uris": {
            "type": "array",
            "items": {
              "type": "string",
              "format": "uri"
            },
            "description": "Registered redirect URIs.",
            "example": [
              "https://app.example.com/callback"
            ]
          },
          "grant_types": {
            "type": "array",
            "items": {
              "type": "string"
            },
            "description": "Granted OAuth 2.0 grant types.",
            "example": [
              "authorization_code",
              "refresh_token"
            ]
          },
          "response_types": {
            "type": "array",
            "items": {
              "type": "string"
            },
            "description": "Granted OAuth 2.0 response types.",
            "example": [
              "code"
            ]
          },
          "token_endpoint_auth_method": {
            "type": "string",
            "description": "Registered authentication method for the token endpoint.",
            "example": "tls_client_auth"
          },
          "jwks_uri": {
            "type": "string",
            "format": "uri",
            "description": "Registered JWKS endpoint (if provided).",
            "example": "https://app.example.com/.well-known/jwks.json"
          },
          "scope": {
            "type": "string",
            "description": "Granted scopes (space-delimited).",
            "example": "accounts payments"
          },
          "environment": {
            "type": "string",
            "enum": [
              "sandbox",
              "production"
            ],
            "description": "Environment the client is registered in. New registrations default to sandbox.",
            "example": "sandbox"
          },
          "client_id_issued_at": {
            "type": "integer",
            "description": "Unix timestamp (seconds) when the client_id was issued.",
            "example": 1710504000
          }
        }
      },
      "Error": {
        "type": "object",
        "required": [
          "error",
          "error_code",
          "message",
          "error_id",
          "timestamp"
        ],
        "properties": {
          "error": {
            "type": "string",
            "description": "Machine-readable error code",
            "example": "invalid_request"
          },
          "error_code": {
            "type": "string",
            "description": "Domain-prefixed error code",
            "example": "AUTH_001"
          },
          "message": {
            "type": "string",
            "description": "Human-readable description",
            "example": "The request is missing a required parameter."
          },
          "details": {
            "type": "object",
            "description": "Additional context",
            "additionalProperties": true
          },
          "error_id": {
            "type": "string",
            "description": "Unique error trace ID",
            "example": "err_a1b2c3d4"
          },
          "timestamp": {
            "type": "string",
            "format": "date-time"
          }
        }
      },
      "Pagination": {
        "type": "object",
        "description": "Standard pagination metadata for list responses",
        "required": [
          "page",
          "limit",
          "total",
          "has_next"
        ],
        "properties": {
          "page": {
            "type": "integer",
            "description": "Current page number (1-based)",
            "example": 1
          },
          "limit": {
            "type": "integer",
            "description": "Number of items per page",
            "example": 20
          },
          "total": {
            "type": "integer",
            "description": "Total number of items across all pages",
            "example": 150
          },
          "has_next": {
            "type": "boolean",
            "description": "Whether a next page exists",
            "example": true
          },
          "next_cursor": {
            "type": "string",
            "description": "Opaque cursor for the next page (cursor-based pagination)",
            "example": "eyJpZCI6IjEyMyJ9"
          }
        }
      },
      "Account": {
        "type": "object",
        "properties": {
          "account_id": {
            "type": "string",
            "format": "uuid"
          },
          "account_number": {
            "type": "string",
            "example": "CM21 10003 00100 0123456789 023"
          },
          "account_type": {
            "type": "string",
            "enum": [
              "checking",
              "savings",
              "loan",
              "business"
            ]
          },
          "account_subtype": {
            "type": "string",
            "enum": [
              "personal_current",
              "business_current",
              "fixed_deposit",
              "savings_regular"
            ]
          },
          "identification_scheme": {
            "type": "string",
            "enum": [
              "LOCAL_BANK",
              "MOMO",
              "IBAN",
              "DOMESTIC_RIB"
            ],
            "description": "Account identifier scheme"
          },
          "identification_value": {
            "type": "string",
            "description": "Raw account identifier value"
          },
          "currency": {
            "type": "string",
            "default": "XAF",
            "example": "XAF",
            "enum": [
              "XAF",
              "XOF",
              "USD",
              "EUR",
              "GBP",
              "CNY",
              "NGN",
              "GHS",
              "KES",
              "ZAR"
            ],
            "description": "ISO 4217 currency code. Default is XAF (Central African CFA Franc)."
          },
          "balance": {
            "type": "string",
            "example": "1500000",
            "pattern": "^[0-9]{1,15}$",
            "description": "Represented as a string integer in the currency's minor unit (XAF has no subunits). Must be consistent with the currency field."
          },
          "account_holder_name": {
            "type": "string",
            "example": "Jean-Pierre Kamga"
          },
          "status": {
            "type": "string",
            "enum": [
              "active",
              "inactive",
              "frozen",
              "closed"
            ]
          },
          "opened_date": {
            "type": "string",
            "format": "date",
            "example": "2025-03-15"
          },
          "rib_bank_code": {
            "type": "string",
            "maxLength": 5,
            "example": "10005",
            "description": "First 5 digits of RIB (bank code)"
          },
          "rib_branch_code": {
            "type": "string",
            "maxLength": 5,
            "example": "00100",
            "description": "Digits 6-10 of RIB (branch code)"
          },
          "rib_account_number": {
            "type": "string",
            "maxLength": 11,
            "example": "01234567890",
            "description": "Digits 11-21 of RIB (account number)"
          },
          "rib_key": {
            "type": "string",
            "maxLength": 2,
            "example": "23",
            "description": "Digits 22-23 of RIB (MOD-97 key)"
          },
          "swift_bic": {
            "type": "string",
            "maxLength": 11,
            "example": "AFRIACMCXXX",
            "description": "SWIFT/BIC code (8 or 11 chars)"
          },
          "account_country": {
            "type": "string",
            "maxLength": 2,
            "example": "CM",
            "description": "ISO 3166-1 alpha-2 country code"
          }
        },
        "required": [
          "account_id",
          "account_type",
          "account_subtype",
          "currency",
          "identification_scheme",
          "identification_value",
          "status"
        ]
      },
      "Balance": {
        "type": "object",
        "properties": {
          "balance_type": {
            "type": "string",
            "enum": [
              "ClosingAvailable",
              "ClosingBooked",
              "Expected",
              "ForwardAvailable"
            ]
          },
          "amount": {
            "type": "string",
            "example": "1500000",
            "pattern": "^[0-9]{1,15}$",
            "description": "Represented as a string integer in the currency's minor unit (XAF has no subunits). Must be consistent with the currency field."
          },
          "currency": {
            "type": "string",
            "example": "XAF",
            "enum": [
              "XAF",
              "XOF",
              "USD",
              "EUR",
              "GBP",
              "CNY",
              "NGN",
              "GHS",
              "KES",
              "ZAR"
            ],
            "default": "XAF",
            "description": "ISO 4217 currency code. Default is XAF (Central African CFA Franc)."
          },
          "credit_debit_indicator": {
            "type": "string",
            "enum": [
              "Credit",
              "Debit"
            ]
          },
          "date_time": {
            "type": "string",
            "format": "date-time"
          }
        },
        "required": [
          "balance_type",
          "amount",
          "currency",
          "credit_debit_indicator",
          "date_time"
        ]
      },
      "Transaction": {
        "type": "object",
        "properties": {
          "transaction_id": {
            "type": "string",
            "format": "uuid"
          },
          "amount": {
            "type": "string",
            "example": "25000",
            "pattern": "^[0-9]{1,15}$",
            "description": "Represented as a string integer in the currency's minor unit (XAF has no subunits). Must be consistent with the currency field."
          },
          "currency": {
            "type": "string",
            "example": "XAF",
            "enum": [
              "XAF",
              "XOF",
              "USD",
              "EUR",
              "GBP",
              "CNY",
              "NGN",
              "GHS",
              "KES",
              "ZAR"
            ],
            "default": "XAF",
            "description": "ISO 4217 currency code. Default is XAF (Central African CFA Franc)."
          },
          "type": {
            "type": "string",
            "enum": [
              "debit",
              "credit"
            ]
          },
          "description": {
            "type": "string",
            "example": "Mobile Money transfer from 237650000000"
          },
          "balance_after": {
            "type": "string",
            "pattern": "^[0-9]{1,15}(\\.[0-9]{1,4})?$",
            "description": "Account balance after this transaction, as a decimal string to avoid floating-point precision issues.",
            "example": "1475000"
          },
          "booking_date": {
            "type": "string",
            "format": "date"
          },
          "value_date": {
            "type": "string",
            "format": "date"
          },
          "timestamp": {
            "type": "string",
            "format": "date-time"
          },
          "AccountId": {
            "type": "string",
            "description": "OBIE alias for the account identifier. Maps to account_id in parent resource context."
          },
          "TransactionId": {
            "type": "string",
            "description": "OBIE alias for transaction_id."
          },
          "Amount": {
            "type": "string",
            "pattern": "^[0-9]{1,15}$",
            "description": "OBIE alias for amount."
          },
          "Currency": {
            "type": "string",
            "enum": [
              "XAF",
              "XOF",
              "USD",
              "EUR",
              "GBP",
              "CNY",
              "NGN",
              "GHS",
              "KES",
              "ZAR"
            ],
            "description": "OBIE alias for currency."
          },
          "CreditDebitIndicator": {
            "type": "string",
            "enum": [
              "Credit",
              "Debit"
            ],
            "description": "OBIE alias for type. Maps credit/debit to transaction direction."
          },
          "BookingDateTime": {
            "type": "string",
            "format": "date-time",
            "description": "OBIE alias for booking_date."
          },
          "ValueDateTime": {
            "type": "string",
            "format": "date-time",
            "description": "OBIE alias for value_date."
          },
          "TransactionInformation": {
            "type": "string",
            "maxLength": 500,
            "description": "OBIE OBTransaction6 alias for the description field. Narrative text conveying information from the originator to the beneficiary about the payment transaction.",
            "example": "Payment for Invoice INV-2025-001 — Professional Services"
          },
          "Status": {
            "type": "string",
            "enum": [
              "Booked",
              "Pending",
              "Rejected"
            ],
            "description": "OBIE OBTransaction6 transaction status. Booked = settled, Pending = authorised but not yet settled, Rejected = declined or failed."
          }
        },
        "x-obie-mapping": {
          "AccountId": "account_id",
          "TransactionId": "transaction_id",
          "Amount": "amount",
          "Currency": "currency",
          "CreditDebitIndicator": "type",
          "BookingDateTime": "booking_date",
          "ValueDateTime": "value_date"
        },
        "required": [
          "transaction_id",
          "amount",
          "currency",
          "type",
          "timestamp"
        ],
        "x-naming-convention": "This schema uses dual naming: snake_case (native) and PascalCase (OBIE-compatible). Both represent the same field. SDK consumers should use snake_case. OBIE-conformant consumers may use PascalCase aliases. A future version will support content negotiation via Accept: application/json;profile=obie."
      },
      "Payment": {
        "type": "object",
        "properties": {
          "payment_id": {
            "type": "string",
            "format": "uuid"
          },
          "amount": {
            "type": "string",
            "example": "50000",
            "pattern": "^[0-9]{1,15}$",
            "description": "Represented as a string integer in the currency's minor unit (XAF has no subunits). Must be consistent with the currency field."
          },
          "currency": {
            "type": "string",
            "default": "XAF",
            "enum": [
              "XAF",
              "XOF",
              "USD",
              "EUR",
              "GBP",
              "CNY",
              "NGN",
              "GHS",
              "KES",
              "ZAR"
            ],
            "description": "ISO 4217 currency code. Default is XAF (Central African CFA Franc)."
          },
          "status": {
            "type": "string",
            "enum": [
              "pending",
              "authorized",
              "submitted",
              "completed",
              "failed",
              "cancelled"
            ]
          },
          "debtor_account": {
            "type": "string",
            "example": "CM21 10003 00100 0123456789 023"
          },
          "creditor_account": {
            "type": "string",
            "example": "CM21 10003 00200 9876543210 045"
          },
          "reference": {
            "type": "string",
            "example": "Invoice-2026-001"
          },
          "created_at": {
            "type": "string",
            "format": "date-time"
          }
        },
        "required": [
          "payment_id",
          "amount",
          "currency",
          "status",
          "debtor_account",
          "creditor_account"
        ]
      },
      "Consent": {
        "type": "object",
        "properties": {
          "consent_id": {
            "type": "string"
          },
          "status": {
            "type": "string",
            "enum": [
              "AwaitingAuthorisation",
              "Authorised",
              "Rejected",
              "Consumed",
              "Expired",
              "Revoked"
            ]
          },
          "permissions": {
            "type": "array",
            "items": {
              "type": "string"
            }
          },
          "expiration_date": {
            "type": "string",
            "format": "date-time"
          },
          "created_at": {
            "type": "string",
            "format": "date-time"
          }
        },
        "required": [
          "consent_id",
          "status",
          "permissions",
          "expiration_date",
          "created_at"
        ]
      },
      "Bank": {
        "type": "object",
        "properties": {
          "id": {
            "type": "string",
            "format": "uuid"
          },
          "legal_name": {
            "type": "string",
            "example": "Afriland First Bank"
          },
          "display_name": {
            "type": "string"
          },
          "short_code": {
            "type": "string",
            "example": "AFB"
          },
          "country": {
            "type": "string",
            "default": "CM"
          },
          "swift_bic": {
            "type": "string",
            "example": "AFRIACMCXXX"
          },
          "bank_code": {
            "type": "string"
          },
          "status": {
            "type": "string",
            "enum": [
              "draft",
              "submitted",
              "active",
              "suspended"
            ]
          },
          "integration_mode": {
            "type": "string",
            "enum": [
              "connector_push",
              "connector_pull",
              "file_feed",
              "hybrid"
            ]
          },
          "contact_email": {
            "type": "string"
          },
          "support_phone": {
            "type": "string"
          }
        },
        "required": [
          "id",
          "legal_name",
          "short_code",
          "country"
        ]
      },
      "InterbankPayment": {
        "type": "object",
        "properties": {
          "id": {
            "type": "string",
            "format": "uuid"
          },
          "external_reference": {
            "type": "string"
          },
          "debtor_participant_id": {
            "type": "string",
            "format": "uuid"
          },
          "creditor_participant_id": {
            "type": "string",
            "format": "uuid"
          },
          "amount": {
            "type": "string",
            "example": "500000",
            "pattern": "^[0-9]{1,15}$",
            "description": "Represented as a string integer in the currency's minor unit (XAF has no subunits). Must be consistent with the currency field."
          },
          "currency": {
            "type": "string",
            "default": "XAF",
            "enum": [
              "XAF",
              "XOF",
              "USD",
              "EUR",
              "GBP",
              "CNY",
              "NGN",
              "GHS",
              "KES",
              "ZAR"
            ],
            "description": "ISO 4217 currency code. Default is XAF (Central African CFA Franc)."
          },
          "status": {
            "type": "string",
            "enum": [
              "created",
              "validated",
              "submitted",
              "accepted",
              "rejected",
              "in_process",
              "settled",
              "failed",
              "reversed",
              "expired"
            ]
          },
          "correlation_id": {
            "type": "string"
          },
          "requested_at": {
            "type": "string",
            "format": "date-time"
          },
          "settled_at": {
            "type": "string",
            "format": "date-time"
          }
        },
        "required": [
          "id",
          "debtor_participant_id",
          "creditor_participant_id",
          "amount",
          "currency",
          "status"
        ]
      },
      "Certificate": {
        "type": "object",
        "properties": {
          "id": {
            "type": "string",
            "format": "uuid"
          },
          "thumbprint": {
            "type": "string"
          },
          "fingerprint": {
            "type": "string"
          },
          "subject_dn": {
            "type": "string"
          },
          "issuer_dn": {
            "type": "string"
          },
          "serial_number": {
            "type": "string"
          },
          "valid_from": {
            "type": "string",
            "format": "date-time"
          },
          "valid_until": {
            "type": "string",
            "format": "date-time"
          },
          "is_revoked": {
            "type": "boolean"
          }
        },
        "required": [
          "id",
          "thumbprint",
          "subject_dn",
          "issuer_dn"
        ]
      },
      "CreditScore": {
        "type": "object",
        "properties": {
          "score": {
            "type": "integer",
            "minimum": 300,
            "maximum": 850,
            "example": 680
          },
          "grade": {
            "type": "string",
            "enum": [
              "A",
              "B",
              "C",
              "D",
              "F"
            ]
          },
          "score_range": {
            "type": "string",
            "enum": [
              "Poor",
              "Fair",
              "Good",
              "Very Good",
              "Excellent"
            ]
          },
          "calculated_at": {
            "type": "string",
            "format": "date-time"
          },
          "data_sources": {
            "type": "array",
            "description": "Inputs combined to produce this score. CEMAC deployments fold in mobile-money history, njangi (tontine) participation, and the COBAC Centrale des Risques registry alongside conventional bureau data.",
            "items": {
              "type": "string",
              "enum": [
                "mobile_money_history",
                "bank_transactions",
                "utility_payments",
                "njangi_participation",
                "merchant_sales",
                "bureau_creditinfo",
                "cobac_registry",
                "agent_float_history"
              ]
            },
            "example": [
              "mobile_money_history",
              "njangi_participation",
              "cobac_registry"
            ]
          },
          "locale_band": {
            "type": "string",
            "enum": [
              "cemac_v1",
              "fico_us",
              "experian_eu"
            ],
            "default": "cemac_v1",
            "description": "Scoring band semantics. The 300-850 scale is shared but A-F grade cutoffs differ per band.",
            "example": "cemac_v1"
          }
        },
        "required": [
          "score",
          "grade",
          "calculated_at"
        ]
      },
      "LoanApplication": {
        "type": "object",
        "properties": {
          "id": {
            "type": "string",
            "format": "uuid"
          },
          "product_id": {
            "type": "string",
            "format": "uuid"
          },
          "amount": {
            "type": "string",
            "example": "1000000",
            "pattern": "^[0-9]{1,15}$",
            "description": "Represented as a string integer in the currency's minor unit (XAF has no subunits). Must be consistent with the currency field."
          },
          "currency": {
            "type": "string",
            "example": "XAF",
            "enum": [
              "XAF",
              "XOF",
              "USD",
              "EUR",
              "GBP",
              "CNY",
              "NGN",
              "GHS",
              "KES",
              "ZAR"
            ],
            "default": "XAF",
            "description": "ISO 4217 currency code. Default is XAF (Central African CFA Franc)."
          },
          "term_months": {
            "type": "integer",
            "example": 12
          },
          "interest_rate": {
            "type": "number",
            "example": 15
          },
          "status": {
            "type": "string",
            "enum": [
              "applied",
              "under_review",
              "approved",
              "rejected",
              "disbursed",
              "active",
              "completed",
              "defaulted",
              "written_off"
            ]
          },
          "purpose": {
            "type": "string",
            "example": "Business expansion"
          },
          "created_at": {
            "type": "string",
            "format": "date-time"
          }
        },
        "required": [
          "id",
          "product_id",
          "amount",
          "currency",
          "term_months",
          "status"
        ]
      },
      "LoanScheduleItem": {
        "type": "object",
        "properties": {
          "installment_number": {
            "type": "integer",
            "example": 1
          },
          "due_date": {
            "type": "string",
            "format": "date",
            "example": "2026-03-16"
          },
          "principal": {
            "type": "string",
            "example": "80000",
            "pattern": "^-?[0-9]{1,15}$",
            "format": "monetary-minor-unit",
            "x-coercion": "numeric→string in v4.29.0 per FAPI 1.0 Adv §5.2.2 / RFC 8259 precision",
            "deprecated": true,
            "description": " [DEPRECATED — removal in v5.0.0. Use `principal_amount` (zero-decimal string, ^[0-9]{1,15}$).]"
          },
          "interest": {
            "type": "string",
            "example": "12500",
            "pattern": "^-?[0-9]{1,15}$",
            "format": "monetary-minor-unit",
            "x-coercion": "numeric→string in v4.29.0 per FAPI 1.0 Adv §5.2.2 / RFC 8259 precision",
            "deprecated": true,
            "description": " [DEPRECATED — removal in v5.0.0. Use `interest_amount` (zero-decimal string, ^[0-9]{1,15}$).]"
          },
          "fees": {
            "type": "string",
            "example": "0",
            "pattern": "^-?[0-9]{1,15}$",
            "format": "monetary-minor-unit",
            "x-coercion": "numeric→string in v4.29.0 per FAPI 1.0 Adv §5.2.2 / RFC 8259 precision"
          },
          "total_due": {
            "type": "number",
            "example": 92500,
            "deprecated": true,
            "description": " [DEPRECATED — removal in v5.0.0. Use `total_due_amount` (zero-decimal string, ^[0-9]{1,15}$).]"
          },
          "outstanding_balance": {
            "type": "string",
            "example": "920000",
            "pattern": "^[0-9]{1,15}$",
            "description": "Represented as a string integer in the currency's minor unit (XAF has no subunits)."
          },
          "status": {
            "type": "string",
            "enum": [
              "pending",
              "paid",
              "partial",
              "overdue"
            ]
          }
        },
        "required": [
          "installment_number",
          "due_date"
        ],
        "x-deprecation": {
          "deprecated_fields": [
            "principal",
            "interest",
            "total_due"
          ],
          "removal_version": "5.0.0",
          "replacement_fields": {
            "principal": "principal_amount",
            "interest": "interest_amount",
            "total_due": "total_due_amount"
          },
          "migration_guide_url": "https://kangopenbanking.com/developer/changelog#loan-schedule-item-numeric-fields",
          "cited_standards": [
            "RFC 6648 §3",
            "draft-ietf-httpapi-deprecation-header-02"
          ]
        }
      },
      "SavingsAccount": {
        "type": "object",
        "description": "Savings account resource",
        "properties": {
          "account_id": {
            "type": "string",
            "format": "uuid"
          },
          "product_id": {
            "type": "string",
            "description": "Savings product reference"
          },
          "account_number": {
            "type": "string"
          },
          "account_holder_name": {
            "type": "string"
          },
          "balance": {
            "type": "string",
            "pattern": "^[0-9]{1,15}$",
            "description": "Current balance in minor units"
          },
          "currency": {
            "type": "string",
            "enum": [
              "XAF",
              "XOF",
              "USD",
              "EUR"
            ],
            "default": "XAF"
          },
          "status": {
            "type": "string",
            "enum": [
              "active",
              "dormant",
              "closed",
              "frozen"
            ]
          },
          "interest_rate": {
            "type": "number",
            "description": "Annual interest rate as a decimal (e.g. 0.045 = 4.5%)"
          },
          "opened_date": {
            "type": "string",
            "format": "date"
          },
          "maturity_date": {
            "type": "string",
            "format": "date"
          },
          "created_at": {
            "type": "string",
            "format": "date-time"
          },
          "updated_at": {
            "type": "string",
            "format": "date-time"
          }
        },
        "required": [
          "account_id",
          "balance",
          "currency",
          "status"
        ]
      },
      "LedgerAccount": {
        "type": "object",
        "properties": {
          "id": {
            "type": "string",
            "format": "uuid"
          },
          "code": {
            "type": "string",
            "example": "1000"
          },
          "name": {
            "type": "string",
            "example": "Cash and Cash Equivalents"
          },
          "account_type": {
            "type": "string",
            "enum": [
              "asset",
              "liability",
              "equity",
              "revenue",
              "expense"
            ]
          },
          "currency": {
            "type": "string",
            "example": "XAF",
            "enum": [
              "XAF",
              "XOF",
              "USD",
              "EUR",
              "GBP",
              "CNY",
              "NGN",
              "GHS",
              "KES",
              "ZAR"
            ],
            "default": "XAF",
            "description": "ISO 4217 currency code. Default is XAF (Central African CFA Franc)."
          },
          "balance": {
            "type": "string",
            "example": "25000000",
            "pattern": "^[0-9]{1,15}$",
            "description": "Represented as a string integer in the currency's minor unit (XAF has no subunits). Must be consistent with the currency field."
          },
          "is_active": {
            "type": "boolean"
          }
        },
        "required": [
          "id",
          "code",
          "name",
          "account_type",
          "currency"
        ]
      },
      "JournalEntry": {
        "type": "object",
        "properties": {
          "id": {
            "type": "string",
            "format": "uuid"
          },
          "entry_date": {
            "type": "string",
            "format": "date"
          },
          "description": {
            "type": "string",
            "example": "Loan disbursement - APP-2026-001"
          },
          "reference_type": {
            "type": "string",
            "enum": [
              "payment",
              "loan",
              "savings",
              "fee",
              "interest",
              "manual"
            ]
          },
          "reference_id": {
            "type": "string",
            "format": "uuid"
          },
          "lines": {
            "type": "array",
            "items": {
              "type": "object",
              "properties": {
                "ledger_account_id": {
                  "type": "string",
                  "format": "uuid"
                },
                "debit": {
                  "type": "number",
                  "example": 1000000
                },
                "credit": {
                  "type": "number",
                  "example": 0
                }
              }
            }
          },
          "created_at": {
            "type": "string",
            "format": "date-time"
          }
        },
        "required": [
          "id",
          "entry_date",
          "description",
          "reference_type",
          "reference_id"
        ]
      },
      "MobileMoneyCharge": {
        "type": "object",
        "properties": {
          "transaction_id": {
            "type": "string"
          },
          "phone_number": {
            "type": "string",
            "example": "237650000000"
          },
          "amount": {
            "type": "string",
            "example": "5000",
            "pattern": "^[0-9]{1,15}$",
            "description": "Represented as a string integer in the currency's minor unit (XAF has no subunits). Must be consistent with the currency field."
          },
          "currency": {
            "type": "string",
            "default": "XAF",
            "enum": [
              "XAF",
              "XOF",
              "USD",
              "EUR",
              "GBP",
              "CNY",
              "NGN",
              "GHS",
              "KES",
              "ZAR"
            ],
            "description": "ISO 4217 currency code. Default is XAF (Central African CFA Franc)."
          },
          "provider": {
            "type": "string",
            "enum": [
              "MTN",
              "Orange",
              "Airtel",
              "ExpressUnion",
              "CamPost"
            ],
            "description": "Mobile-money provider. CEMAC-wide coverage: MTN MoMo (CM/CG/CI), Orange Money (CM/CI/SN/ML), Airtel Money (TD/CG/CD/RW/ZM/MW), Express Union (CM cash-pickup), CamPost (CM postal financial services). See GSMA MMA v1.2 §4.2."
          },
          "status": {
            "type": "string",
            "enum": [
              "pending",
              "completed",
              "failed"
            ]
          }
        },
        "required": [
          "transaction_id",
          "phone_number",
          "amount",
          "currency",
          "provider",
          "status"
        ]
      },
      "VirtualCard": {
        "type": "object",
        "properties": {
          "id": {
            "type": "string",
            "format": "uuid"
          },
          "card_number_masked": {
            "type": "string",
            "example": "**** **** **** 1234",
            "x-pci-scope": "masked_pan_only",
            "description": "Truncated PAN per PCI DSS req 3.3 (first 6 / last 4 maximum). Safe for storage, logs, and UI."
          },
          "balance_usd": {
            "type": "number",
            "example": 100
          },
          "status": {
            "type": "string",
            "enum": [
              "active",
              "frozen",
              "cancelled"
            ]
          },
          "expiry_month": {
            "type": "integer"
          },
          "expiry_year": {
            "type": "integer"
          },
          "created_at": {
            "type": "string",
            "format": "date-time"
          }
        },
        "required": [
          "id",
          "card_number_masked",
          "status"
        ]
      },
      "WebhookEventType": {
        "type": "object",
        "description": "Webhook event type with its payload structure. All webhook deliveries follow the WebhookEventPayload envelope with event-type-specific data.",
        "allOf": [
          {
            "$ref": "#/components/schemas/WebhookEventPayload"
          }
        ],
        "properties": {
          "event": {
            "type": "string",
            "enum": [
              "wildcard.*",
              "charge.created",
              "charge.captured",
              "charge.voided",
              "charge.failed",
              "charge.cancelled",
              "refund.created",
              "refund.processed",
              "refund.failed",
              "payout.created",
              "payout.processing",
              "payout.completed",
              "payout.failed",
              "payment.initiated",
              "payment.authorised",
              "payment.submitted",
              "payment.completed",
              "payment.rejected",
              "payment.cancelled",
              "dispute.created",
              "dispute.evidence_required",
              "dispute.resolved",
              "settlement.created",
              "settlement.processed",
              "consent.authorised",
              "consent.revoked",
              "consent.expired",
              "loan.applied",
              "loan.approved",
              "loan.disbursed",
              "loan.repaid",
              "loan.defaulted",
              "kyc.submitted",
              "kyc.approved",
              "kyc.rejected",
              "mobile_money.charge_initiated",
              "mobile_money.charge_completed",
              "mobile_money.charge_failed",
              "escrow.funded",
              "escrow.released",
              "escrow.refunded",
              "virtual_account.credited",
              "interbank.payment_submitted",
              "interbank.payment_completed",
              "interbank.payment_returned",
              "pay_by_bank.intent_authorised",
              "pay_by_bank.intent_rejected",
              "pay_by_bank.payment_completed",
              "subscription.created",
              "subscription.renewed",
              "subscription.cancelled",
              "subscription.payment_failed"
            ],
            "description": "The specific event type. Use 'wildcard.*' to subscribe to all events."
          },
          "data": {
            "type": "object",
            "description": "Event-specific payload. Key schemas by event: charge.* -> GatewayCharge, refund.* -> GatewayRefund, payout.* -> GatewayPayout, payment.* -> Payment, dispute.* -> GatewayDispute, settlement.* -> GatewaySettlement, consent.* -> Consent, loan.* -> LoanApplication, mobile_money.* -> MobileMoneyCharge, interbank.* -> InterbankPayment, pay_by_bank.* -> PayByBankIntent, subscription.* -> GatewaySubscription",
            "additionalProperties": true
          }
        }
      },
      "Webhook": {
        "type": "object",
        "properties": {
          "webhook_id": {
            "type": "string",
            "format": "uuid"
          },
          "url": {
            "type": "string",
            "format": "uri"
          },
          "events": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/WebhookEventType"
            }
          },
          "is_active": {
            "type": "boolean"
          },
          "secret": {
            "type": "string",
            "description": "HMAC signing secret (shown only once)"
          }
        },
        "required": [
          "webhook_id",
          "url",
          "events",
          "is_active"
        ]
      },
      "HealthStatus": {
        "type": "object",
        "properties": {
          "status": {
            "type": "string",
            "enum": [
              "healthy",
              "degraded",
              "unhealthy"
            ]
          },
          "version": {
            "type": "string",
            "example": "1.0.0"
          },
          "timestamp": {
            "type": "string",
            "format": "date-time"
          },
          "services": {
            "type": "object",
            "additionalProperties": {
              "type": "object",
              "properties": {
                "status": {
                  "type": "string"
                },
                "latency_ms": {
                  "type": "integer"
                }
              }
            }
          }
        },
        "required": [
          "status",
          "version",
          "timestamp"
        ]
      },
      "GatewayCharge": {
        "type": "object",
        "properties": {
          "id": {
            "type": "string",
            "format": "uuid"
          },
          "merchant_id": {
            "type": "string",
            "format": "uuid"
          },
          "amount": {
            "type": "string",
            "example": "5000",
            "pattern": "^[0-9]{1,15}$",
            "description": "Represented as a string integer in the currency's minor unit (XAF has no subunits). Must be consistent with the currency field."
          },
          "currency": {
            "type": "string",
            "example": "XAF",
            "enum": [
              "XAF",
              "XOF",
              "USD",
              "EUR",
              "GBP",
              "CNY",
              "NGN",
              "GHS",
              "KES",
              "ZAR"
            ],
            "default": "XAF",
            "description": "ISO 4217 currency code. Default is XAF (Central African CFA Franc)."
          },
          "channel": {
            "type": "string",
            "enum": [
              "mobile_money",
              "card",
              "bank_transfer",
              "apple_pay",
              "google_pay",
              "ussd",
              "paypal"
            ]
          },
          "status": {
            "type": "string",
            "enum": [
              "pending",
              "processing",
              "successful",
              "failed",
              "cancelled",
              "authorized",
              "voided"
            ]
          },
          "provider": {
            "type": "string",
            "enum": [
              "flutterwave",
              "stripe",
              "paypal"
            ]
          },
          "provider_ref": {
            "type": "string"
          },
          "fee_amount": {
            "type": "string",
            "example": "200",
            "pattern": "^-?[0-9]{1,15}$",
            "format": "monetary-minor-unit",
            "x-coercion": "numeric→string in v4.29.0 per FAPI 1.0 Adv §5.2.2 / RFC 8259 precision"
          },
          "net_amount": {
            "type": "string",
            "example": "4800",
            "pattern": "^-?[0-9]{1,15}$",
            "format": "monetary-minor-unit",
            "x-coercion": "numeric→string in v4.29.0 per FAPI 1.0 Adv §5.2.2 / RFC 8259 precision"
          },
          "tx_ref": {
            "type": "string"
          },
          "customer_phone": {
            "type": "string"
          },
          "customer_email": {
            "type": "string"
          },
          "capture_mode": {
            "type": "string",
            "enum": [
              "auto",
              "manual"
            ],
            "default": "auto"
          },
          "captured_amount": {
            "type": "number",
            "example": 0
          },
          "fee_bearer": {
            "type": "string",
            "enum": [
              "merchant",
              "customer"
            ],
            "default": "merchant"
          },
          "created_at": {
            "type": "string",
            "format": "date-time"
          },
          "updated_at": {
            "type": "string",
            "format": "date-time",
            "description": "Timestamp of last status change"
          },
          "description": {
            "type": "string",
            "description": "Merchant-provided description of the charge"
          },
          "metadata": {
            "type": "object",
            "additionalProperties": {
              "type": "string"
            },
            "description": "Arbitrary key-value metadata attached to this charge by the merchant"
          },
          "customer_id": {
            "type": "string",
            "description": "Identifier of the customer associated with this charge"
          },
          "dispute_id": {
            "type": "string",
            "format": "uuid",
            "description": "ID of the dispute if this charge has been disputed"
          },
          "refunded_at": {
            "type": "string",
            "format": "date-time",
            "description": "Timestamp when the charge was fully refunded, if applicable"
          },
          "failure_reason": {
            "type": "string",
            "description": "Machine-readable failure reason code (e.g. insufficient_funds, expired_card)"
          },
          "failure_message": {
            "type": "string",
            "description": "Human-readable failure message for display to the merchant"
          }
        },
        "required": [
          "id",
          "merchant_id",
          "amount",
          "currency",
          "channel",
          "status",
          "created_at"
        ]
      },
      "GatewayPayout": {
        "type": "object",
        "properties": {
          "id": {
            "type": "string",
            "format": "uuid"
          },
          "merchant_id": {
            "type": "string",
            "format": "uuid"
          },
          "amount": {
            "type": "string",
            "example": "10000",
            "pattern": "^[0-9]{1,15}$",
            "description": "Represented as a string integer in the currency's minor unit (XAF has no subunits). Must be consistent with the currency field."
          },
          "currency": {
            "type": "string",
            "example": "XAF",
            "enum": [
              "XAF",
              "XOF",
              "USD",
              "EUR",
              "GBP",
              "CNY",
              "NGN",
              "GHS",
              "KES",
              "ZAR"
            ],
            "default": "XAF",
            "description": "ISO 4217 currency code. Default is XAF (Central African CFA Franc)."
          },
          "channel": {
            "type": "string",
            "enum": [
              "mobile_money",
              "bank_transfer",
              "paypal"
            ]
          },
          "status": {
            "type": "string",
            "enum": [
              "pending",
              "processing",
              "completed",
              "failed"
            ]
          },
          "beneficiary_name": {
            "type": "string"
          },
          "beneficiary_phone": {
            "type": "string"
          },
          "tx_ref": {
            "type": "string"
          },
          "created_at": {
            "type": "string",
            "format": "date-time"
          }
        },
        "required": [
          "id",
          "merchant_id",
          "amount",
          "currency",
          "channel",
          "status",
          "created_at"
        ]
      },
      "GatewayRefund": {
        "type": "object",
        "properties": {
          "id": {
            "type": "string",
            "format": "uuid"
          },
          "charge_id": {
            "type": "string",
            "format": "uuid"
          },
          "amount": {
            "type": "string",
            "example": "5000",
            "pattern": "^[0-9]{1,15}$",
            "description": "Represented as a string integer in the currency's minor unit (XAF has no subunits). Must be consistent with the currency field."
          },
          "currency": {
            "type": "string",
            "example": "XAF",
            "enum": [
              "XAF",
              "XOF",
              "USD",
              "EUR",
              "GBP",
              "CNY",
              "NGN",
              "GHS",
              "KES",
              "ZAR"
            ],
            "default": "XAF",
            "description": "ISO 4217 currency code. Default is XAF (Central African CFA Franc)."
          },
          "status": {
            "type": "string",
            "enum": [
              "pending",
              "processing",
              "completed",
              "failed"
            ]
          },
          "provider": {
            "type": "string"
          },
          "reason": {
            "type": "string"
          },
          "created_at": {
            "type": "string",
            "format": "date-time"
          }
        },
        "required": [
          "id",
          "charge_id",
          "amount",
          "currency",
          "status"
        ]
      },
      "GatewayDispute": {
        "type": "object",
        "properties": {
          "id": {
            "type": "string",
            "format": "uuid"
          },
          "charge_id": {
            "type": "string",
            "format": "uuid"
          },
          "amount": {
            "type": "string",
            "example": "5000",
            "pattern": "^[0-9]{1,15}$",
            "description": "Represented as a string integer in the currency's minor unit (XAF has no subunits). Must be consistent with the currency field."
          },
          "currency": {
            "type": "string",
            "example": "XAF",
            "enum": [
              "XAF",
              "XOF",
              "USD",
              "EUR",
              "GBP",
              "CNY",
              "NGN",
              "GHS",
              "KES",
              "ZAR"
            ],
            "default": "XAF",
            "description": "ISO 4217 currency code. Default is XAF (Central African CFA Franc)."
          },
          "status": {
            "type": "string",
            "enum": [
              "open",
              "under_review",
              "won",
              "lost",
              "closed"
            ]
          },
          "reason": {
            "type": "string"
          },
          "evidence_due_by": {
            "type": "string",
            "format": "date-time"
          },
          "provider": {
            "type": "string"
          },
          "created_at": {
            "type": "string",
            "format": "date-time"
          }
        },
        "required": [
          "id",
          "charge_id",
          "amount",
          "currency",
          "status"
        ]
      },
      "GatewaySettlement": {
        "type": "object",
        "properties": {
          "id": {
            "type": "string",
            "format": "uuid"
          },
          "merchant_id": {
            "type": "string",
            "format": "uuid"
          },
          "amount": {
            "type": "string",
            "example": "450000",
            "pattern": "^[0-9]{1,15}$",
            "description": "Represented as a string integer in the currency's minor unit (XAF has no subunits). Must be consistent with the currency field."
          },
          "currency": {
            "type": "string",
            "example": "XAF",
            "enum": [
              "XAF",
              "XOF",
              "USD",
              "EUR",
              "GBP",
              "CNY",
              "NGN",
              "GHS",
              "KES",
              "ZAR"
            ],
            "default": "XAF",
            "description": "ISO 4217 currency code. Default is XAF (Central African CFA Franc)."
          },
          "status": {
            "type": "string",
            "enum": [
              "pending",
              "processing",
              "paid"
            ]
          },
          "period_start": {
            "type": "string",
            "format": "date"
          },
          "period_end": {
            "type": "string",
            "format": "date"
          },
          "charges_count": {
            "type": "integer"
          },
          "fees_total": {
            "type": "number"
          },
          "net_amount": {
            "type": "string",
            "pattern": "^-?[0-9]{1,15}$",
            "format": "monetary-minor-unit",
            "example": "0",
            "x-coercion": "numeric→string in v4.29.0 per FAPI 1.0 Adv §5.2.2 / RFC 8259 precision"
          },
          "settled_at": {
            "type": "string",
            "format": "date-time"
          }
        },
        "required": [
          "id",
          "merchant_id",
          "amount",
          "currency",
          "status"
        ]
      },
      "GatewayBeneficiary": {
        "type": "object",
        "properties": {
          "id": {
            "type": "string",
            "format": "uuid"
          },
          "merchant_id": {
            "type": "string",
            "format": "uuid"
          },
          "name": {
            "type": "string"
          },
          "channel": {
            "type": "string",
            "enum": [
              "mobile_money",
              "bank_transfer"
            ]
          },
          "phone": {
            "type": "string"
          },
          "bank_account": {
            "type": "string"
          },
          "bank_code": {
            "type": "string"
          },
          "created_at": {
            "type": "string",
            "format": "date-time"
          }
        },
        "required": [
          "id",
          "merchant_id",
          "name",
          "channel"
        ]
      },
      "GatewayFeeEstimate": {
        "type": "object",
        "properties": {
          "amount": {
            "type": "string",
            "example": "5000",
            "pattern": "^[0-9]{1,15}$",
            "description": "Represented as a string integer in the currency's minor unit (XAF has no subunits). Must be consistent with the currency field."
          },
          "currency": {
            "type": "string",
            "example": "XAF",
            "enum": [
              "XAF",
              "XOF",
              "USD",
              "EUR",
              "GBP",
              "CNY",
              "NGN",
              "GHS",
              "KES",
              "ZAR"
            ],
            "default": "XAF",
            "description": "ISO 4217 currency code. Default is XAF (Central African CFA Franc)."
          },
          "channel": {
            "type": "string"
          },
          "fee_amount": {
            "type": "string",
            "example": "200",
            "pattern": "^-?[0-9]{1,15}$",
            "format": "monetary-minor-unit",
            "x-coercion": "numeric→string in v4.29.0 per FAPI 1.0 Adv §5.2.2 / RFC 8259 precision"
          },
          "net_amount": {
            "type": "string",
            "example": "4800",
            "pattern": "^-?[0-9]{1,15}$",
            "format": "monetary-minor-unit",
            "x-coercion": "numeric→string in v4.29.0 per FAPI 1.0 Adv §5.2.2 / RFC 8259 precision"
          },
          "fee_percentage": {
            "type": "string",
            "example": "3%"
          },
          "fixed_fee": {
            "type": "string",
            "example": "50",
            "pattern": "^-?[0-9]{1,15}$",
            "format": "monetary-minor-unit",
            "x-coercion": "numeric→string in v4.29.0 per FAPI 1.0 Adv §5.2.2 / RFC 8259 precision"
          }
        },
        "required": [
          "amount",
          "currency",
          "channel",
          "fee_amount",
          "net_amount"
        ]
      },
      "GatewayVirtualAccount": {
        "type": "object",
        "properties": {
          "id": {
            "type": "string",
            "format": "uuid"
          },
          "merchant_id": {
            "type": "string",
            "format": "uuid"
          },
          "account_number": {
            "type": "string",
            "example": "37001 23456 78901234567 89",
            "description": "Bank account or virtual-account number. For CEMAC banks this is a 23-digit RIB (Relevé d'Identité Bancaire) per BEAC Reg. 02/03 §7."
          },
          "bank_name": {
            "type": "string",
            "example": "Afriland First Bank"
          },
          "currency": {
            "type": "string",
            "example": "XAF",
            "enum": [
              "XAF",
              "XOF",
              "USD",
              "EUR",
              "GBP",
              "CNY",
              "NGN",
              "GHS",
              "KES",
              "ZAR"
            ],
            "default": "XAF",
            "description": "ISO 4217 currency code. Default is XAF (Central African CFA Franc)."
          },
          "status": {
            "type": "string",
            "enum": [
              "active",
              "closed"
            ]
          },
          "email": {
            "type": "string"
          },
          "expiry": {
            "type": "string",
            "format": "date-time"
          },
          "created_at": {
            "type": "string",
            "format": "date-time"
          },
          "bank_country": {
            "type": "string",
            "enum": [
              "CM",
              "GA",
              "CG",
              "TD",
              "CF",
              "GQ",
              "NG",
              "GH",
              "KE",
              "ZA"
            ],
            "default": "CM",
            "description": "ISO 3166-1 alpha-2 country code of the issuing bank. CEMAC defaults to CM (Cameroon).",
            "example": "CM"
          }
        },
        "required": [
          "id",
          "merchant_id",
          "account_number",
          "bank_name",
          "currency"
        ]
      },
      "GatewayMerchantWallet": {
        "type": "object",
        "properties": {
          "id": {
            "type": "string",
            "format": "uuid"
          },
          "merchant_id": {
            "type": "string",
            "format": "uuid"
          },
          "currency": {
            "type": "string",
            "example": "XAF",
            "enum": [
              "XAF",
              "XOF",
              "USD",
              "EUR",
              "GBP",
              "CNY",
              "NGN",
              "GHS",
              "KES",
              "ZAR"
            ],
            "default": "XAF",
            "description": "ISO 4217 currency code. Default is XAF (Central African CFA Franc)."
          },
          "available_balance": {
            "type": "string",
            "example": "500000",
            "pattern": "^[0-9]{1,15}$",
            "description": "Represented as a string integer in the currency's minor unit (XAF has no subunits). Must be consistent with the currency field."
          },
          "pending_balance": {
            "type": "number",
            "example": 25000
          },
          "ledger_balance": {
            "type": "number",
            "example": 525000
          },
          "updated_at": {
            "type": "string",
            "format": "date-time"
          }
        },
        "required": [
          "id",
          "merchant_id",
          "currency",
          "available_balance"
        ]
      },
      "GatewayBankVerification": {
        "type": "object",
        "properties": {
          "account_name": {
            "type": "string",
            "example": "John Doe"
          },
          "account_number": {
            "type": "string",
            "example": "1234567890"
          }
        },
        "required": [
          "account_name",
          "account_number"
        ]
      },
      "GatewayBvnResolution": {
        "type": "object",
        "properties": {
          "bvn": {
            "type": "string"
          },
          "first_name": {
            "type": "string"
          },
          "last_name": {
            "type": "string"
          },
          "middle_name": {
            "type": "string"
          },
          "date_of_birth": {
            "type": "string"
          },
          "phone_number": {
            "type": "string"
          }
        },
        "required": [
          "bvn",
          "first_name",
          "last_name"
        ]
      },
      "GatewayPaymentLink": {
        "type": "object",
        "properties": {
          "id": {
            "type": "string",
            "format": "uuid"
          },
          "merchant_id": {
            "type": "string",
            "format": "uuid"
          },
          "name": {
            "type": "string",
            "example": "Product Payment"
          },
          "slug": {
            "type": "string",
            "example": "product-payment-abc123"
          },
          "amount": {
            "type": "string",
            "example": "5000",
            "pattern": "^[0-9]{1,15}$",
            "description": "Represented as a string integer in the currency's minor unit (XAF has no subunits). Must be consistent with the currency field."
          },
          "currency": {
            "type": "string",
            "example": "XAF",
            "enum": [
              "XAF",
              "XOF",
              "USD",
              "EUR",
              "GBP",
              "CNY",
              "NGN",
              "GHS",
              "KES",
              "ZAR"
            ],
            "default": "XAF",
            "description": "ISO 4217 currency code. Default is XAF (Central African CFA Franc)."
          },
          "status": {
            "type": "string",
            "enum": [
              "active",
              "inactive",
              "expired"
            ]
          },
          "redirect_url": {
            "type": "string"
          },
          "max_uses": {
            "type": "integer"
          },
          "use_count": {
            "type": "integer"
          },
          "expires_at": {
            "type": "string",
            "format": "date-time"
          },
          "created_at": {
            "type": "string",
            "format": "date-time"
          }
        },
        "required": [
          "id",
          "merchant_id",
          "name",
          "slug",
          "amount",
          "currency",
          "status"
        ]
      },
      "GatewayPaymentPlan": {
        "type": "object",
        "properties": {
          "id": {
            "type": "string",
            "format": "uuid"
          },
          "merchant_id": {
            "type": "string",
            "format": "uuid"
          },
          "name": {
            "type": "string",
            "example": "Monthly Pro Plan"
          },
          "amount": {
            "type": "string",
            "example": "10000",
            "pattern": "^[0-9]{1,15}$",
            "description": "Represented as a string integer in the currency's minor unit (XAF has no subunits). Must be consistent with the currency field."
          },
          "currency": {
            "type": "string",
            "example": "XAF",
            "enum": [
              "XAF",
              "XOF",
              "USD",
              "EUR",
              "GBP",
              "CNY",
              "NGN",
              "GHS",
              "KES",
              "ZAR"
            ],
            "default": "XAF",
            "description": "ISO 4217 currency code. Default is XAF (Central African CFA Franc)."
          },
          "interval": {
            "type": "string",
            "enum": [
              "daily",
              "weekly",
              "monthly",
              "quarterly",
              "yearly"
            ]
          },
          "duration": {
            "type": "integer",
            "description": "Number of billing cycles (0 = unlimited)"
          },
          "status": {
            "type": "string",
            "enum": [
              "active",
              "cancelled",
              "completed"
            ]
          },
          "created_at": {
            "type": "string",
            "format": "date-time"
          }
        },
        "required": [
          "id",
          "merchant_id",
          "name",
          "amount",
          "currency"
        ]
      },
      "GatewaySubscription": {
        "type": "object",
        "properties": {
          "id": {
            "type": "string",
            "format": "uuid"
          },
          "plan_id": {
            "type": "string",
            "format": "uuid"
          },
          "customer_email": {
            "type": "string"
          },
          "customer_phone": {
            "type": "string"
          },
          "status": {
            "type": "string",
            "enum": [
              "active",
              "paused",
              "cancelled",
              "completed",
              "past_due"
            ]
          },
          "current_period_start": {
            "type": "string",
            "format": "date-time"
          },
          "current_period_end": {
            "type": "string",
            "format": "date-time"
          },
          "next_charge_date": {
            "type": "string",
            "format": "date-time"
          },
          "charges_count": {
            "type": "integer"
          },
          "created_at": {
            "type": "string",
            "format": "date-time"
          },
          "trial_start": {
            "type": "string",
            "format": "date-time",
            "nullable": true,
            "description": "UTC datetime when the trial period started. Null if no trial was applied to this subscription.",
            "example": "2025-03-01T00:00:00Z"
          },
          "trial_end": {
            "type": "string",
            "format": "date-time",
            "nullable": true,
            "description": "UTC datetime when the trial period ends or ended. After this datetime, regular billing resumes. Null if no trial was applied.",
            "example": "2025-03-15T00:00:00Z"
          },
          "cancel_at_period_end": {
            "type": "boolean",
            "default": false,
            "description": "When true, the subscription is scheduled to cancel at the end of the current billing period (current_period_end) rather than immediately. The status remains 'active' until then.",
            "example": false
          },
          "cancelled_at": {
            "type": "string",
            "format": "date-time",
            "nullable": true,
            "description": "UTC datetime when the subscription was cancelled (either immediately or when a scheduled end-of-period cancellation took effect). Null if subscription is still active.",
            "example": "2025-04-01T00:00:00Z"
          },
          "billing_cycle_anchor": {
            "type": "string",
            "format": "date-time",
            "nullable": true,
            "description": "UTC datetime that defines the billing cycle. Future billing dates are calculated relative to this anchor. Useful for aligning subscription billing to a fixed day of the month.",
            "example": "2025-01-01T00:00:00Z"
          },
          "metadata": {
            "type": "object",
            "additionalProperties": {
              "type": "string"
            },
            "maxProperties": 20,
            "description": "Arbitrary key-value metadata attached to this subscription. Keys and values must be strings. Maximum 20 pairs.",
            "example": {
              "customer_ref": "CUST-001",
              "plan_tier": "professional"
            }
          }
        },
        "required": [
          "id",
          "plan_id",
          "status",
          "current_period_start",
          "current_period_end",
          "created_at"
        ]
      },
      "GatewaySubaccount": {
        "type": "object",
        "properties": {
          "id": {
            "type": "string",
            "format": "uuid"
          },
          "merchant_id": {
            "type": "string",
            "format": "uuid"
          },
          "business_name": {
            "type": "string"
          },
          "settlement_bank": {
            "type": "string"
          },
          "account_number": {
            "type": "string"
          },
          "split_type": {
            "type": "string",
            "enum": [
              "percentage",
              "flat"
            ]
          },
          "split_value": {
            "type": "number"
          },
          "country": {
            "type": "string",
            "example": "CM"
          },
          "created_at": {
            "type": "string",
            "format": "date-time"
          }
        },
        "required": [
          "id",
          "merchant_id",
          "business_name",
          "account_number"
        ]
      },
      "GatewayCustomer": {
        "type": "object",
        "properties": {
          "id": {
            "type": "string",
            "format": "uuid"
          },
          "merchant_id": {
            "type": "string",
            "format": "uuid"
          },
          "email": {
            "type": "string"
          },
          "phone": {
            "type": "string"
          },
          "name": {
            "type": "string"
          },
          "metadata": {
            "type": "object"
          },
          "created_at": {
            "type": "string",
            "format": "date-time"
          }
        },
        "required": [
          "id",
          "merchant_id",
          "email"
        ]
      },
      "GatewayCustomerToken": {
        "type": "object",
        "properties": {
          "id": {
            "type": "string",
            "format": "uuid"
          },
          "customer_id": {
            "type": "string",
            "format": "uuid"
          },
          "channel": {
            "type": "string",
            "enum": [
              "mobile_money",
              "card"
            ]
          },
          "token_ref": {
            "type": "string"
          },
          "last4": {
            "type": "string",
            "example": "1234"
          },
          "provider": {
            "type": "string"
          },
          "is_active": {
            "type": "boolean"
          },
          "created_at": {
            "type": "string",
            "format": "date-time"
          }
        },
        "required": [
          "id",
          "customer_id",
          "channel",
          "token_ref"
        ]
      },
      "GatewayChargeEvent": {
        "type": "object",
        "properties": {
          "id": {
            "type": "string",
            "format": "uuid"
          },
          "charge_id": {
            "type": "string",
            "format": "uuid"
          },
          "event_type": {
            "type": "string",
            "enum": [
              "charge.created",
              "charge.processing",
              "charge.successful",
              "charge.failed",
              "charge.cancelled",
              "charge.voided",
              "charge.captured",
              "charge.refunded"
            ],
            "example": "charge.created"
          },
          "data": {
            "type": "object"
          },
          "created_at": {
            "type": "string",
            "format": "date-time"
          }
        },
        "required": [
          "id",
          "charge_id",
          "event_type",
          "created_at"
        ]
      },
      "GatewayReconciliationRun": {
        "type": "object",
        "properties": {
          "id": {
            "type": "string",
            "format": "uuid"
          },
          "merchant_id": {
            "type": "string",
            "format": "uuid"
          },
          "status": {
            "type": "string",
            "enum": [
              "pending",
              "running",
              "completed",
              "failed"
            ]
          },
          "matched_count": {
            "type": "integer"
          },
          "mismatched_count": {
            "type": "integer"
          },
          "period_start": {
            "type": "string",
            "format": "date"
          },
          "period_end": {
            "type": "string",
            "format": "date"
          },
          "created_at": {
            "type": "string",
            "format": "date-time"
          }
        },
        "required": [
          "id",
          "merchant_id",
          "status"
        ]
      },
      "GatewayMerchant": {
        "type": "object",
        "properties": {
          "id": {
            "type": "string",
            "format": "uuid"
          },
          "user_id": {
            "type": "string",
            "format": "uuid"
          },
          "business_name": {
            "type": "string"
          },
          "business_type": {
            "type": "string"
          },
          "contact_email": {
            "type": "string"
          },
          "contact_phone": {
            "type": "string"
          },
          "country": {
            "type": "string",
            "example": "CM"
          },
          "status": {
            "type": "string",
            "enum": [
              "pending",
              "active",
              "suspended",
              "deactivated"
            ]
          },
          "kyb_status": {
            "type": "string",
            "enum": [
              "not_submitted",
              "pending",
              "approved",
              "rejected"
            ]
          },
          "logo_url": {
            "type": "string"
          },
          "created_at": {
            "type": "string",
            "format": "date-time"
          }
        },
        "required": [
          "id",
          "business_name",
          "business_type",
          "contact_email"
        ]
      },
      "WooCommerceMerchant": {
        "type": "object",
        "properties": {
          "id": {
            "type": "string",
            "format": "uuid"
          },
          "store_name": {
            "type": "string"
          },
          "store_url": {
            "type": "string",
            "format": "uri"
          },
          "admin_email": {
            "type": "string",
            "format": "email"
          },
          "api_key": {
            "type": "string",
            "description": "Generated API key for the merchant"
          },
          "client_secret": {
            "type": "string",
            "description": "Generated client secret (shown once)"
          },
          "webhook_secret": {
            "type": "string",
            "description": "Webhook signing secret"
          },
          "status": {
            "type": "string",
            "enum": [
              "active",
              "inactive",
              "suspended"
            ]
          },
          "plugin_version": {
            "type": "string"
          },
          "created_at": {
            "type": "string",
            "format": "date-time"
          }
        },
        "required": [
          "id",
          "store_name",
          "store_url",
          "admin_email"
        ]
      },
      "WooCommerceTransaction": {
        "type": "object",
        "properties": {
          "id": {
            "type": "string",
            "format": "uuid"
          },
          "transaction_ref": {
            "type": "string"
          },
          "woocommerce_order_id": {
            "type": "integer"
          },
          "amount": {
            "type": "string",
            "pattern": "^[0-9]{1,15}$",
            "description": "Represented as a string integer in the currency's minor unit (XAF has no subunits). Must be consistent with the currency field."
          },
          "currency": {
            "type": "string",
            "enum": [
              "XAF",
              "XOF",
              "USD",
              "EUR",
              "GBP",
              "CNY",
              "NGN",
              "GHS",
              "KES",
              "ZAR"
            ],
            "default": "XAF",
            "description": "ISO 4217 currency code. Default is XAF (Central African CFA Franc)."
          },
          "status": {
            "type": "string",
            "enum": [
              "pending",
              "completed",
              "failed",
              "refunded"
            ]
          },
          "payment_method": {
            "type": "string"
          },
          "customer_email": {
            "type": "string"
          },
          "fee_amount": {
            "type": "string",
            "pattern": "^-?[0-9]{1,15}$",
            "format": "monetary-minor-unit",
            "example": "0",
            "x-coercion": "numeric→string in v4.29.0 per FAPI 1.0 Adv §5.2.2 / RFC 8259 precision"
          },
          "net_amount": {
            "type": "string",
            "pattern": "^-?[0-9]{1,15}$",
            "format": "monetary-minor-unit",
            "example": "0",
            "x-coercion": "numeric→string in v4.29.0 per FAPI 1.0 Adv §5.2.2 / RFC 8259 precision"
          },
          "created_at": {
            "type": "string",
            "format": "date-time"
          },
          "completed_at": {
            "type": "string",
            "format": "date-time"
          }
        },
        "required": [
          "id",
          "transaction_ref",
          "amount",
          "currency",
          "status"
        ]
      },
      "PayByBankIntent": {
        "type": "object",
        "properties": {
          "id": {
            "type": "string",
            "format": "uuid"
          },
          "merchant_id": {
            "type": "string",
            "format": "uuid"
          },
          "consent_id": {
            "type": "string"
          },
          "amount": {
            "type": "string",
            "example": "50000",
            "pattern": "^[0-9]{1,15}$",
            "description": "Represented as a string integer in the currency's minor unit (XAF has no subunits). Must be consistent with the currency field."
          },
          "currency": {
            "type": "string",
            "example": "XAF",
            "enum": [
              "XAF",
              "XOF",
              "USD",
              "EUR",
              "GBP",
              "CNY",
              "NGN",
              "GHS",
              "KES",
              "ZAR"
            ],
            "default": "XAF",
            "description": "ISO 4217 currency code. Default is XAF (Central African CFA Franc)."
          },
          "redirect_uri": {
            "type": "string",
            "format": "uri"
          },
          "state": {
            "type": "string"
          },
          "status": {
            "type": "string",
            "enum": [
              "awaiting_auth",
              "authorized",
              "submitted",
              "processing",
              "completed",
              "failed",
              "expired",
              "rejected"
            ]
          },
          "merchant_name": {
            "type": "string"
          },
          "merchant_logo_url": {
            "type": "string",
            "format": "uri",
            "nullable": true
          },
          "description": {
            "type": "string",
            "nullable": true
          },
          "authorization_url": {
            "type": "string",
            "format": "uri"
          },
          "expires_at": {
            "type": "string",
            "format": "date-time"
          },
          "created_at": {
            "type": "string",
            "format": "date-time"
          },
          "updated_at": {
            "type": "string",
            "format": "date-time"
          }
        },
        "required": [
          "id",
          "merchant_id",
          "amount",
          "currency",
          "status",
          "redirect_uri"
        ]
      },
      "CreatePayByBankIntentRequest": {
        "type": "object",
        "required": [
          "merchant_id",
          "amount",
          "redirect_uri",
          "state"
        ],
        "properties": {
          "merchant_id": {
            "type": "string",
            "format": "uuid"
          },
          "amount": {
            "type": "string",
            "example": "50000",
            "pattern": "^[0-9]{1,15}$",
            "description": "Represented as a string integer in the currency's minor unit (XAF has no subunits). Must be consistent with the currency field."
          },
          "currency": {
            "type": "string",
            "default": "XAF",
            "enum": [
              "XAF",
              "XOF",
              "USD",
              "EUR",
              "GBP",
              "CNY",
              "NGN",
              "GHS",
              "KES",
              "ZAR"
            ],
            "description": "ISO 4217 currency code. Default is XAF (Central African CFA Franc)."
          },
          "redirect_uri": {
            "type": "string",
            "format": "uri"
          },
          "state": {
            "type": "string",
            "description": "Opaque state for CSRF protection"
          },
          "description": {
            "type": "string"
          },
          "creditor_account": {
            "type": "string"
          },
          "creditor_name": {
            "type": "string"
          },
          "customer_email": {
            "type": "string",
            "format": "email"
          }
        }
      },
      "StandardResponse": {
        "type": "object",
        "description": "Unified single-resource response wrapper",
        "required": [
          "data",
          "meta"
        ],
        "properties": {
          "data": {
            "type": "object",
            "description": "The primary response payload"
          },
          "meta": {
            "$ref": "#/components/schemas/ResponseMeta"
          }
        }
      },
      "PaginatedResponse": {
        "type": "object",
        "description": "Unified paginated list response wrapper",
        "required": [
          "data",
          "pagination",
          "meta"
        ],
        "properties": {
          "data": {
            "type": "array",
            "items": {},
            "description": "Array of resource objects"
          },
          "pagination": {
            "$ref": "#/components/schemas/Pagination"
          },
          "meta": {
            "$ref": "#/components/schemas/ResponseMeta"
          }
        }
      },
      "ResponseMeta": {
        "type": "object",
        "description": "Standard response metadata",
        "required": [
          "request_id",
          "timestamp"
        ],
        "properties": {
          "request_id": {
            "type": "string",
            "format": "uuid",
            "description": "Unique request identifier (echoes x-fapi-interaction-id)",
            "example": "550e8400-e29b-41d4-a716-446655440000"
          },
          "timestamp": {
            "type": "string",
            "format": "date-time",
            "description": "UTC timestamp of the response",
            "example": "2025-03-27T12:00:00Z"
          },
          "api_version": {
            "type": "string",
            "description": "API version that served this response",
            "example": "4.3.0"
          }
        }
      },
      "ProblemDetails": {
        "type": "object",
        "description": "RFC 7807 Problem Details for HTTP APIs. Used for structured error responses.",
        "required": [
          "type",
          "title",
          "status"
        ],
        "properties": {
          "type": {
            "type": "string",
            "format": "uri",
            "description": "URI reference identifying the problem type",
            "example": "https://api.kangopenbanking.com/v1/errors/validation-error"
          },
          "title": {
            "type": "string",
            "description": "Short human-readable summary",
            "example": "Validation Error"
          },
          "status": {
            "type": "integer",
            "description": "HTTP status code",
            "example": 400
          },
          "detail": {
            "type": "string",
            "description": "Human-readable explanation specific to this occurrence",
            "example": "The amount field must be a positive integer string"
          },
          "instance": {
            "type": "string",
            "format": "uri",
            "description": "URI identifying the specific occurrence",
            "example": "/v1/gateway/charges/abc-123"
          },
          "errors": {
            "type": "array",
            "description": "Detailed field-level validation errors",
            "items": {
              "type": "object",
              "properties": {
                "field": {
                  "type": "string",
                  "example": "amount"
                },
                "message": {
                  "type": "string",
                  "example": "must match pattern ^[0-9]{1,15}$"
                },
                "code": {
                  "type": "string",
                  "example": "PATTERN_MISMATCH"
                }
              }
            }
          },
          "error_id": {
            "type": "string",
            "description": "Kang-specific trace correlation identifier. Reference this ID when contacting support. Matches the error_id field in the standard Error schema for cross-format correlation.",
            "example": "err_a1b2c3d4e5f6"
          },
          "timestamp": {
            "type": "string",
            "format": "date-time",
            "description": "UTC ISO 8601 datetime when this error occurred. Useful for correlating with server logs.",
            "example": "2025-03-27T14:32:00Z"
          }
        }
      },
      "WebhookEventPayload": {
        "type": "object",
        "description": "Base structure for all Kang webhook event payloads. The 'data' field contains the event-specific resource object.",
        "required": [
          "id",
          "event",
          "created_at",
          "api_version",
          "data"
        ],
        "properties": {
          "id": {
            "type": "string",
            "format": "uuid",
            "description": "Unique webhook delivery ID for deduplication",
            "example": "evt_a1b2c3d4-e5f6-7890-abcd-ef1234567890"
          },
          "event": {
            "type": "string",
            "description": "Event type name from the subscribed events catalogue",
            "example": "charge.created",
            "enum": [
              "charge.created",
              "charge.successful",
              "charge.failed",
              "charge.pending",
              "charge.refunded",
              "charge.reversed",
              "charge.expired",
              "charge.cancelled",
              "payout.created",
              "payout.completed",
              "payout.failed",
              "payout.reversed",
              "payout.pending",
              "refund.created",
              "refund.completed",
              "refund.failed",
              "dispute.created",
              "dispute.updated",
              "dispute.won",
              "dispute.lost",
              "settlement.created",
              "settlement.paid",
              "settlement.failed",
              "subscription.created",
              "subscription.activated",
              "subscription.renewed",
              "subscription.cancelled",
              "subscription.expired",
              "subscription.payment_failed",
              "merchant.created",
              "merchant.updated",
              "merchant.verified",
              "merchant.suspended",
              "wallet.credited",
              "wallet.debited",
              "wallet.frozen",
              "escrow.created",
              "escrow.funded",
              "escrow.released",
              "escrow.disputed",
              "escrow.refunded",
              "consent.authorized",
              "consent.revoked",
              "consent.expired",
              "payment_link.created",
              "payment_link.paid",
              "payment_link.expired",
              "pay_by_bank.authorized",
              "pay_by_bank.submitted",
              "pay_by_bank.completed",
              "pay_by_bank.failed",
              "onboarding_application.approved",
              "onboarding_application.rejected",
              "merchant_kyb.verified",
              "merchant_kyb.failed",
              "credit_score.updated",
              "loan_application.approved",
              "loan_application.rejected",
              "loan_application.pending_documents"
            ]
          },
          "created_at": {
            "type": "string",
            "format": "date-time",
            "description": "UTC datetime when the event was generated",
            "example": "2025-03-27T14:32:00Z"
          },
          "api_version": {
            "type": "string",
            "description": "API version that generated this event",
            "example": "4.6.0"
          },
          "livemode": {
            "type": "boolean",
            "description": "true for production events, false for sandbox/test events",
            "example": true
          },
          "data": {
            "type": "object",
            "description": "The primary event resource. Schema varies by event type.",
            "additionalProperties": true
          },
          "metadata": {
            "type": "object",
            "additionalProperties": {
              "type": "string"
            },
            "description": "Merchant-provided metadata attached to the originating resource"
          }
        }
      },
      "RateLimitError": {
        "type": "object",
        "description": "Error response for HTTP 429.",
        "required": [
          "type",
          "title",
          "status",
          "detail",
          "error_code",
          "error_id",
          "timestamp",
          "retry_after",
          "limit"
        ],
        "properties": {
          "type": {
            "type": "string",
            "format": "uri",
            "example": "https://kangopenbanking.com/errors/rate-limit-exceeded"
          },
          "title": {
            "type": "string",
            "example": "Too Many Requests"
          },
          "status": {
            "type": "integer",
            "example": 429
          },
          "detail": {
            "type": "string",
            "example": "Rate limit of 300 requests per minute exceeded for client_id tpp_abc123."
          },
          "error_code": {
            "type": "string",
            "example": "AUTH_005"
          },
          "error_id": {
            "type": "string",
            "example": "err_ratelimit_9f3a2b"
          },
          "timestamp": {
            "type": "string",
            "format": "date-time"
          },
          "retry_after": {
            "type": "integer",
            "description": "Seconds until the rate limit window resets.",
            "example": 37
          },
          "limit": {
            "type": "integer",
            "description": "The rate limit ceiling for this endpoint.",
            "example": 300
          }
        }
      },
      "TransactionOBIE": {
        "type": "object",
        "description": "OBIE Read/Write Data API v3.1-compatible Transaction representation. Use this schema variant when consuming or producing OBIE-aligned payloads. The primary `Transaction` schema retains its snake_case fields for the canonical Kang OB representation; PascalCase aliases on Transaction are deprecated and will be removed in v5.0.0.",
        "properties": {
          "AccountId": {
            "type": "string",
            "description": "OBIE alias for the account identifier. Maps to account_id in parent resource context."
          },
          "TransactionId": {
            "type": "string",
            "description": "OBIE alias for transaction_id."
          },
          "Amount": {
            "type": "string",
            "pattern": "^[0-9]{1,15}$",
            "description": "OBIE alias for amount."
          },
          "Currency": {
            "type": "string",
            "enum": [
              "XAF",
              "XOF",
              "USD",
              "EUR",
              "GBP",
              "CNY",
              "NGN",
              "GHS",
              "KES",
              "ZAR"
            ],
            "description": "OBIE alias for currency."
          },
          "CreditDebitIndicator": {
            "type": "string",
            "enum": [
              "Credit",
              "Debit"
            ],
            "description": "OBIE alias for type. Maps credit/debit to transaction direction."
          },
          "BookingDateTime": {
            "type": "string",
            "format": "date-time",
            "description": "OBIE alias for booking_date."
          },
          "ValueDateTime": {
            "type": "string",
            "format": "date-time",
            "description": "OBIE alias for value_date."
          },
          "TransactionInformation": {
            "type": "string",
            "maxLength": 500,
            "description": "OBIE OBTransaction6 alias for the description field. Narrative text conveying information from the originator to the beneficiary about the payment transaction.",
            "example": "Payment for Invoice INV-2025-001 — Professional Services"
          },
          "Status": {
            "type": "string",
            "enum": [
              "Booked",
              "Pending",
              "Rejected"
            ],
            "description": "OBIE OBTransaction6 transaction status. Booked = settled, Pending = authorised but not yet settled, Rejected = declined or failed."
          }
        },
        "required": [
          "AccountId",
          "TransactionId",
          "Amount",
          "CreditDebitIndicator",
          "BookingDateTime",
          "Status"
        ],
        "x-obie-version": "3.1.10",
        "x-obie-spec": "https://standards.openbanking.org.uk/api-specifications/"
      },
      "WebhookEvent": {
        "type": "object",
        "required": [
          "id",
          "type",
          "created_at",
          "data"
        ],
        "properties": {
          "id": {
            "type": "string"
          },
          "type": {
            "type": "string"
          },
          "created_at": {
            "type": "string",
            "format": "date-time"
          },
          "data": {
            "type": "object"
          }
        }
      },
      "BudgetCategory": {
        "type": "object",
        "required": [
          "id",
          "name",
          "icon",
          "colour",
          "limit",
          "spent"
        ],
        "properties": {
          "id": {
            "type": "string",
            "example": "cat_food"
          },
          "name": {
            "type": "string",
            "example": "Food & Market"
          },
          "icon": {
            "type": "string",
            "example": "ShoppingCart"
          },
          "colour": {
            "type": "string",
            "pattern": "^#[0-9A-Fa-f]{6}$",
            "example": "#10D9A0"
          },
          "limit": {
            "type": "integer",
            "format": "int64",
            "minimum": 0,
            "description": "Amount in XAF (zero-decimal)."
          },
          "spent": {
            "type": "integer",
            "format": "int64",
            "minimum": 0,
            "description": "Amount in XAF (zero-decimal)."
          },
          "remaining": {
            "type": "integer",
            "format": "int64",
            "minimum": 0,
            "description": "Amount in XAF (zero-decimal)."
          },
          "percentage_used": {
            "type": "number",
            "format": "float",
            "minimum": 0
          },
          "transaction_count": {
            "type": "integer",
            "minimum": 0
          },
          "top_merchant": {
            "type": [
              "string",
              "null"
            ]
          }
        },
        "description": "A spending category used to classify transactions for budgeting and analytics."
      },
      "Budget": {
        "type": "object",
        "required": [
          "id",
          "consumer_id",
          "name",
          "period",
          "start_date",
          "end_date",
          "total_limit",
          "currency",
          "status",
          "created_at"
        ],
        "properties": {
          "id": {
            "type": "string",
            "example": "bgt_01HXYZ"
          },
          "consumer_id": {
            "type": "string",
            "format": "uuid"
          },
          "name": {
            "type": "string",
            "example": "May 2026 Budget"
          },
          "period": {
            "type": "string",
            "enum": [
              "monthly",
              "weekly",
              "custom"
            ]
          },
          "start_date": {
            "type": "string",
            "format": "date"
          },
          "end_date": {
            "type": "string",
            "format": "date"
          },
          "total_limit": {
            "type": "integer",
            "format": "int64",
            "minimum": 0,
            "description": "Amount in XAF (zero-decimal)."
          },
          "categories": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/BudgetCategory"
            }
          },
          "currency": {
            "type": "string",
            "enum": [
              "XAF"
            ],
            "default": "XAF"
          },
          "status": {
            "type": "string",
            "enum": [
              "active",
              "paused",
              "archived"
            ]
          },
          "created_at": {
            "type": "string",
            "format": "date-time"
          },
          "updated_at": {
            "type": "string",
            "format": "date-time"
          }
        },
        "description": "A budget for a category and period, holding the allocated amount and the spend accumulated against it."
      },
      "BudgetCreateRequest": {
        "type": "object",
        "required": [
          "name",
          "period",
          "start_date",
          "end_date",
          "total_limit"
        ],
        "properties": {
          "name": {
            "type": "string",
            "maxLength": 80
          },
          "period": {
            "type": "string",
            "enum": [
              "monthly",
              "weekly",
              "custom"
            ]
          },
          "start_date": {
            "type": "string",
            "format": "date"
          },
          "end_date": {
            "type": "string",
            "format": "date"
          },
          "total_limit": {
            "type": "integer",
            "format": "int64",
            "minimum": 0,
            "description": "Amount in XAF (zero-decimal)."
          },
          "categories": {
            "type": "array",
            "items": {
              "type": "object",
              "required": [
                "id",
                "limit"
              ],
              "properties": {
                "id": {
                  "type": "string"
                },
                "limit": {
                  "type": "integer",
                  "format": "int64",
                  "minimum": 0,
                  "description": "Amount in XAF (zero-decimal)."
                }
              }
            }
          }
        },
        "description": "Request payload used to create a budget for a category and period."
      },
      "BudgetSummary": {
        "type": "object",
        "required": [
          "budget_id",
          "period_start",
          "period_end",
          "total_limit",
          "total_spent",
          "total_remaining",
          "percentage_used",
          "currency"
        ],
        "properties": {
          "budget_id": {
            "type": "string"
          },
          "period_start": {
            "type": "string",
            "format": "date"
          },
          "period_end": {
            "type": "string",
            "format": "date"
          },
          "total_limit": {
            "type": "integer",
            "format": "int64",
            "minimum": 0,
            "description": "Amount in XAF (zero-decimal)."
          },
          "total_spent": {
            "type": "integer",
            "format": "int64",
            "minimum": 0,
            "description": "Amount in XAF (zero-decimal)."
          },
          "total_remaining": {
            "type": "integer",
            "format": "int64",
            "minimum": 0,
            "description": "Amount in XAF (zero-decimal)."
          },
          "percentage_used": {
            "type": "number",
            "format": "float"
          },
          "days_remaining": {
            "type": "integer"
          },
          "projected_overspend": {
            "type": "boolean"
          },
          "projected_end_balance": {
            "type": "integer",
            "format": "int64",
            "minimum": 0,
            "description": "Amount in XAF (zero-decimal)."
          },
          "categories": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/BudgetCategory"
            }
          },
          "currency": {
            "type": "string",
            "enum": [
              "XAF"
            ]
          }
        },
        "description": "An aggregated view of a budget: allocation, spend to date, remaining amount and utilisation for the current period."
      },
      "CategoryCreateRequest": {
        "type": "object",
        "required": [
          "name",
          "icon",
          "colour",
          "limit"
        ],
        "properties": {
          "name": {
            "type": "string"
          },
          "icon": {
            "type": "string"
          },
          "colour": {
            "type": "string",
            "pattern": "^#[0-9A-Fa-f]{6}$"
          },
          "limit": {
            "type": "integer",
            "format": "int64",
            "minimum": 0,
            "description": "Amount in XAF (zero-decimal)."
          }
        },
        "description": "Request payload used to create a spending category."
      },
      "CategoryRule": {
        "type": "object",
        "required": [
          "id",
          "pattern",
          "category_id"
        ],
        "properties": {
          "id": {
            "type": "string"
          },
          "pattern": {
            "type": "string",
            "description": "Substring or regex applied to transaction description."
          },
          "category_id": {
            "type": "string"
          },
          "priority": {
            "type": "integer",
            "default": 100
          },
          "created_at": {
            "type": "string",
            "format": "date-time"
          }
        },
        "description": "An automatic categorisation rule matching transaction attributes to a spending category."
      },
      "SavingsGoal": {
        "type": "object",
        "required": [
          "id",
          "name",
          "target_amount",
          "current_amount",
          "status",
          "created_at"
        ],
        "properties": {
          "id": {
            "type": "string",
            "example": "goal_01HXYZ"
          },
          "name": {
            "type": "string"
          },
          "target_amount": {
            "type": "integer",
            "format": "int64",
            "minimum": 0,
            "description": "Amount in XAF (zero-decimal)."
          },
          "current_amount": {
            "type": "integer",
            "format": "int64",
            "minimum": 0,
            "description": "Amount in XAF (zero-decimal)."
          },
          "deadline": {
            "type": "string",
            "format": "date"
          },
          "icon": {
            "type": "string"
          },
          "colour": {
            "type": "string",
            "pattern": "^#[0-9A-Fa-f]{6}$"
          },
          "round_up_enabled": {
            "type": "boolean",
            "default": false
          },
          "round_up_nearest": {
            "type": [
              "integer",
              "null"
            ],
            "enum": [
              500,
              1000,
              2000,
              null
            ]
          },
          "linked_piggy_bank_id": {
            "type": [
              "string",
              "null"
            ]
          },
          "status": {
            "type": "string",
            "enum": [
              "active",
              "completed",
              "paused"
            ]
          },
          "created_at": {
            "type": "string",
            "format": "date-time"
          }
        },
        "description": "A goal-based savings target, including the target amount, deadline and optional round-up configuration."
      },
      "GoalProgress": {
        "type": "object",
        "required": [
          "goal_id",
          "percentage_complete",
          "amount_remaining"
        ],
        "properties": {
          "goal_id": {
            "type": "string"
          },
          "percentage_complete": {
            "type": "number",
            "format": "float"
          },
          "amount_remaining": {
            "type": "integer",
            "format": "int64",
            "minimum": 0,
            "description": "Amount in XAF (zero-decimal)."
          },
          "projected_completion_date": {
            "type": "string",
            "format": "date"
          },
          "weekly_required": {
            "type": "integer",
            "format": "int64",
            "minimum": 0,
            "description": "Amount in XAF (zero-decimal)."
          },
          "on_track": {
            "type": "boolean"
          },
          "milestones_reached": {
            "type": "array",
            "items": {
              "type": "integer",
              "enum": [
                25,
                50,
                75,
                100
              ]
            }
          },
          "next_milestone": {
            "type": [
              "integer",
              "null"
            ]
          },
          "round_up_total_this_month": {
            "type": "integer",
            "format": "int64",
            "minimum": 0,
            "description": "Amount in XAF (zero-decimal)."
          }
        },
        "description": "Progress against a savings goal: amount saved, amount remaining and the projected completion position."
      },
      "NjangiSchedule": {
        "type": "object",
        "required": [
          "group_id",
          "next_contribution_date",
          "next_contribution_amount"
        ],
        "properties": {
          "group_id": {
            "type": "string"
          },
          "group_name": {
            "type": "string"
          },
          "next_contribution_date": {
            "type": "string",
            "format": "date"
          },
          "next_contribution_amount": {
            "type": "integer",
            "format": "int64",
            "minimum": 0,
            "description": "Amount in XAF (zero-decimal)."
          },
          "days_until_due": {
            "type": "integer"
          },
          "budget_impact_xaf": {
            "type": "integer",
            "format": "int64",
            "minimum": 0,
            "description": "Amount in XAF (zero-decimal)."
          },
          "reminder_enabled": {
            "type": "boolean"
          }
        },
        "description": "The rotating contribution and payout schedule for a Njangi group."
      },
      "BudgetInsight": {
        "type": "object",
        "required": [
          "answer",
          "lang",
          "generated_at"
        ],
        "properties": {
          "answer": {
            "type": "string"
          },
          "lang": {
            "type": "string",
            "enum": [
              "en",
              "fr",
              "pid"
            ],
            "description": "Response language: English, French, or Cameroon Pidgin."
          },
          "confidence": {
            "type": "number",
            "format": "float",
            "minimum": 0,
            "maximum": 1
          },
          "suggested_action": {
            "type": [
              "object",
              "null"
            ],
            "properties": {
              "type": {
                "type": "string",
                "enum": [
                  "update_category_limit",
                  "create_goal",
                  "pause_category",
                  "enable_roundup"
                ]
              },
              "category_id": {
                "type": [
                  "string",
                  "null"
                ]
              },
              "suggested_limit": {
                "type": [
                  "integer",
                  "null"
                ]
              }
            }
          },
          "generated_at": {
            "type": "string",
            "format": "date-time"
          }
        },
        "description": "A cached AI-generated budgeting insight for the authenticated user, with the period it was derived from."
      },
      "InsightAskRequest": {
        "type": "object",
        "required": [
          "question",
          "lang"
        ],
        "properties": {
          "question": {
            "type": "string",
            "maxLength": 500
          },
          "lang": {
            "type": "string",
            "enum": [
              "en",
              "fr",
              "pid"
            ],
            "description": "Response language: English, French, or Cameroon Pidgin."
          },
          "context": {
            "type": "string",
            "enum": [
              "budget_summary",
              "category",
              "goal",
              "general"
            ]
          }
        },
        "description": "Request payload asking the budgeting adviser a free-text question. Requests are rate-limited per user per day."
      },
      "InsightAskResponse": {
        "$ref": "#/components/schemas/BudgetInsight",
        "description": "The budgeting adviser answer, together with the remaining daily question allowance."
      },
      "BudgetAlert": {
        "type": "object",
        "required": [
          "id",
          "type",
          "severity",
          "message",
          "created_at",
          "dismissed"
        ],
        "properties": {
          "id": {
            "type": "string"
          },
          "type": {
            "type": "string",
            "enum": [
              "budget.threshold_reached",
              "budget.overspent",
              "goal.milestone_reached",
              "njangi.contribution_due",
              "budget.unusual_transaction"
            ]
          },
          "severity": {
            "type": "string",
            "enum": [
              "info",
              "warning",
              "critical"
            ]
          },
          "message": {
            "type": "string"
          },
          "category_id": {
            "type": [
              "string",
              "null"
            ]
          },
          "created_at": {
            "type": "string",
            "format": "date-time"
          },
          "dismissed": {
            "type": "boolean"
          }
        },
        "description": "A budget alert raised when spending crosses a configured threshold, until it is dismissed by the user."
      },
      "MonthlyAnalytics": {
        "type": "object",
        "required": [
          "months"
        ],
        "properties": {
          "months": {
            "type": "array",
            "items": {
              "type": "object",
              "properties": {
                "month": {
                  "type": "string",
                  "example": "2026-03"
                },
                "total_spent": {
                  "type": "integer",
                  "format": "int64",
                  "minimum": 0,
                  "description": "Amount in XAF (zero-decimal)."
                },
                "by_category": {
                  "type": "object",
                  "additionalProperties": {
                    "type": "integer",
                    "format": "int64",
                    "minimum": 0,
                    "description": "Amount in XAF (zero-decimal)."
                  }
                }
              }
            }
          }
        },
        "description": "Aggregated monthly spending analytics for the authenticated user, broken down by category."
      },
      "MerchantAnalytics": {
        "type": "object",
        "required": [
          "period",
          "merchants"
        ],
        "properties": {
          "period": {
            "type": "string"
          },
          "merchants": {
            "type": "array",
            "items": {
              "type": "object",
              "properties": {
                "name": {
                  "type": "string"
                },
                "category_id": {
                  "type": "string"
                },
                "total_spent": {
                  "type": "integer",
                  "format": "int64",
                  "minimum": 0,
                  "description": "Amount in XAF (zero-decimal)."
                },
                "transaction_count": {
                  "type": "integer"
                }
              }
            }
          }
        },
        "description": "Aggregated spending analytics grouped by merchant for the requested period."
      },
      "PaymentIntent": {
        "type": "object",
        "description": "Rail-agnostic asynchronous payment intent. Models the canonical lifecycle of any payment from creation through terminal state. State machine (Stripe API Reference §payment_intents): requires_payment_method → requires_confirmation → processing → (requires_action → processing →)* succeeded | canceled | failed.",
        "required": [
          "id",
          "amount",
          "currency",
          "status",
          "payment_method_types",
          "created_at"
        ],
        "properties": {
          "id": {
            "type": "string",
            "format": "uuid"
          },
          "amount": {
            "type": "string",
            "description": "Smallest currency unit; for XAF/XOF this is the whole amount (zero-decimal). Decimal string to preserve exact monetary precision.",
            "pattern": "^-?[0-9]{1,15}(\\.[0-9]{1,4})?$"
          },
          "currency": {
            "type": "string",
            "pattern": "^[A-Z]{3}$"
          },
          "status": {
            "type": "string",
            "enum": [
              "requires_payment_method",
              "requires_confirmation",
              "processing",
              "requires_action",
              "succeeded",
              "canceled",
              "failed"
            ]
          },
          "payment_method_types": {
            "type": "array",
            "items": {
              "type": "string",
              "enum": [
                "mobile_money",
                "bank_transfer",
                "card",
                "pay_by_bank",
                "wallet"
              ]
            },
            "minItems": 1
          },
          "next_action": {
            "type": "object",
            "nullable": true,
            "description": "Present when status is `requires_action`. Tells the client what to do next.",
            "properties": {
              "type": {
                "type": "string",
                "enum": [
                  "redirect_to_url",
                  "display_qr",
                  "use_stk_push",
                  "poll_provider"
                ]
              },
              "redirect_to_url": {
                "type": "object",
                "properties": {
                  "url": {
                    "type": "string",
                    "format": "uri"
                  },
                  "return_url": {
                    "type": "string",
                    "format": "uri"
                  }
                }
              },
              "display_qr": {
                "type": "object",
                "properties": {
                  "qr_payload": {
                    "type": "string"
                  }
                }
              },
              "use_stk_push": {
                "type": "object",
                "properties": {
                  "msisdn": {
                    "type": "string"
                  },
                  "operator": {
                    "type": "string"
                  }
                }
              }
            }
          },
          "last_error": {
            "type": "object",
            "nullable": true,
            "properties": {
              "code": {
                "type": "string"
              },
              "message": {
                "type": "string"
              }
            }
          },
          "description": {
            "type": "string",
            "nullable": true
          },
          "metadata": {
            "type": "object",
            "additionalProperties": true
          },
          "customer_id": {
            "type": "string",
            "format": "uuid",
            "nullable": true
          },
          "child_intent_id": {
            "type": "string",
            "format": "uuid",
            "nullable": true,
            "description": "ID of the underlying rail-specific intent (e.g. pay-by-bank intent or funding intent)."
          },
          "child_resource": {
            "type": "string",
            "nullable": true,
            "enum": [
              null,
              "pay_by_bank_intent",
              "funding_intent",
              "gateway_charge"
            ]
          },
          "created_at": {
            "type": "string",
            "format": "date-time"
          },
          "updated_at": {
            "type": "string",
            "format": "date-time"
          },
          "succeeded_at": {
            "type": "string",
            "format": "date-time",
            "nullable": true
          },
          "canceled_at": {
            "type": "string",
            "format": "date-time",
            "nullable": true
          }
        }
      },
      "PaymentIntentCreate": {
        "type": "object",
        "required": [
          "amount",
          "currency",
          "payment_method_types"
        ],
        "properties": {
          "amount": {
            "type": "string",
            "pattern": "^-?[0-9]{1,15}(\\.[0-9]{1,4})?$",
            "description": "Decimal string to preserve exact monetary precision."
          },
          "currency": {
            "type": "string",
            "pattern": "^[A-Z]{3}$"
          },
          "payment_method_types": {
            "type": "array",
            "items": {
              "type": "string",
              "enum": [
                "mobile_money",
                "bank_transfer",
                "card",
                "pay_by_bank",
                "wallet"
              ]
            },
            "minItems": 1
          },
          "confirm": {
            "type": "boolean",
            "default": false,
            "description": "If true, attempt immediate confirmation. If false, intent is created in `requires_confirmation`."
          },
          "description": {
            "type": "string"
          },
          "metadata": {
            "type": "object",
            "additionalProperties": true
          },
          "customer_id": {
            "type": "string",
            "format": "uuid"
          }
        }
      },
      "PaymentIntentList": {
        "type": "object",
        "required": [
          "data"
        ],
        "properties": {
          "data": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/PaymentIntent"
            }
          },
          "has_more": {
            "type": "boolean"
          },
          "next_cursor": {
            "type": "string",
            "nullable": true
          }
        }
      },
      "MobileMoneyErrorCode": {
        "type": "string",
        "description": "Unified KOB mobile-money error code. Maps every provider-specific code (MTN MoMo, Orange Money, Wave, M-Pesa) to a single taxonomy so SDKs can branch deterministically. See `/developer/reference/mobile-money-errors` for the full mapping.",
        "enum": [
          "insufficient_funds",
          "invalid_msisdn",
          "subscriber_not_found",
          "subscriber_pin_blocked",
          "subscriber_kyc_incomplete",
          "subscriber_limit_exceeded",
          "duplicate_transaction",
          "transaction_expired",
          "transaction_declined",
          "provider_timeout",
          "provider_unavailable",
          "currency_not_supported",
          "amount_below_minimum",
          "amount_above_maximum",
          "internal_error"
        ]
      },
      "MobileMoneyProviderError": {
        "type": "object",
        "description": "Raw upstream error preserved for audit + support. Use `normalized_code` for programmatic branching.",
        "required": [
          "provider",
          "raw_code",
          "normalized_code"
        ],
        "properties": {
          "provider": {
            "type": "string",
            "enum": [
              "mtn",
              "orange",
              "wave",
              "mpesa",
              "airtel"
            ]
          },
          "raw_code": {
            "type": "string",
            "description": "Verbatim provider error code (e.g. MTN ‘NOT_ENOUGH_FUNDS’)."
          },
          "raw_message": {
            "type": "string"
          },
          "normalized_code": {
            "$ref": "#/components/schemas/MobileMoneyErrorCode"
          },
          "retryable": {
            "type": "boolean"
          }
        }
      },
      "ConsentCreate": {
        "type": "object",
        "required": [
          "type",
          "permissions"
        ],
        "properties": {
          "type": {
            "type": "string",
            "enum": [
              "AISP",
              "PISP",
              "CBPII"
            ]
          },
          "permissions": {
            "type": "array",
            "minItems": 1,
            "items": {
              "type": "string",
              "enum": [
                "ReadAccountsBasic",
                "ReadAccountsDetail",
                "ReadBalances",
                "ReadTransactionsBasic",
                "ReadTransactionsDetail",
                "ReadBeneficiariesBasic",
                "ReadStandingOrdersBasic",
                "ReadDirectDebitsBasic",
                "ReadPAN",
                "InitiatePayment"
              ]
            }
          },
          "expiration_date": {
            "type": "string",
            "format": "date-time"
          },
          "transaction_from_date": {
            "type": "string",
            "format": "date"
          },
          "transaction_to_date": {
            "type": "string",
            "format": "date"
          },
          "psu_identifier": {
            "type": "string",
            "description": "PSU MSISDN or customer reference."
          }
        }
      },
      "ConsentList": {
        "type": "object",
        "required": [
          "data"
        ],
        "properties": {
          "data": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/Consent"
            }
          },
          "next_cursor": {
            "type": "string",
            "nullable": true
          }
        }
      },
      "StatementRequest": {
        "type": "object",
        "required": [
          "account_id",
          "period_from",
          "period_to"
        ],
        "properties": {
          "account_id": {
            "type": "string",
            "format": "uuid"
          },
          "period_from": {
            "type": "string",
            "format": "date"
          },
          "period_to": {
            "type": "string",
            "format": "date"
          },
          "format": {
            "type": "string",
            "enum": [
              "camt053",
              "pdf",
              "csv"
            ],
            "default": "camt053"
          }
        }
      },
      "Statement": {
        "type": "object",
        "required": [
          "statement_id",
          "account_id",
          "period_from",
          "period_to",
          "format",
          "status"
        ],
        "properties": {
          "statement_id": {
            "type": "string",
            "format": "uuid"
          },
          "account_id": {
            "type": "string",
            "format": "uuid"
          },
          "period_from": {
            "type": "string",
            "format": "date"
          },
          "period_to": {
            "type": "string",
            "format": "date"
          },
          "format": {
            "type": "string",
            "enum": [
              "camt053",
              "pdf",
              "csv"
            ]
          },
          "status": {
            "type": "string",
            "enum": [
              "pending",
              "ready",
              "failed"
            ]
          },
          "download_url": {
            "type": "string",
            "format": "uri",
            "nullable": true
          },
          "generated_at": {
            "type": "string",
            "format": "date-time",
            "nullable": true
          }
        }
      },
      "RateLimitTier": {
        "type": "object",
        "required": [
          "tier",
          "requests_per_minute",
          "burst",
          "concurrent_connections"
        ],
        "properties": {
          "tier": {
            "type": "string",
            "enum": [
              "free",
              "pro",
              "enterprise"
            ]
          },
          "requests_per_minute": {
            "type": "integer"
          },
          "burst": {
            "type": "integer"
          },
          "concurrent_connections": {
            "type": "integer"
          },
          "webhook_deliveries_per_minute": {
            "type": "integer"
          },
          "idempotency_window_hours": {
            "type": "integer"
          }
        }
      },
      "RateLimitTiers": {
        "type": "object",
        "required": [
          "data"
        ],
        "properties": {
          "data": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/RateLimitTier"
            }
          }
        }
      },
      "ExpressUnionPickup": {
        "type": "object",
        "description": "Express Union cash-pickup envelope. Returned in next_action when channel=mobile_money and provider=ExpressUnion.",
        "properties": {
          "pickup_code": {
            "type": "string",
            "minLength": 6,
            "maxLength": 12,
            "example": "EU8K2N4"
          },
          "pickup_locations_url": {
            "type": "string",
            "format": "uri",
            "example": "https://expressunion.cm/agences"
          },
          "expires_at": {
            "type": "string",
            "format": "date-time"
          },
          "recipient_name": {
            "type": "string",
            "maxLength": 120
          }
        },
        "required": [
          "pickup_code",
          "expires_at"
        ]
      },
      "CamPostAccount": {
        "type": "object",
        "description": "CamPost (La Poste du Cameroun) postal financial account identifier.",
        "properties": {
          "postal_account": {
            "type": "string",
            "pattern": "^CP[0-9]{8,12}$",
            "example": "CP00045123987"
          },
          "branch_code": {
            "type": "string",
            "maxLength": 6,
            "example": "YDE01"
          }
        },
        "required": [
          "postal_account"
        ]
      },
      "RtpSla": {
        "type": "object",
        "description": "Real-time payment SLA hints. Indicates the expected confirmation window for the underlying rail. Targets are p50/p95 based on the trailing 30-day production sample (see /developer/reference/rtp-sla).",
        "properties": {
          "expected_completion_seconds": {
            "type": "integer",
            "minimum": 1,
            "maximum": 86400,
            "example": 18
          },
          "sla_tier": {
            "type": "string",
            "enum": [
              "instant",
              "p50_30s",
              "p95_60s",
              "p99_300s",
              "best_effort"
            ],
            "example": "p50_30s"
          },
          "retry_after_seconds": {
            "type": "integer",
            "minimum": 1,
            "maximum": 3600,
            "example": 3
          },
          "provider_p50_ms": {
            "type": "integer",
            "minimum": 0,
            "example": 18000
          },
          "provider_p95_ms": {
            "type": "integer",
            "minimum": 0,
            "example": 42000
          }
        },
        "required": [
          "expected_completion_seconds",
          "sla_tier"
        ]
      },
      "LocalizedError": {
        "type": "object",
        "description": "Localized RFC 7807 error envelope. Returned by /v1/errors/{code}.",
        "properties": {
          "code": {
            "type": "string",
            "example": "AUTH_001"
          },
          "type": {
            "type": "string",
            "format": "uri",
            "example": "https://docs.kangopenbanking.com/errors/AUTH_001"
          },
          "title_en": {
            "type": "string",
            "example": "Invalid access token"
          },
          "title_fr": {
            "type": "string",
            "example": "Jeton d'accès invalide"
          },
          "detail_en": {
            "type": "string"
          },
          "detail_fr": {
            "type": "string"
          },
          "status": {
            "type": "integer",
            "example": 401
          },
          "remediation_url": {
            "type": "string",
            "format": "uri"
          }
        },
        "required": [
          "code",
          "title_en",
          "title_fr",
          "status"
        ]
      },
      "NinVerificationRequest": {
        "type": "object",
        "properties": {
          "country": {
            "type": "string",
            "enum": [
              "CM",
              "GA",
              "CG",
              "TD",
              "CF",
              "GQ"
            ],
            "example": "CM"
          },
          "nin": {
            "type": "string",
            "pattern": "^[A-Z0-9]{8,18}$",
            "example": "11999900001234"
          },
          "holder_first_name": {
            "type": "string",
            "maxLength": 80
          },
          "holder_last_name": {
            "type": "string",
            "maxLength": 80
          },
          "holder_dob": {
            "type": "string",
            "format": "date",
            "example": "1990-05-12"
          },
          "consent_id": {
            "type": "string",
            "format": "uuid"
          }
        },
        "required": [
          "country",
          "nin",
          "consent_id"
        ]
      },
      "NinVerificationResult": {
        "type": "object",
        "properties": {
          "match": {
            "type": "boolean",
            "example": true
          },
          "score": {
            "type": "integer",
            "minimum": 0,
            "maximum": 100,
            "example": 97
          },
          "holder_full_name": {
            "type": "string",
            "example": "MBALLA NGONO Jean"
          },
          "holder_dob": {
            "type": "string",
            "format": "date"
          },
          "issuing_authority": {
            "type": "string",
            "example": "ANTIC Cameroun"
          },
          "issued_at": {
            "type": "string",
            "format": "date"
          },
          "expires_at": {
            "type": "string",
            "format": "date"
          },
          "verified_at": {
            "type": "string",
            "format": "date-time"
          }
        },
        "required": [
          "match",
          "score",
          "verified_at"
        ]
      },
      "CniVerificationRequest": {
        "type": "object",
        "properties": {
          "country": {
            "type": "string",
            "enum": [
              "CM",
              "GA",
              "CG",
              "TD",
              "CF",
              "GQ"
            ],
            "example": "CM"
          },
          "cni_number": {
            "type": "string",
            "pattern": "^[A-Z0-9]{6,18}$",
            "example": "110123456"
          },
          "holder_first_name": {
            "type": "string",
            "maxLength": 80
          },
          "holder_last_name": {
            "type": "string",
            "maxLength": 80
          },
          "holder_dob": {
            "type": "string",
            "format": "date"
          },
          "consent_id": {
            "type": "string",
            "format": "uuid"
          }
        },
        "required": [
          "country",
          "cni_number",
          "consent_id"
        ]
      },
      "CniVerificationResult": {
        "type": "object",
        "properties": {
          "match": {
            "type": "boolean",
            "example": true
          },
          "score": {
            "type": "integer",
            "minimum": 0,
            "maximum": 100,
            "example": 97
          },
          "holder_full_name": {
            "type": "string",
            "example": "MBALLA NGONO Jean"
          },
          "holder_dob": {
            "type": "string",
            "format": "date"
          },
          "issuing_authority": {
            "type": "string",
            "example": "ANTIC Cameroun"
          },
          "issued_at": {
            "type": "string",
            "format": "date"
          },
          "expires_at": {
            "type": "string",
            "format": "date"
          },
          "verified_at": {
            "type": "string",
            "format": "date-time"
          }
        },
        "required": [
          "match",
          "score",
          "verified_at"
        ]
      },
      "Agent": {
        "type": "object",
        "properties": {
          "id": {
            "type": "string",
            "format": "uuid"
          },
          "agent_code": {
            "type": "string",
            "example": "AG3K7M2P"
          },
          "business_name": {
            "type": "string",
            "example": "Mama Africa Mobile Money"
          },
          "legal_name": {
            "type": "string",
            "nullable": true
          },
          "msisdn": {
            "type": "string",
            "pattern": "^\\+?[0-9]{8,15}$",
            "example": "+237671234567"
          },
          "email": {
            "type": "string",
            "format": "email",
            "nullable": true
          },
          "country_code": {
            "type": "string",
            "enum": [
              "CM",
              "GA",
              "CG",
              "TD",
              "CF",
              "GQ"
            ],
            "example": "CM"
          },
          "region": {
            "type": "string",
            "nullable": true,
            "example": "Centre"
          },
          "city": {
            "type": "string",
            "nullable": true,
            "example": "Yaoundé"
          },
          "address": {
            "type": "string",
            "nullable": true
          },
          "latitude": {
            "type": "number",
            "format": "double",
            "nullable": true,
            "example": 3.848
          },
          "longitude": {
            "type": "number",
            "format": "double",
            "nullable": true,
            "example": 11.502
          },
          "status": {
            "type": "string",
            "enum": [
              "pending",
              "active",
              "suspended",
              "terminated"
            ]
          },
          "tier": {
            "type": "string",
            "enum": [
              "standard",
              "premium",
              "master"
            ]
          },
          "commission_rate": {
            "type": "number",
            "format": "double",
            "example": 0.01
          },
          "created_at": {
            "type": "string",
            "format": "date-time"
          }
        },
        "required": [
          "agent_code",
          "business_name",
          "msisdn",
          "country_code",
          "status",
          "tier"
        ]
      },
      "AgentRegisterRequest": {
        "type": "object",
        "properties": {
          "business_name": {
            "type": "string",
            "minLength": 2,
            "maxLength": 200
          },
          "legal_name": {
            "type": "string",
            "maxLength": 200
          },
          "msisdn": {
            "type": "string",
            "pattern": "^\\+?[0-9]{8,15}$"
          },
          "email": {
            "type": "string",
            "format": "email"
          },
          "country_code": {
            "type": "string",
            "enum": [
              "CM",
              "GA",
              "CG",
              "TD",
              "CF",
              "GQ"
            ]
          },
          "region": {
            "type": "string"
          },
          "city": {
            "type": "string"
          },
          "address": {
            "type": "string"
          },
          "latitude": {
            "type": "number"
          },
          "longitude": {
            "type": "number"
          },
          "tier": {
            "type": "string",
            "enum": [
              "standard",
              "premium",
              "master"
            ]
          }
        },
        "required": [
          "business_name",
          "msisdn"
        ]
      },
      "AgentFloat": {
        "type": "object",
        "properties": {
          "currency": {
            "type": "string",
            "enum": [
              "XAF",
              "XOF",
              "EUR",
              "USD"
            ]
          },
          "float_balance": {
            "type": "number",
            "format": "double",
            "example": 250000
          },
          "cash_balance": {
            "type": "number",
            "format": "double",
            "example": 75000
          },
          "low_threshold": {
            "type": "number",
            "format": "double",
            "example": 50000
          },
          "last_topup_at": {
            "type": "string",
            "format": "date-time",
            "nullable": true
          }
        },
        "required": [
          "currency",
          "float_balance",
          "cash_balance"
        ]
      },
      "AgentFloatMutationRequest": {
        "type": "object",
        "properties": {
          "amount": {
            "type": "string",
            "pattern": "^-?[0-9]{1,15}(\\.[0-9]{1,4})?$",
            "description": "Decimal string to preserve exact monetary precision."
          },
          "currency": {
            "type": "string",
            "enum": [
              "XAF",
              "XOF",
              "EUR",
              "USD"
            ],
            "default": "XAF"
          }
        },
        "required": [
          "amount"
        ]
      },
      "AgentCashTransaction": {
        "type": "object",
        "properties": {
          "id": {
            "type": "string",
            "format": "uuid"
          },
          "agent_id": {
            "type": "string",
            "format": "uuid"
          },
          "customer_msisdn": {
            "type": "string",
            "nullable": true
          },
          "customer_user_id": {
            "type": "string",
            "format": "uuid",
            "nullable": true
          },
          "tx_type": {
            "type": "string",
            "enum": [
              "cash_in",
              "cash_out",
              "float_topup",
              "float_withdraw",
              "commission"
            ]
          },
          "amount": {
            "type": "string",
            "pattern": "^-?[0-9]{1,15}(\\.[0-9]{1,4})?$",
            "description": "Decimal string to preserve exact monetary precision."
          },
          "currency": {
            "type": "string"
          },
          "commission_amount": {
            "type": "number",
            "format": "double"
          },
          "status": {
            "type": "string",
            "enum": [
              "pending",
              "completed",
              "failed",
              "reversed"
            ]
          },
          "idempotency_key": {
            "type": "string",
            "format": "uuid"
          },
          "created_at": {
            "type": "string",
            "format": "date-time"
          },
          "completed_at": {
            "type": "string",
            "format": "date-time",
            "nullable": true
          }
        },
        "required": [
          "id",
          "agent_id",
          "tx_type",
          "amount",
          "currency",
          "status",
          "idempotency_key"
        ]
      },
      "AgentCashRequest": {
        "type": "object",
        "properties": {
          "amount": {
            "type": "string",
            "pattern": "^-?[0-9]{1,15}(\\.[0-9]{1,4})?$",
            "description": "Decimal string to preserve exact monetary precision."
          },
          "currency": {
            "type": "string",
            "enum": [
              "XAF",
              "XOF"
            ],
            "default": "XAF"
          },
          "customer_msisdn": {
            "type": "string",
            "pattern": "^\\+?[0-9]{8,15}$"
          },
          "customer_user_id": {
            "type": "string",
            "format": "uuid"
          },
          "reference": {
            "type": "string",
            "maxLength": 64
          }
        },
        "required": [
          "amount"
        ]
      },
      "AdminTestWebhookRequest": {
        "type": "object",
        "required": [
          "endpoint_id",
          "event_type"
        ],
        "properties": {
          "endpoint_id": {
            "type": "string",
            "format": "uuid"
          },
          "event_type": {
            "type": "string",
            "enum": [
              "payment.succeeded",
              "payment.failed",
              "qr.paid",
              "remittance.cemac.paid",
              "agent.cashin.completed",
              "ussd.session.ended",
              "transfer.completed"
            ]
          },
          "payload": {
            "type": "object",
            "additionalProperties": true
          }
        }
      },
      "AdminTestWebhookResult": {
        "type": "object",
        "required": [
          "delivery_id",
          "status"
        ],
        "properties": {
          "delivery_id": {
            "type": "string",
            "format": "uuid",
            "nullable": true
          },
          "event_id": {
            "type": "string"
          },
          "status": {
            "type": "string",
            "enum": [
              "delivered",
              "failed"
            ]
          },
          "http_status": {
            "type": "integer"
          },
          "latency_ms": {
            "type": "integer"
          },
          "signature_header": {
            "type": "string"
          },
          "endpoint_url": {
            "type": "string",
            "format": "uri"
          }
        }
      },
      "AdminApiKey": {
        "type": "object",
        "required": [
          "id",
          "status",
          "environment"
        ],
        "properties": {
          "id": {
            "type": "string",
            "format": "uuid"
          },
          "key_prefix": {
            "type": "string",
            "example": "sk_live_a1b2"
          },
          "label": {
            "type": "string"
          },
          "environment": {
            "type": "string",
            "enum": [
              "sandbox",
              "production"
            ]
          },
          "status": {
            "type": "string",
            "enum": [
              "active",
              "suspended",
              "revoked"
            ]
          },
          "created_at": {
            "type": "string",
            "format": "date-time"
          },
          "suspended_at": {
            "type": "string",
            "format": "date-time",
            "nullable": true
          },
          "suspended_reason": {
            "type": "string",
            "nullable": true
          }
        }
      },
      "AdminApiKeyCreateRequest": {
        "type": "object",
        "required": [
          "merchant_id"
        ],
        "properties": {
          "merchant_id": {
            "type": "string",
            "format": "uuid"
          },
          "label": {
            "type": "string",
            "maxLength": 120
          },
          "environment": {
            "type": "string",
            "enum": [
              "sandbox",
              "production"
            ],
            "default": "sandbox"
          }
        }
      },
      "AdminApiKeyCreateResponse": {
        "allOf": [
          {
            "$ref": "#/components/schemas/AdminApiKey"
          },
          {
            "type": "object",
            "required": [
              "api_key",
              "shown_once"
            ],
            "properties": {
              "api_key": {
                "type": "string",
                "example": "sk_live_…"
              },
              "shown_once": {
                "type": "boolean"
              },
              "message": {
                "type": "string"
              }
            }
          }
        ]
      },
      "AdminApiKeySuspendRequest": {
        "type": "object",
        "required": [
          "action"
        ],
        "properties": {
          "action": {
            "type": "string",
            "enum": [
              "suspend",
              "resume"
            ]
          },
          "reason": {
            "type": "string",
            "maxLength": 500
          }
        }
      },
      "UssdSession": {
        "type": "object",
        "required": [
          "id",
          "msisdn",
          "session_id",
          "state",
          "created_at"
        ],
        "properties": {
          "id": {
            "type": "string",
            "format": "uuid"
          },
          "session_id": {
            "type": "string",
            "example": "USSD-3f9d2c"
          },
          "msisdn": {
            "type": "string",
            "pattern": "^\\+?[0-9]{8,15}$",
            "example": "+237671234567"
          },
          "service_code": {
            "type": "string",
            "example": "*144#"
          },
          "state": {
            "type": "string",
            "enum": [
              "active",
              "ended",
              "expired"
            ]
          },
          "menu": {
            "type": "string",
            "example": "1. Send Money\n2. Buy Airtime\n3. Balance"
          },
          "input": {
            "type": "string",
            "nullable": true
          },
          "language": {
            "type": "string",
            "enum": [
              "en",
              "fr"
            ],
            "example": "fr"
          },
          "created_at": {
            "type": "string",
            "format": "date-time"
          },
          "ended_at": {
            "type": "string",
            "format": "date-time",
            "nullable": true
          }
        }
      },
      "UssdSessionRequest": {
        "type": "object",
        "required": [
          "session_id",
          "msisdn",
          "service_code"
        ],
        "properties": {
          "session_id": {
            "type": "string"
          },
          "msisdn": {
            "type": "string",
            "pattern": "^\\+?[0-9]{8,15}$"
          },
          "service_code": {
            "type": "string"
          },
          "input": {
            "type": "string",
            "nullable": true
          },
          "language": {
            "type": "string",
            "enum": [
              "en",
              "fr"
            ],
            "default": "fr"
          }
        }
      },
      "QrCode": {
        "type": "object",
        "required": [
          "id",
          "payload",
          "amount",
          "currency",
          "merchant_id",
          "status",
          "created_at"
        ],
        "properties": {
          "id": {
            "type": "string",
            "format": "uuid"
          },
          "payload": {
            "type": "string",
            "description": "EMVCo-compliant TLV payload (base64)."
          },
          "amount": {
            "type": "string",
            "pattern": "^[0-9]{1,15}$",
            "example": "5000"
          },
          "currency": {
            "type": "string",
            "enum": [
              "XAF",
              "XOF"
            ],
            "example": "XAF"
          },
          "merchant_id": {
            "type": "string",
            "format": "uuid"
          },
          "status": {
            "type": "string",
            "enum": [
              "active",
              "consumed",
              "expired",
              "revoked"
            ]
          },
          "expires_at": {
            "type": "string",
            "format": "date-time",
            "nullable": true
          },
          "created_at": {
            "type": "string",
            "format": "date-time"
          }
        }
      },
      "OfflineToken": {
        "type": "object",
        "required": [
          "token_id",
          "payer_id",
          "amount",
          "currency",
          "issued_at",
          "expires_at",
          "signature"
        ],
        "properties": {
          "token_id": {
            "type": "string",
            "format": "uuid"
          },
          "payer_id": {
            "type": "string",
            "format": "uuid"
          },
          "payee_id": {
            "type": "string",
            "format": "uuid",
            "nullable": true
          },
          "amount": {
            "type": "string",
            "pattern": "^[0-9]{1,15}$"
          },
          "currency": {
            "type": "string",
            "enum": [
              "XAF",
              "XOF"
            ]
          },
          "issued_at": {
            "type": "string",
            "format": "date-time"
          },
          "expires_at": {
            "type": "string",
            "format": "date-time"
          },
          "signature": {
            "type": "string",
            "description": "Ed25519 detached signature (base64url)."
          },
          "redeemed_at": {
            "type": "string",
            "format": "date-time",
            "nullable": true
          }
        }
      },
      "OfflineTokenIssueRequest": {
        "type": "object",
        "required": [
          "payer_id",
          "amount",
          "currency"
        ],
        "properties": {
          "payer_id": {
            "type": "string",
            "format": "uuid"
          },
          "payee_id": {
            "type": "string",
            "format": "uuid",
            "nullable": true
          },
          "amount": {
            "type": "string",
            "pattern": "^[0-9]{1,15}$"
          },
          "currency": {
            "type": "string",
            "enum": [
              "XAF",
              "XOF"
            ]
          },
          "ttl_seconds": {
            "type": "integer",
            "minimum": 60,
            "maximum": 86400,
            "default": 3600
          }
        }
      },
      "OfflineTokenRedeemRequest": {
        "type": "object",
        "required": [
          "token_id",
          "signature"
        ],
        "properties": {
          "token_id": {
            "type": "string",
            "format": "uuid"
          },
          "signature": {
            "type": "string"
          },
          "payee_id": {
            "type": "string",
            "format": "uuid"
          }
        }
      },
      "CemacCorridor": {
        "type": "object",
        "required": [
          "origin_country",
          "destination_country",
          "fee_bps",
          "fx_rate",
          "status"
        ],
        "properties": {
          "origin_country": {
            "type": "string",
            "enum": [
              "CM",
              "GA",
              "CG",
              "TD",
              "CF",
              "GQ"
            ]
          },
          "destination_country": {
            "type": "string",
            "enum": [
              "CM",
              "GA",
              "CG",
              "TD",
              "CF",
              "GQ"
            ]
          },
          "fee_bps": {
            "type": "integer",
            "minimum": 0,
            "maximum": 1000,
            "example": 100
          },
          "fx_rate": {
            "type": "number",
            "format": "double",
            "example": 1
          },
          "status": {
            "type": "string",
            "enum": [
              "active",
              "suspended"
            ]
          }
        }
      },
      "CemacRemittanceQuoteRequest": {
        "type": "object",
        "required": [
          "origin_country",
          "destination_country",
          "amount"
        ],
        "properties": {
          "origin_country": {
            "type": "string",
            "enum": [
              "CM",
              "GA",
              "CG",
              "TD",
              "CF",
              "GQ"
            ]
          },
          "destination_country": {
            "type": "string",
            "enum": [
              "CM",
              "GA",
              "CG",
              "TD",
              "CF",
              "GQ"
            ]
          },
          "amount": {
            "type": "string",
            "pattern": "^[0-9]{1,15}$",
            "example": "50000"
          }
        }
      },
      "CemacRemittanceQuote": {
        "type": "object",
        "required": [
          "amount",
          "fee",
          "net",
          "receive_amount",
          "fx_rate",
          "currency"
        ],
        "properties": {
          "amount": {
            "type": "string",
            "pattern": "^[0-9]{1,15}$"
          },
          "fee": {
            "type": "string",
            "pattern": "^[0-9]{1,15}$"
          },
          "net": {
            "type": "string",
            "pattern": "^[0-9]{1,15}$"
          },
          "receive_amount": {
            "type": "string",
            "pattern": "^[0-9]{1,15}$"
          },
          "fx_rate": {
            "type": "number",
            "format": "double"
          },
          "currency": {
            "type": "string",
            "enum": [
              "XAF"
            ]
          },
          "quote_id": {
            "type": "string",
            "format": "uuid"
          },
          "expires_at": {
            "type": "string",
            "format": "date-time"
          }
        }
      },
      "CemacRemittanceTransferRequest": {
        "type": "object",
        "required": [
          "quote_id",
          "sender",
          "recipient"
        ],
        "properties": {
          "quote_id": {
            "type": "string",
            "format": "uuid"
          },
          "sender": {
            "type": "object",
            "required": [
              "full_name",
              "msisdn",
              "country"
            ],
            "properties": {
              "full_name": {
                "type": "string"
              },
              "msisdn": {
                "type": "string",
                "pattern": "^\\+?[0-9]{8,15}$"
              },
              "country": {
                "type": "string",
                "enum": [
                  "CM",
                  "GA",
                  "CG",
                  "TD",
                  "CF",
                  "GQ"
                ]
              }
            }
          },
          "recipient": {
            "type": "object",
            "required": [
              "full_name",
              "msisdn",
              "country"
            ],
            "properties": {
              "full_name": {
                "type": "string"
              },
              "msisdn": {
                "type": "string",
                "pattern": "^\\+?[0-9]{8,15}$"
              },
              "country": {
                "type": "string",
                "enum": [
                  "CM",
                  "GA",
                  "CG",
                  "TD",
                  "CF",
                  "GQ"
                ]
              }
            }
          },
          "reference": {
            "type": "string",
            "maxLength": 140,
            "nullable": true
          }
        }
      },
      "CemacRemittanceTransfer": {
        "type": "object",
        "required": [
          "id",
          "status",
          "amount",
          "fee",
          "net",
          "origin_country",
          "destination_country",
          "created_at"
        ],
        "properties": {
          "id": {
            "type": "string",
            "format": "uuid"
          },
          "status": {
            "type": "string",
            "enum": [
              "pending",
              "funded",
              "settled",
              "cancelled",
              "failed"
            ]
          },
          "amount": {
            "type": "string",
            "pattern": "^[0-9]{1,15}$"
          },
          "fee": {
            "type": "string",
            "pattern": "^[0-9]{1,15}$"
          },
          "net": {
            "type": "string",
            "pattern": "^[0-9]{1,15}$"
          },
          "origin_country": {
            "type": "string",
            "enum": [
              "CM",
              "GA",
              "CG",
              "TD",
              "CF",
              "GQ"
            ]
          },
          "destination_country": {
            "type": "string",
            "enum": [
              "CM",
              "GA",
              "CG",
              "TD",
              "CF",
              "GQ"
            ]
          },
          "reference": {
            "type": "string",
            "nullable": true
          },
          "created_at": {
            "type": "string",
            "format": "date-time"
          },
          "settled_at": {
            "type": "string",
            "format": "date-time",
            "nullable": true
          }
        }
      },
      "NiumGlobalAccount": {
        "type": "object",
        "properties": {
          "id": {
            "type": "string",
            "format": "uuid"
          },
          "currency": {
            "type": "string",
            "enum": [
              "USD",
              "EUR",
              "GBP"
            ]
          },
          "iban": {
            "type": "string",
            "nullable": true
          },
          "account_number": {
            "type": "string",
            "nullable": true
          },
          "routing_code": {
            "type": "string",
            "nullable": true
          },
          "bic": {
            "type": "string",
            "nullable": true
          },
          "bank_name": {
            "type": "string"
          },
          "bank_address": {
            "type": "string",
            "nullable": true
          },
          "beneficiary_name": {
            "type": "string"
          },
          "status": {
            "type": "string",
            "enum": [
              "active",
              "suspended",
              "closed"
            ]
          },
          "payout_preference_override": {
            "type": "string",
            "nullable": true,
            "enum": [
              "KANG_WALLET",
              "MOBILE_MONEY",
              null
            ]
          },
          "payout_channel_override": {
            "type": "string",
            "nullable": true
          },
          "mode": {
            "type": "string",
            "enum": [
              "stub",
              "sandbox",
              "live"
            ]
          }
        },
        "example": {
          "id": "f1d6f4a0-1d4e-4a3a-9e0a-1a2b3c4d5e6f",
          "currency": "USD",
          "iban": null,
          "account_number": "912345678",
          "routing_code": "021000021",
          "bic": "CHASUS33",
          "bank_name": "JPMorgan Chase (via Nium)",
          "bank_address": "383 Madison Ave, New York, NY 10179",
          "beneficiary_name": "Jane Influencer",
          "status": "active",
          "payout_preference_override": null,
          "payout_channel_override": null,
          "mode": "stub"
        },
        "required": [
          "currency",
          "status"
        ]
      },
      "NiumIncomingPayment": {
        "type": "object",
        "properties": {
          "id": {
            "type": "string",
            "format": "uuid"
          },
          "source_amount": {
            "type": "number"
          },
          "source_currency": {
            "type": "string"
          },
          "fx_rate_nium": {
            "type": "number"
          },
          "fx_spread_bps": {
            "type": "integer"
          },
          "xaf_gross": {
            "type": "number"
          },
          "xaf_spread_revenue": {
            "type": "number"
          },
          "xaf_withdrawal_fee": {
            "type": "number"
          },
          "xaf_net_credited": {
            "type": "number"
          },
          "routing": {
            "type": "string",
            "enum": [
              "KANG_WALLET",
              "MOBILE_MONEY"
            ]
          },
          "status": {
            "type": "string",
            "enum": [
              "received",
              "credited",
              "payout_pending",
              "payout_completed",
              "payout_failed",
              "failed"
            ]
          },
          "created_at": {
            "type": "string",
            "format": "date-time"
          }
        },
        "example": {
          "id": "p_2026_03_001",
          "source_amount": 250,
          "source_currency": "USD",
          "fx_rate_nium": 612.45,
          "fx_spread_bps": 75,
          "xaf_gross": 153112.5,
          "xaf_spread_revenue": 1148.34,
          "xaf_withdrawal_fee": 0,
          "xaf_net_credited": 151964.16,
          "routing": "KANG_WALLET",
          "status": "credited",
          "created_at": "2026-03-12T14:02:11Z"
        },
        "required": [
          "id"
        ]
      },
      "NiumPayoutPreference": {
        "type": "object",
        "properties": {
          "payout_preference": {
            "type": "string",
            "enum": [
              "KANG_WALLET",
              "MOBILE_MONEY"
            ]
          },
          "payout_channel": {
            "type": "string",
            "nullable": true
          }
        },
        "example": {
          "payout_preference": "MOBILE_MONEY",
          "payout_channel": "237677123456"
        },
        "required": [
          "payout_preference"
        ]
      },
      "NiumWebhookEvent": {
        "type": "object",
        "required": [
          "eventType",
          "transactionId",
          "accountId",
          "amount",
          "currency"
        ],
        "properties": {
          "eventType": {
            "type": "string",
            "example": "payment_incoming"
          },
          "transactionId": {
            "type": "string"
          },
          "accountId": {
            "type": "string"
          },
          "amount": {
            "type": "string",
            "pattern": "^-?[0-9]{1,15}(\\.[0-9]{1,4})?$",
            "description": "Decimal string to preserve exact monetary precision."
          },
          "currency": {
            "type": "string",
            "enum": [
              "USD",
              "EUR",
              "GBP"
            ]
          },
          "senderName": {
            "type": "string"
          },
          "reference": {
            "type": "string"
          }
        },
        "example": {
          "eventType": "payment_incoming",
          "transactionId": "NIUM_TX_001",
          "accountId": "nium_acc_abc123",
          "amount": 250,
          "currency": "USD",
          "senderName": "YouTube Adsense",
          "reference": "Creator payout March 2026"
        }
      },
      "Money": {
        "type": "object",
        "description": "Canonical monetary value. String-encoded minor units to avoid floating-point drift. Currency is an ISO 4217 code (or XAF/XOF for CEMAC/UEMOA zero-decimal).",
        "required": [
          "amount",
          "currency"
        ],
        "properties": {
          "amount": {
            "type": "string",
            "pattern": "^-?[0-9]{1,20}(\\.[0-9]{1,8})?$",
            "description": "Decimal string. For zero-decimal currencies (XAF, XOF, JPY) send integer strings only.",
            "example": "15000"
          },
          "currency": {
            "type": "string",
            "pattern": "^[A-Z]{3}$",
            "description": "ISO 4217 currency code (uppercase).",
            "example": "XAF"
          }
        },
        "x-added-in": "4.54.0",
        "x-status": "stable"
      },
      "AgentTransactionResponse": {
        "type": "object",
        "required": [
          "transaction_id",
          "agent_id",
          "type",
          "amount",
          "currency",
          "status",
          "balance_after",
          "created_at"
        ],
        "properties": {
          "transaction_id": {
            "type": "string",
            "format": "uuid",
            "description": "Unique ledger transaction identifier."
          },
          "agent_id": {
            "type": "string",
            "format": "uuid"
          },
          "type": {
            "type": "string",
            "enum": [
              "float_topup",
              "float_withdraw",
              "cash_in",
              "cash_out"
            ]
          },
          "amount": {
            "type": "string",
            "pattern": "^[0-9]{1,15}$",
            "description": "Amount in minor units (XAF/XOF are zero-decimal — value equals major units)."
          },
          "currency": {
            "type": "string",
            "enum": [
              "XAF",
              "XOF"
            ],
            "description": "ISO 4217 currency."
          },
          "status": {
            "type": "string",
            "enum": [
              "pending",
              "completed",
              "failed",
              "reversed"
            ]
          },
          "balance_after": {
            "type": "string",
            "pattern": "^[0-9]{1,15}$",
            "description": "Agent float balance after this transaction, in minor units."
          },
          "reference": {
            "type": [
              "string",
              "null"
            ],
            "description": "Optional external reference supplied by the caller."
          },
          "customer_phone": {
            "type": [
              "string",
              "null"
            ],
            "description": "Present on cash-in / cash-out operations."
          },
          "created_at": {
            "type": "string",
            "format": "date-time"
          }
        },
        "description": "Result of an agent float or cash movement. Zero-decimal currency amounts follow the KOB minor-unit string convention."
      },
      "JournalLine": {
        "type": "object",
        "description": "A single side of a double-entry journal entry. Exactly one of `debit` or `credit` must be non-zero.",
        "properties": {
          "ledger_account_id": {
            "type": "string",
            "format": "uuid",
            "description": "Ledger account this line posts against."
          },
          "debit": {
            "type": "number",
            "minimum": 0,
            "default": 0,
            "description": "Debit amount. Minor-unit-safe decimal amount. Zero-decimal currencies (XAF, XOF) MUST be supplied as whole numbers.",
            "example": 1000000
          },
          "credit": {
            "type": "number",
            "minimum": 0,
            "default": 0,
            "description": "Credit amount. Minor-unit-safe decimal amount. Zero-decimal currencies (XAF, XOF) MUST be supplied as whole numbers.",
            "example": 0
          },
          "memo": {
            "type": "string",
            "maxLength": 255,
            "description": "Optional line-level narrative.",
            "example": "Loan principal"
          }
        },
        "required": [
          "ledger_account_id",
          "debit",
          "credit"
        ],
        "additionalProperties": false
      },
      "JournalEntryCreateRequest": {
        "type": "object",
        "description": "Client-supplied journal entry. Server-generated fields (`id`, `created_at`) are not accepted. The entry MUST balance: the sum of `lines[].debit` MUST equal the sum of `lines[].credit`. Unbalanced entries are rejected with 422 `journal_entry_unbalanced`.",
        "properties": {
          "entry_date": {
            "type": "string",
            "format": "date",
            "description": "Accounting date of the entry.",
            "example": "2026-05-02"
          },
          "description": {
            "type": "string",
            "minLength": 1,
            "maxLength": 500,
            "example": "Loan disbursement - APP-2026-001"
          },
          "reference_type": {
            "type": "string",
            "enum": [
              "payment",
              "loan",
              "savings",
              "fee",
              "interest",
              "manual"
            ],
            "example": "loan"
          },
          "reference_id": {
            "type": "string",
            "format": "uuid",
            "description": "Identifier of the originating business object. Required for every non-manual reference type.",
            "example": "3f1a6b52-9c84-4d2e-8f77-1b0c5a9e4d31"
          },
          "lines": {
            "type": "array",
            "minItems": 2,
            "maxItems": 200,
            "description": "Balanced set of journal lines. At least one debit line and one credit line are required.",
            "items": {
              "$ref": "#/components/schemas/JournalLine"
            }
          }
        },
        "required": [
          "entry_date",
          "description",
          "reference_type",
          "lines"
        ],
        "additionalProperties": false
      },
      "GenericSuccessResponse": {
        "type": "object",
        "description": "Generic successful operation envelope.",
        "required": [
          "success"
        ],
        "properties": {
          "success": {
            "type": "boolean",
            "description": "True when the operation completed successfully."
          },
          "data": {
            "type": "object",
            "additionalProperties": true,
            "description": "Operation-specific payload."
          },
          "request_id": {
            "type": "string",
            "description": "Correlation identifier for this request."
          }
        }
      }
    },
    "parameters": {
      "IdempotencyKey": {
        "name": "Idempotency-Key",
        "in": "header",
        "required": true,
        "schema": {
          "type": "string",
          "format": "uuid",
          "pattern": "^[0-9a-f]{8}-[0-9a-f]{4}-4[0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}$",
          "maxLength": 255
        },
        "description": "Required on all POST/PUT endpoints. Unique key for idempotent request processing (UUID v4 recommended). Keys expire after 24 hours."
      },
      "Limit": {
        "name": "limit",
        "in": "query",
        "schema": {
          "type": "integer",
          "default": 25,
          "maximum": 100
        },
        "description": "Items per page"
      },
      "Offset": {
        "name": "offset",
        "in": "query",
        "schema": {
          "type": "integer",
          "default": 0
        },
        "description": "Items to skip"
      },
      "XFapiInteractionId": {
        "name": "x-fapi-interaction-id",
        "in": "header",
        "required": false,
        "description": "RFC4122 UUID used as a correlation ID. If provided, the server MUST echo it in the response x-fapi-interaction-id header. If not provided, the server MUST generate a fresh UUID.",
        "schema": {
          "type": "string",
          "format": "uuid",
          "example": "550e8400-e29b-41d4-a716-446655440000"
        }
      },
      "XFapiCustomerIpAddress": {
        "name": "x-fapi-customer-ip-address",
        "in": "header",
        "required": false,
        "description": "The PSU's IP address if the PSU is currently logged in with the TPP.",
        "schema": {
          "type": "string",
          "format": "ipv4",
          "example": "104.10.10.1"
        }
      },
      "XFapiAuthDate": {
        "name": "x-fapi-auth-date",
        "in": "header",
        "required": false,
        "description": "The time when the PSU last logged in with the TPP. RFC7231 HTTP-date format.",
        "schema": {
          "type": "string",
          "example": "Tue, 11 Sep 2024 08:42:00 UTC"
        }
      },
      "PageParam": {
        "name": "page",
        "in": "query",
        "required": false,
        "description": "Page number (1-based). Defaults to 1.",
        "schema": {
          "type": "integer",
          "minimum": 1,
          "default": 1,
          "example": 1
        }
      },
      "LimitParam": {
        "name": "limit",
        "in": "query",
        "required": false,
        "description": "Number of items per page. Maximum 100. Defaults to 20.",
        "schema": {
          "type": "integer",
          "minimum": 1,
          "maximum": 100,
          "default": 20,
          "example": 20
        }
      },
      "CursorParam": {
        "name": "cursor",
        "in": "query",
        "required": false,
        "description": "Opaque cursor from a previous response for cursor-based pagination. Mutually exclusive with page.",
        "schema": {
          "type": "string",
          "example": "eyJpZCI6IjEyMyJ9"
        }
      },
      "StartingAfter": {
        "name": "starting_after",
        "in": "query",
        "required": false,
        "description": "Cursor for pagination. Returns results immediately after the supplied object id. Mutually exclusive with `ending_before`. Offset-style `offset` is also accepted for backward compatibility.",
        "schema": {
          "type": "string",
          "maxLength": 128
        }
      },
      "EndingBefore": {
        "name": "ending_before",
        "in": "query",
        "required": false,
        "description": "Cursor for pagination. Returns results immediately before the supplied object id. Mutually exclusive with `starting_after`.",
        "schema": {
          "type": "string",
          "maxLength": 128
        }
      },
      "RequestId": {
        "name": "X-Request-ID",
        "in": "header",
        "required": false,
        "description": "Client-supplied correlation id (UUID v4 recommended). Echoed back in the `X-Request-ID` response header and persisted across edge functions, ledger writes and outbound webhook deliveries for distributed tracing.",
        "schema": {
          "type": "string",
          "maxLength": 64,
          "pattern": "^[A-Za-z0-9._-]{1,64}$"
        }
      },
      "BudgetingLangQuery": {
        "name": "lang",
        "in": "query",
        "required": false,
        "schema": {
          "type": "string",
          "enum": [
            "en",
            "fr",
            "pid"
          ],
          "default": "en"
        },
        "description": "Response language for budgeting insights."
      },
      "Traceparent": {
        "name": "traceparent",
        "in": "header",
        "required": false,
        "description": "W3C Trace Context Level 2 traceparent header. When supplied, KOB propagates the same context to every upstream call (bank connectors, mobile-money providers, settlement workers) and emits the resulting span IDs to OTLP collectors. See https://www.w3.org/TR/trace-context/",
        "schema": {
          "type": "string",
          "pattern": "^[0-9a-f]{2}-[0-9a-f]{32}-[0-9a-f]{16}-[0-9a-f]{2}$",
          "maxLength": 55
        },
        "example": "00-0af7651916cd43dd8448eb211c80319c-b7ad6b7169203331-01"
      },
      "Tracestate": {
        "name": "tracestate",
        "in": "header",
        "required": false,
        "description": "W3C Trace Context Level 2 tracestate header. Vendor-specific trace data, propagated unchanged.",
        "schema": {
          "type": "string",
          "maxLength": 512
        },
        "example": "kob=req:abc123,partner=acme"
      },
      "AcceptLanguage": {
        "name": "Accept-Language",
        "in": "header",
        "required": false,
        "description": "BCP 47 language tag(s) for response localisation. Supported: `en`, `en-CM`, `en-GB`, `fr`, `fr-CM`. Defaults to `en` when omitted. RFC 7807 `ProblemDetails.detail` and `title` are translated when a French tag is supplied.",
        "schema": {
          "type": "string",
          "example": "fr-CM",
          "pattern": "^[A-Za-z]{2,3}(-[A-Za-z]{2})?(,[A-Za-z]{2,3}(-[A-Za-z]{2})?(;q=0\\.[0-9]+)?)*$"
        }
      },
      "IdempotencyKeyHeader": {
        "name": "Idempotency-Key",
        "in": "header",
        "required": false,
        "schema": {
          "type": "string",
          "format": "uuid",
          "pattern": "^[0-9a-f]{8}-[0-9a-f]{4}-4[0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}$",
          "maxLength": 255
        },
        "description": "Optional UUID v4 idempotency key (draft-ietf-httpapi-idempotency-key-header §2). When supplied, KOB scopes the key by tenant + route + method and replays the original response for identical retries, returns 409 IDEMPOTENCY_KEY_REUSED for the same key with a different request body, and returns 409 IDEMPOTENCY_REQUEST_IN_PROGRESS for concurrent duplicates. Retention: 24h. Existing v1 clients that omit the header retain prior behaviour (Phase 1B backward-compatible additive rollout)."
      },
      "WebhookSignatureV2Header": {
        "name": "X-Webhook-Signature",
        "in": "header",
        "required": true,
        "description": "Webhooks v2 signature in the form `t=<unix-seconds>,v1=<hex>`. `v1` is the lowercase hex HMAC-SHA256 of the string `<t>.<raw request body>` keyed with the endpoint signing secret. Compare with a constant-time function and reject the request when `|now - t| > 300` seconds. Endpoints registered through the deprecated v1 webhook operations receive a raw lowercase hex HMAC-SHA256 of the body in this header instead.",
        "schema": {
          "type": "string",
          "example": "t=1760000000,v1=5257a869e7ecebeda32affa62cdca3fa51cad7e77a0e56ff536d0ce8e108d8bd"
        }
      },
      "WebhookTimestampHeader": {
        "name": "X-Webhook-Timestamp",
        "in": "header",
        "required": true,
        "description": "Unix time in seconds at which the delivery was signed. Equal to `t` in `X-Webhook-Signature`; part of the signed string.",
        "schema": {
          "type": "string",
          "pattern": "^[0-9]{10}$",
          "example": "1760000000"
        }
      },
      "WebhookIdHeader": {
        "name": "X-Webhook-ID",
        "in": "header",
        "required": true,
        "description": "Unique identifier of this delivery attempt (UUID). A new value is issued for each attempt, so it identifies the delivery, not the business event. Use `X-Webhook-Event-ID` for deduplication.",
        "schema": {
          "type": "string",
          "format": "uuid"
        }
      },
      "WebhookEventIdHeader": {
        "name": "X-Webhook-Event-ID",
        "in": "header",
        "required": false,
        "description": "Stable identifier of the logical event (UUID), generated server-side when the event is dispatched and identical on every retry and on every subscribed endpoint. Equal to `event_id` in the body. Store it for at least the retry horizon (about 72 hours) and acknowledge duplicates with 2xx without reprocessing. Absent only on retries of deliveries created before release 4.54.1.",
        "schema": {
          "type": "string",
          "format": "uuid"
        }
      },
      "WebhookEventHeader": {
        "name": "X-Webhook-Event",
        "in": "header",
        "required": true,
        "description": "Event type, identical to the `event` field in the body.",
        "schema": {
          "type": "string",
          "example": "charge.succeeded"
        }
      },
      "WebhookSignatureLegacyHeader": {
        "name": "X-Webhook-Signature-Legacy",
        "in": "header",
        "required": false,
        "description": "Deprecated. Lowercase hex HMAC-SHA256 of the raw body without a timestamp, sent alongside the v2 signature for receivers that have not migrated. Scheduled for removal in API v5.0.0. Do not rely on it for replay protection.",
        "schema": {
          "type": "string"
        }
      }
    },
    "headers": {
      "XFapiInteractionIdResponse": {
        "description": "RFC4122 UUID echoing the request x-fapi-interaction-id or a server-generated UUID if not provided in the request.",
        "required": true,
        "schema": {
          "type": "string",
          "format": "uuid",
          "example": "550e8400-e29b-41d4-a716-446655440000"
        }
      },
      "XRateLimitLimit": {
        "description": "The maximum number of requests allowed in the current rate limit window.",
        "schema": {
          "type": "integer",
          "example": 1000
        }
      },
      "XRateLimitRemaining": {
        "description": "The number of requests remaining in the current rate limit window.",
        "schema": {
          "type": "integer",
          "example": 995
        }
      },
      "XRateLimitReset": {
        "description": "UTC epoch seconds when the current rate limit window resets.",
        "schema": {
          "type": "integer",
          "example": 1743081600
        }
      },
      "RetryAfter": {
        "description": "Number of seconds to wait before retrying after a 429 Too Many Requests response. Implement exponential backoff with jitter starting from this value.",
        "schema": {
          "type": "integer",
          "example": 30
        }
      },
      "CacheControl": {
        "description": "Directives for caching mechanisms. For mutable data (balances, transactions): `no-cache`. For semi-static data (bank directory, exchange rates): `max-age=300, must-revalidate`.",
        "required": true,
        "schema": {
          "type": "string",
          "example": "max-age=300, must-revalidate"
        }
      },
      "ETag": {
        "description": "Entity tag for conditional requests. Use with `If-None-Match` on subsequent requests to receive 304 Not Modified when data has not changed.",
        "required": true,
        "schema": {
          "type": "string",
          "example": "\"v1-abc123def456\""
        }
      },
      "LastModified": {
        "description": "Timestamp of last data modification. Use with `If-Modified-Since` for conditional polling.",
        "required": false,
        "schema": {
          "type": "string",
          "format": "date-time",
          "example": "Sat, 22 Mar 2026 10:00:00 GMT"
        }
      },
      "IdempotencyKey": {
        "description": "A unique UUID (v4) identifying this request for safe retries. Keys are retained for **24 hours** after the first request. Reusing a key with identical parameters returns the cached response. Reusing a key with different parameters returns 409 Conflict. Required on all money-moving POST endpoints.",
        "required": true,
        "schema": {
          "type": "string",
          "format": "uuid",
          "example": "550e8400-e29b-41d4-a716-446655440000",
          "pattern": "^[0-9a-f]{8}-[0-9a-f]{4}-4[0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}$",
          "maxLength": 255
        }
      },
      "X-RateLimit-Limit": {
        "description": "Maximum number of requests allowed in the current window",
        "schema": {
          "type": "integer",
          "example": 1000
        }
      },
      "X-RateLimit-Remaining": {
        "description": "Number of requests remaining in the current window",
        "schema": {
          "type": "integer",
          "example": 847
        }
      },
      "X-RateLimit-Reset": {
        "description": "Unix timestamp when the rate limit window resets",
        "schema": {
          "type": "integer",
          "example": 1709290800
        }
      },
      "Retry-After": {
        "description": "Seconds to wait before retrying (only on 429 responses)",
        "schema": {
          "type": "integer",
          "example": 30
        }
      },
      "XFapiInteractionId": {
        "description": "FAPI 1.0 §6.2.1.13 — server echoes (or generates) a UUID v4 correlation ID so callers can pin a single request across logs and audits.",
        "schema": {
          "type": "string",
          "format": "uuid"
        }
      },
      "X-Webhook-Replay": {
        "description": "Set to `true` when the event is a manual replay from the DLQ or operator console.",
        "schema": {
          "type": "boolean"
        }
      },
      "X-Webhook-Replay-Of": {
        "description": "UUID of the original delivery being replayed. Only present when `X-Webhook-Replay: true`.",
        "schema": {
          "type": "string",
          "format": "uuid"
        }
      },
      "X-Circuit-State": {
        "description": "Current circuit-breaker state for the receiving endpoint (`closed`, `half_open`, `open`). Echoed on every webhook attempt so receivers can self-throttle.",
        "schema": {
          "type": "string",
          "enum": [
            "closed",
            "half_open",
            "open"
          ]
        }
      },
      "X-Idempotent-Replay": {
        "description": "Set to `true` when the response was served from the idempotency cache for a replayed request (Stripe API Reference §Idempotent Requests).",
        "schema": {
          "type": "boolean"
        }
      },
      "X-Idempotency-Status": {
        "description": "Idempotency outcome: `first_request` (new key, normal processing), `replayed` (cached response served), `conflict_rejected` (same key reused with different payload — 409).",
        "schema": {
          "type": "string",
          "enum": [
            "first_request",
            "replayed",
            "conflict_rejected"
          ]
        }
      },
      "X-Webhook-Signature": {
        "description": "HMAC-SHA256 webhook signature. Format `t=<unix_ts>,v1=<hex>` per Stripe webhook signing convention. Receivers MUST reject deliveries where `|now - t| > 300s` (OWASP Webhook Security Cheat Sheet).",
        "schema": {
          "type": "string",
          "pattern": "^t=\\d{10},v1=[0-9a-f]{64}$",
          "example": "t=1716998400,v1=5257a869e7ecebeda32affa62cdca3fa51cad7e77a0e56ff536d0ce8e108d8bd"
        }
      },
      "X-Webhook-Timestamp": {
        "description": "Unix timestamp (seconds) of webhook signature generation. Use to compute and verify replay-protection window.",
        "schema": {
          "type": "integer",
          "format": "int64",
          "example": 1716998400
        }
      },
      "X-Webhook-Signature-Legacy": {
        "description": "Deprecated. Raw HMAC-SHA256 hex of the body without timestamp prefix. Emitted in parallel during the 4.42.0 deprecation window for receivers that have not yet adopted the timestamped signature. Will be removed in v5.0.0.",
        "deprecated": true,
        "schema": {
          "type": "string",
          "pattern": "^[0-9a-f]{64}$"
        }
      },
      "Traceparent": {
        "description": "Echoed W3C traceparent (Trace Context Level 2). Always returned to support distributed correlation.",
        "schema": {
          "type": "string",
          "pattern": "^[0-9a-f]{2}-[0-9a-f]{32}-[0-9a-f]{16}-[0-9a-f]{2}$"
        }
      },
      "X-Confirmation-Eta": {
        "description": "Server-estimated seconds until the underlying rail returns a terminal state. Echoes RtpSla.expected_completion_seconds for callers that prefer header-only signalling.",
        "schema": {
          "type": "integer",
          "minimum": 1,
          "maximum": 86400
        }
      },
      "Content-Language": {
        "description": "Language of the response body (BCP 47). Echoes the negotiated tag.",
        "schema": {
          "type": "string",
          "example": "fr"
        }
      },
      "Deprecation": {
        "description": "RFC 8594 Deprecation indicator. Date-time the resource was marked deprecated.",
        "schema": {
          "type": "string",
          "example": "Thu, 29 May 2026 00:00:00 GMT"
        }
      },
      "Sunset": {
        "description": "RFC 8594 Sunset header. Date-time the resource will be removed.",
        "schema": {
          "type": "string",
          "example": "Wed, 01 Jan 2027 00:00:00 GMT"
        }
      },
      "LinkSuccessor": {
        "description": "RFC 8288 Link header carrying rel=\"successor-version\" pointing to the replacement endpoint.",
        "schema": {
          "type": "string",
          "example": "<https://api.kangopenbanking.com/v1/verify/nin>; rel=\"successor-version\""
        }
      }
    },
    "responses": {
      "NotModified": {
        "description": "Resource has not been modified since the last request. Returned when `If-None-Match` matches the current `ETag` or `If-Modified-Since` is after `Last-Modified`.",
        "headers": {
          "ETag": {
            "$ref": "#/components/headers/ETag"
          },
          "Cache-Control": {
            "$ref": "#/components/headers/CacheControl"
          }
        }
      },
      "TooManyRequests": {
        "description": "Too Many Requests",
        "headers": {
          "X-RateLimit-Limit": {
            "$ref": "#/components/headers/X-RateLimit-Limit"
          },
          "X-RateLimit-Remaining": {
            "$ref": "#/components/headers/X-RateLimit-Remaining"
          },
          "X-RateLimit-Reset": {
            "$ref": "#/components/headers/X-RateLimit-Reset"
          },
          "Retry-After": {
            "$ref": "#/components/headers/Retry-After"
          }
        },
        "content": {
          "application/problem+json": {
            "schema": {
              "$ref": "#/components/schemas/RateLimitError"
            }
          }
        }
      },
      "Unauthorized": {
        "description": "401 Unauthorized",
        "headers": {},
        "content": {
          "application/problem+json": {
            "schema": {
              "$ref": "#/components/schemas/ProblemDetails"
            },
            "examples": {
              "default": {
                "$ref": "#/components/examples/ErrorUnauthorized"
              }
            }
          }
        }
      },
      "Forbidden": {
        "description": "403 Forbidden",
        "headers": {},
        "content": {
          "application/problem+json": {
            "schema": {
              "$ref": "#/components/schemas/ProblemDetails"
            },
            "examples": {
              "default": {
                "$ref": "#/components/examples/ErrorForbidden"
              }
            }
          }
        }
      },
      "Conflict": {
        "description": "409 Conflict",
        "headers": {},
        "content": {
          "application/problem+json": {
            "schema": {
              "$ref": "#/components/schemas/ProblemDetails"
            },
            "examples": {
              "default": {
                "$ref": "#/components/examples/ErrorConflict"
              }
            }
          }
        }
      },
      "BadRequest": {
        "description": "400 Bad Request",
        "headers": {},
        "content": {
          "application/problem+json": {
            "schema": {
              "$ref": "#/components/schemas/ProblemDetails"
            },
            "examples": {
              "default": {
                "$ref": "#/components/examples/ErrorBadRequest"
              }
            }
          }
        }
      },
      "NotFound": {
        "description": "404 Not Found",
        "headers": {},
        "content": {
          "application/problem+json": {
            "schema": {
              "$ref": "#/components/schemas/ProblemDetails"
            },
            "examples": {
              "default": {
                "$ref": "#/components/examples/ErrorNotFound"
              }
            }
          }
        }
      },
      "UnprocessableEntity": {
        "description": "422 Unprocessable Entity",
        "headers": {},
        "content": {
          "application/problem+json": {
            "schema": {
              "$ref": "#/components/schemas/ProblemDetails"
            },
            "examples": {
              "default": {
                "$ref": "#/components/examples/ErrorUnprocessable"
              }
            }
          }
        }
      },
      "InternalServerError": {
        "description": "500 Internal Server Error",
        "headers": {},
        "content": {
          "application/problem+json": {
            "schema": {
              "$ref": "#/components/schemas/ProblemDetails"
            },
            "examples": {
              "default": {
                "$ref": "#/components/examples/ErrorServer"
              }
            }
          }
        }
      },
      "ServiceUnavailable": {
        "description": "503 Service Unavailable",
        "headers": {},
        "content": {
          "application/problem+json": {
            "schema": {
              "$ref": "#/components/schemas/ProblemDetails"
            },
            "examples": {
              "default": {
                "$ref": "#/components/examples/ErrorUnavailable"
              }
            }
          }
        }
      }
    },
    "examples": {
      "GenericSuccess": {
        "summary": "Successful response envelope",
        "value": {
          "success": true,
          "data": {
            "id": "obj_01HZX9TRJ4M7YQK6P3W2VBDN5K",
            "object": "resource",
            "created_at": "2026-05-02T10:15:30Z"
          },
          "meta": {
            "request_id": "7d1f0a1c-2b4e-4f6a-9c3d-5e8f0a1b2c3d",
            "timestamp": "2026-05-02T10:15:30Z"
          }
        }
      },
      "PaginatedList": {
        "summary": "Cursor-paginated list",
        "value": {
          "success": true,
          "data": [
            {
              "id": "obj_01HZX9TRJ4M7YQK6P3W2VBDN5K",
              "object": "resource",
              "created_at": "2026-05-02T10:15:30Z"
            },
            {
              "id": "obj_01HZX9TRJ4M7YQK6P3W2VBDN5L",
              "object": "resource",
              "created_at": "2026-05-02T10:15:31Z"
            }
          ],
          "pagination": {
            "has_more": true,
            "next_cursor": "cursor_01HZX9TRJ4M7YQK6P3W2VBDN5M",
            "prev_cursor": null,
            "total_count": 247
          },
          "meta": {
            "request_id": "7d1f0a1c-2b4e-4f6a-9c3d-5e8f0a1b2c3d",
            "timestamp": "2026-05-02T10:15:30Z"
          }
        }
      },
      "ErrorBadRequest": {
        "summary": "400 Bad Request",
        "value": {
          "type": "https://docs.kangopenbanking.com/errors/invalid_request",
          "title": "Bad Request",
          "status": 400,
          "code": "invalid_request",
          "detail": "The request body failed validation. See errors[] for field-level detail.",
          "instance": "/v1/resource/01HZX9TRJ4M7YQK6P3W2VBDN5K",
          "request_id": "req_01HZX9TRJ4M7YQK6P3W2VBDN5K",
          "timestamp": "2026-05-02T10:15:30Z"
        }
      },
      "ErrorUnauthorized": {
        "summary": "401 Unauthorized",
        "value": {
          "type": "https://docs.kangopenbanking.com/errors/invalid_credentials",
          "title": "Unauthorized",
          "status": 401,
          "code": "invalid_credentials",
          "detail": "Missing or invalid bearer token. Authenticate at /v1/oauth/token.",
          "instance": "/v1/resource/01HZX9TRJ4M7YQK6P3W2VBDN5K",
          "request_id": "req_01HZX9TRJ4M7YQK6P3W2VBDN5K",
          "timestamp": "2026-05-02T10:15:30Z"
        }
      },
      "ErrorForbidden": {
        "summary": "403 Forbidden",
        "value": {
          "type": "https://docs.kangopenbanking.com/errors/insufficient_scope",
          "title": "Forbidden",
          "status": 403,
          "code": "insufficient_scope",
          "detail": "The access token is missing the required scope for this operation.",
          "instance": "/v1/resource/01HZX9TRJ4M7YQK6P3W2VBDN5K",
          "request_id": "req_01HZX9TRJ4M7YQK6P3W2VBDN5K",
          "timestamp": "2026-05-02T10:15:30Z"
        }
      },
      "ErrorNotFound": {
        "summary": "404 Not Found",
        "value": {
          "type": "https://docs.kangopenbanking.com/errors/resource_not_found",
          "title": "Not Found",
          "status": 404,
          "code": "resource_not_found",
          "detail": "The requested resource does not exist or has been archived.",
          "instance": "/v1/resource/01HZX9TRJ4M7YQK6P3W2VBDN5K",
          "request_id": "req_01HZX9TRJ4M7YQK6P3W2VBDN5K",
          "timestamp": "2026-05-02T10:15:30Z"
        }
      },
      "ErrorConflict": {
        "summary": "409 Conflict",
        "value": {
          "type": "https://docs.kangopenbanking.com/errors/idempotency_conflict",
          "title": "Conflict",
          "status": 409,
          "code": "idempotency_conflict",
          "detail": "Idempotency-Key was reused with a different request body.",
          "instance": "/v1/resource/01HZX9TRJ4M7YQK6P3W2VBDN5K",
          "request_id": "req_01HZX9TRJ4M7YQK6P3W2VBDN5K",
          "timestamp": "2026-05-02T10:15:30Z"
        }
      },
      "ErrorUnprocessable": {
        "summary": "422 Unprocessable Entity",
        "value": {
          "type": "https://docs.kangopenbanking.com/errors/business_rule_violation",
          "title": "Unprocessable Entity",
          "status": 422,
          "code": "business_rule_violation",
          "detail": "The request was syntactically valid but violates a business rule (e.g. insufficient funds).",
          "instance": "/v1/resource/01HZX9TRJ4M7YQK6P3W2VBDN5K",
          "request_id": "req_01HZX9TRJ4M7YQK6P3W2VBDN5K",
          "timestamp": "2026-05-02T10:15:30Z"
        }
      },
      "ErrorRateLimited": {
        "summary": "429 Too Many Requests",
        "value": {
          "type": "https://docs.kangopenbanking.com/errors/rate_limited",
          "title": "Too Many Requests",
          "status": 429,
          "code": "rate_limited",
          "detail": "Request quota exceeded. Retry after the period indicated by Retry-After.",
          "instance": "https://api.kangopenbanking.com/v1/resource/01HZX9TRJ4M7YQK6P3W2VBDN5K",
          "request_id": "7d1f0a1c-2b4e-4f6a-9c3d-5e8f0a1b2c3d",
          "timestamp": "2026-05-02T10:15:30Z"
        }
      },
      "ErrorServer": {
        "summary": "500 Internal Server Error",
        "value": {
          "type": "https://docs.kangopenbanking.com/errors/internal_error",
          "title": "Internal Server Error",
          "status": 500,
          "code": "internal_error",
          "detail": "An unexpected error occurred. The incident has been logged with request_id.",
          "instance": "/v1/resource/01HZX9TRJ4M7YQK6P3W2VBDN5K",
          "request_id": "req_01HZX9TRJ4M7YQK6P3W2VBDN5K",
          "timestamp": "2026-05-02T10:15:30Z"
        }
      },
      "ErrorUnavailable": {
        "summary": "503 Service Unavailable",
        "value": {
          "type": "https://docs.kangopenbanking.com/errors/service_unavailable",
          "title": "Service Unavailable",
          "status": 503,
          "code": "service_unavailable",
          "detail": "A downstream dependency is temporarily unavailable. Retry with exponential backoff.",
          "instance": "/v1/resource/01HZX9TRJ4M7YQK6P3W2VBDN5K",
          "request_id": "req_01HZX9TRJ4M7YQK6P3W2VBDN5K",
          "timestamp": "2026-05-02T10:15:30Z"
        }
      },
      "PaymentIntentCreated": {
        "summary": "Payment intent created",
        "value": {
          "success": true,
          "data": {
            "id": "pi_01HZX9TRJ4M7YQK6P3W2VBDN5K",
            "object": "payment_intent",
            "amount": "5000",
            "currency": "XAF",
            "status": "requires_confirmation",
            "client_secret": "pi_01HZX9TRJ4M7YQK6P3W2VBDN5K_secret_aBc123",
            "payment_method_types": [
              "mobile_money",
              "card",
              "bank_transfer"
            ],
            "idempotency_key": "550e8400-e29b-41d4-a716-446655440000",
            "created_at": "2026-05-02T10:15:30Z"
          },
          "meta": {
            "request_id": "7d1f0a1c-2b4e-4f6a-9c3d-5e8f0a1b2c3d",
            "timestamp": "2026-05-02T10:15:30Z"
          }
        }
      },
      "AccountBalance": {
        "summary": "Account balance snapshot",
        "value": {
          "success": true,
          "data": {
            "account_id": "acc_01HZX9TRJ4M7YQK6P3W2VBDN5K",
            "currency": "XAF",
            "balances": [
              {
                "type": "ClosingAvailable",
                "amount": "125000",
                "credit_debit_indicator": "Credit",
                "datetime": "2026-05-02T10:15:30Z"
              },
              {
                "type": "ClosingBooked",
                "amount": "130000",
                "credit_debit_indicator": "Credit",
                "datetime": "2026-05-02T10:15:30Z"
              }
            ]
          },
          "meta": {
            "request_id": "7d1f0a1c-2b4e-4f6a-9c3d-5e8f0a1b2c3d",
            "timestamp": "2026-05-02T10:15:30Z"
          }
        }
      },
      "ProblemDetailsConflict": {
        "summary": "RFC 7807 — idempotency key reused with different payload (409)",
        "value": {
          "type": "https://api.kangopenbanking.com/errors/idempotency-key-reused",
          "title": "Idempotency Key Conflict",
          "status": 409,
          "detail": "The provided Idempotency-Key was previously used with a different request body.",
          "instance": "/v1/gateway/charges",
          "error_id": "err_idem_a1b2c3",
          "timestamp": "2026-05-29T10:00:00Z"
        }
      },
      "ProblemDetailsValidation": {
        "summary": "RFC 7807 — request body validation error (422)",
        "value": {
          "type": "https://api.kangopenbanking.com/errors/validation",
          "title": "Unprocessable Entity",
          "status": 422,
          "detail": "One or more request fields failed validation.",
          "instance": "/v1/gateway/charges",
          "error_id": "err_val_d4e5f6",
          "timestamp": "2026-05-29T10:00:00Z",
          "errors": [
            {
              "field": "amount",
              "code": "GW_001",
              "message": "Amount must be > 0"
            },
            {
              "field": "currency",
              "code": "GW_002",
              "message": "Unsupported currency 'USX'"
            }
          ]
        }
      },
      "ProblemDetailsRateLimited": {
        "summary": "RFC 7807 — rate limit exceeded (429)",
        "value": {
          "type": "https://api.kangopenbanking.com/errors/rate-limited",
          "title": "Too Many Requests",
          "status": 429,
          "detail": "Request rate exceeded for the merchant's current tier.",
          "instance": "/v1/gateway/charges",
          "error_id": "err_rl_g7h8i9",
          "timestamp": "2026-05-29T10:00:00Z",
          "retry_after": 30
        }
      },
      "MobileMoneyInsufficientFunds": {
        "summary": "Provider declined for insufficient funds",
        "value": {
          "provider": "mtn",
          "raw_code": "NOT_ENOUGH_FUNDS",
          "raw_message": "Subscriber balance too low",
          "normalized_code": "insufficient_funds",
          "retryable": false
        }
      },
      "ProblemDetailsSystemCategoryProtected": {
        "summary": "Protected system category cannot be soft-deleted",
        "value": {
          "type": "https://api.kangopenbanking.com/errors/system-category-protected",
          "title": "System Category Protected",
          "status": 409,
          "detail": "The requested category is a system-managed category and cannot be soft-deleted.",
          "instance": "https://api.kangopenbanking.com/v1/budgeting/categories/00000000-0000-4000-8000-000000000000",
          "code": "SYSTEM_CATEGORY_PROTECTED",
          "error_id": "err_syscat_a1b2c3",
          "timestamp": "2026-07-16T10:00:00Z"
        }
      },
      "ProblemDetailsCategoryActiveDependencies": {
        "summary": "Category has active dependencies preventing soft-deletion",
        "value": {
          "type": "https://api.kangopenbanking.com/errors/category-has-active-dependencies",
          "title": "Category Has Active Dependencies",
          "status": 409,
          "detail": "The category cannot be soft-deleted because active dependent resources still reference it.",
          "instance": "https://api.kangopenbanking.com/v1/budgeting/categories/00000000-0000-4000-8000-000000000000",
          "code": "CATEGORY_HAS_ACTIVE_DEPENDENCIES",
          "error_id": "err_catdep_a1b2c3",
          "timestamp": "2026-07-16T10:00:00Z"
        }
      },
      "ProblemDetailsIdempotencyKeyReused": {
        "summary": "Idempotency key reused with a different request body",
        "value": {
          "type": "https://api.kangopenbanking.com/errors/idempotency-key-reused",
          "title": "Idempotency Key Conflict",
          "status": 409,
          "detail": "The provided Idempotency-Key was previously used with a different request body.",
          "instance": "https://api.kangopenbanking.com/v1/budgeting/budgets/00000000-0000-4000-8000-000000000000",
          "code": "IDEMPOTENCY_KEY_REUSED",
          "error_id": "err_idem_a1b2c3",
          "timestamp": "2026-07-16T10:00:00Z"
        }
      },
      "ProblemDetailsInvalidIdempotencyKey": {
        "summary": "Malformed Idempotency-Key header",
        "value": {
          "type": "https://api.kangopenbanking.com/errors/invalid-idempotency-key",
          "title": "Invalid Idempotency Key",
          "status": 400,
          "detail": "The Idempotency-Key header value is not a valid UUID v4.",
          "instance": "https://api.kangopenbanking.com/v1/budgeting/budgets/00000000-0000-4000-8000-000000000000",
          "code": "INVALID_IDEMPOTENCY_KEY",
          "error_id": "err_iik_a1b2c3",
          "timestamp": "2026-07-16T10:00:00Z"
        }
      },
      "ProblemDetailsGoalHasPendingFinancialOperations": {
        "summary": "Goal has unresolved financial operations and cannot be archived",
        "value": {
          "type": "https://api.kangopenbanking.com/errors/goal-has-pending-financial-operations",
          "title": "Goal Has Pending Financial Operations",
          "status": 409,
          "detail": "The savings goal cannot be archived while it has unresolved contributions, transfers, settlements, payment instructions or round-up instructions.",
          "instance": "https://api.kangopenbanking.com/v1/budgeting/goals/00000000-0000-4000-8000-000000000000",
          "code": "GOAL_HAS_PENDING_FINANCIAL_OPERATIONS",
          "error_id": "err_goalpend_a1b2c3",
          "timestamp": "2026-07-16T10:00:00Z"
        }
      },
      "ProblemDetailsGoalStateConflict": {
        "summary": "Goal lifecycle state does not permit archival",
        "value": {
          "type": "https://api.kangopenbanking.com/errors/goal-state-conflict",
          "title": "Goal State Conflict",
          "status": 409,
          "detail": "The savings goal is in a lifecycle state that does not permit archival.",
          "instance": "https://api.kangopenbanking.com/v1/budgeting/goals/00000000-0000-4000-8000-000000000000",
          "code": "GOAL_STATE_CONFLICT",
          "error_id": "err_goalstate_a1b2c3",
          "timestamp": "2026-07-16T10:00:00Z"
        }
      },
      "ProblemDetailsRoundupHasPendingInstructions": {
        "summary": "Round-up has pending instructions preventing disablement",
        "value": {
          "type": "https://api.kangopenbanking.com/errors/roundup-has-pending-instructions",
          "title": "Round-Up Has Pending Instructions",
          "status": 409,
          "detail": "Round-up cannot be disabled while pending round-up instructions remain unresolved.",
          "instance": "https://api.kangopenbanking.com/v1/budgeting/goals/00000000-0000-4000-8000-000000000000/round-up",
          "code": "ROUNDUP_HAS_PENDING_INSTRUCTIONS",
          "error_id": "err_ruspend_a1b2c3",
          "timestamp": "2026-07-16T10:00:00Z"
        }
      },
      "ProblemDetailsRoundupStateConflict": {
        "summary": "Round-up configuration is in a state that cannot be disabled immediately",
        "value": {
          "type": "https://api.kangopenbanking.com/errors/roundup-state-conflict",
          "title": "Round-Up State Conflict",
          "status": 409,
          "detail": "Round-up cannot be disabled from its current state.",
          "instance": "https://api.kangopenbanking.com/v1/budgeting/goals/00000000-0000-4000-8000-000000000000/round-up",
          "code": "ROUNDUP_STATE_CONFLICT",
          "error_id": "err_rustate_a1b2c3",
          "timestamp": "2026-07-16T10:00:00Z"
        }
      }
    }
  },
  "paths": {
    "/v1/health": {
      "get": {
        "tags": [
          "Monitoring"
        ],
        "summary": "API health check",
        "operationId": "apiHealth",
        "security": [],
        "responses": {
          "200": {
            "description": "API is healthy",
            "content": {
              "application/json": {
                "schema": {
                  "allOf": [
                    {
                      "$ref": "#/components/schemas/StandardResponse"
                    },
                    {
                      "type": "object",
                      "properties": {
                        "data": {
                          "$ref": "#/components/schemas/HealthStatus"
                        }
                      }
                    }
                  ]
                },
                "example": {
                  "data": {
                    "status": "healthy",
                    "version": "1.0.0",
                    "timestamp": "2026-01-01T00:00:00Z",
                    "services": {}
                  },
                  "meta": {
                    "request_id": "550e8400-e29b-41d4-a716-446655440000",
                    "timestamp": "2025-03-27T12:00:00Z",
                    "api_version": "4.3.0"
                  }
                }
              }
            },
            "headers": {
              "x-fapi-interaction-id": {
                "$ref": "#/components/headers/XFapiInteractionIdResponse"
              },
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/XRateLimitLimit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/XRateLimitRemaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/XRateLimitReset"
              },
              "Cache-Control": {
                "$ref": "#/components/headers/CacheControl"
              },
              "ETag": {
                "$ref": "#/components/headers/ETag"
              },
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              },
              "traceparent": {
                "$ref": "#/components/headers/Traceparent"
              },
              "Content-Language": {
                "$ref": "#/components/headers/Content-Language"
              }
            }
          },
          "429": {
            "$ref": "#/components/responses/TooManyRequests",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "503": {
            "$ref": "#/components/responses/ServiceUnavailable",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          }
        },
        "parameters": [
          {
            "$ref": "#/components/parameters/RequestId"
          },
          {
            "$ref": "#/components/parameters/Traceparent"
          },
          {
            "$ref": "#/components/parameters/Tracestate"
          },
          {
            "$ref": "#/components/parameters/AcceptLanguage"
          }
        ],
        "x-codeSamples": [
          {
            "lang": "cURL",
            "label": "cURL",
            "source": "curl -X GET \"https://api.kangopenbanking.com/v1/health\" \\\n  -H \"Authorization: Bearer $KOB_ACCESS_TOKEN\" \\\n  -H \"Content-Type: application/json\""
          },
          {
            "lang": "JavaScript",
            "label": "Node.js",
            "source": "import { KangOpenBanking } from \"@kangopenbanking/sdk\";\n\nconst kob = new KangOpenBanking({ apiKey: process.env.KOB_API_KEY });\nconst res = await kob.request(\"GET\", \"/v1/health\");\nconsole.log(res);"
          },
          {
            "lang": "Python",
            "label": "Python",
            "source": "from kangopenbanking import KangOpenBanking\n\nkob = KangOpenBanking(api_key=os.environ[\"KOB_API_KEY\"])\nres = kob.request(\"GET\", \"/v1/health\")\nprint(res)"
          },
          {
            "lang": "PHP",
            "label": "PHP",
            "source": "<?php\n$kob = new KangOpenBanking\\KangOpenBanking(getenv('KOB_API_KEY'));\n$res = $kob->request('GET', '/v1/health');\nprint_r($res);"
          }
        ]
      }
    },
    "/v1/ready": {
      "get": {
        "tags": [
          "Monitoring"
        ],
        "summary": "Readiness probe",
        "description": "Returns 200 when the API is ready to accept traffic. Checks database connectivity.",
        "operationId": "apiReady",
        "security": [],
        "responses": {
          "200": {
            "description": "Ready",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "ready": {
                      "type": "boolean"
                    },
                    "db": {
                      "type": "string"
                    },
                    "timestamp": {
                      "type": "string",
                      "format": "date-time"
                    }
                  }
                },
                "example": {
                  "ready": true,
                  "db": "string",
                  "timestamp": "2026-01-01T00:00:00Z"
                }
              }
            },
            "headers": {
              "x-fapi-interaction-id": {
                "$ref": "#/components/headers/XFapiInteractionIdResponse"
              },
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/XRateLimitLimit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/XRateLimitRemaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/XRateLimitReset"
              },
              "Cache-Control": {
                "$ref": "#/components/headers/CacheControl"
              },
              "ETag": {
                "$ref": "#/components/headers/ETag"
              },
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              },
              "traceparent": {
                "$ref": "#/components/headers/Traceparent"
              },
              "Content-Language": {
                "$ref": "#/components/headers/Content-Language"
              }
            }
          },
          "429": {
            "$ref": "#/components/responses/TooManyRequests",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "503": {
            "$ref": "#/components/responses/ServiceUnavailable",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          }
        },
        "parameters": [
          {
            "$ref": "#/components/parameters/RequestId"
          },
          {
            "$ref": "#/components/parameters/Traceparent"
          },
          {
            "$ref": "#/components/parameters/Tracestate"
          },
          {
            "$ref": "#/components/parameters/AcceptLanguage"
          }
        ],
        "x-codeSamples": [
          {
            "lang": "cURL",
            "label": "cURL",
            "source": "curl -X GET \"https://api.kangopenbanking.com/v1/ready\" \\\n  -H \"Authorization: Bearer $KOB_ACCESS_TOKEN\" \\\n  -H \"Content-Type: application/json\""
          },
          {
            "lang": "JavaScript",
            "label": "Node.js",
            "source": "import { KangOpenBanking } from \"@kangopenbanking/sdk\";\n\nconst kob = new KangOpenBanking({ apiKey: process.env.KOB_API_KEY });\nconst res = await kob.request(\"GET\", \"/v1/ready\");\nconsole.log(res);"
          },
          {
            "lang": "Python",
            "label": "Python",
            "source": "from kangopenbanking import KangOpenBanking\n\nkob = KangOpenBanking(api_key=os.environ[\"KOB_API_KEY\"])\nres = kob.request(\"GET\", \"/v1/ready\")\nprint(res)"
          },
          {
            "lang": "PHP",
            "label": "PHP",
            "source": "<?php\n$kob = new KangOpenBanking\\KangOpenBanking(getenv('KOB_API_KEY'));\n$res = $kob->request('GET', '/v1/ready');\nprint_r($res);"
          }
        ]
      }
    },
    "/v1/system-health": {
      "get": {
        "tags": [
          "Monitoring"
        ],
        "summary": "Detailed system health",
        "operationId": "systemHealth",
        "security": [
          {
            "bearerAuth": []
          }
        ],
        "responses": {
          "200": {
            "description": "System health details",
            "content": {
              "application/json": {
                "schema": {
                  "allOf": [
                    {
                      "$ref": "#/components/schemas/StandardResponse"
                    },
                    {
                      "type": "object",
                      "properties": {
                        "data": {
                          "$ref": "#/components/schemas/HealthStatus"
                        }
                      }
                    }
                  ]
                },
                "example": {
                  "data": {
                    "status": "healthy",
                    "version": "1.0.0",
                    "timestamp": "2026-01-01T00:00:00Z",
                    "services": {}
                  },
                  "meta": {
                    "request_id": "550e8400-e29b-41d4-a716-446655440000",
                    "timestamp": "2025-03-27T12:00:00Z",
                    "api_version": "4.3.0"
                  }
                }
              }
            },
            "headers": {
              "x-fapi-interaction-id": {
                "$ref": "#/components/headers/XFapiInteractionIdResponse"
              },
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/XRateLimitLimit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/XRateLimitRemaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/XRateLimitReset"
              },
              "Cache-Control": {
                "$ref": "#/components/headers/CacheControl"
              },
              "ETag": {
                "$ref": "#/components/headers/ETag"
              },
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              },
              "traceparent": {
                "$ref": "#/components/headers/Traceparent"
              },
              "Content-Language": {
                "$ref": "#/components/headers/Content-Language"
              }
            }
          },
          "400": {
            "description": "Bad request",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              },
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                },
                "examples": {
                  "error": {
                    "$ref": "#/components/examples/ErrorBadRequest"
                  }
                }
              }
            },
            "headers": {
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/XRateLimitLimit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/XRateLimitRemaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/XRateLimitReset"
              },
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "403": {
            "$ref": "#/components/responses/Forbidden",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "404": {
            "$ref": "#/components/responses/NotFound",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "409": {
            "$ref": "#/components/responses/Conflict",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "429": {
            "$ref": "#/components/responses/TooManyRequests",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "500": {
            "$ref": "#/components/responses/InternalServerError",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          }
        },
        "parameters": [
          {
            "$ref": "#/components/parameters/RequestId"
          },
          {
            "$ref": "#/components/parameters/Traceparent"
          },
          {
            "$ref": "#/components/parameters/Tracestate"
          },
          {
            "$ref": "#/components/parameters/AcceptLanguage"
          }
        ],
        "x-codeSamples": [
          {
            "lang": "cURL",
            "label": "cURL",
            "source": "curl -X GET \"https://api.kangopenbanking.com/v1/system-health\" \\\n  -H \"Authorization: Bearer $KOB_ACCESS_TOKEN\" \\\n  -H \"Content-Type: application/json\""
          },
          {
            "lang": "JavaScript",
            "label": "Node.js",
            "source": "import { KangOpenBanking } from \"@kangopenbanking/sdk\";\n\nconst kob = new KangOpenBanking({ apiKey: process.env.KOB_API_KEY });\nconst res = await kob.request(\"GET\", \"/v1/system-health\");\nconsole.log(res);"
          },
          {
            "lang": "Python",
            "label": "Python",
            "source": "from kangopenbanking import KangOpenBanking\n\nkob = KangOpenBanking(api_key=os.environ[\"KOB_API_KEY\"])\nres = kob.request(\"GET\", \"/v1/system-health\")\nprint(res)"
          },
          {
            "lang": "PHP",
            "label": "PHP",
            "source": "<?php\n$kob = new KangOpenBanking\\KangOpenBanking(getenv('KOB_API_KEY'));\n$res = $kob->request('GET', '/v1/system-health');\nprint_r($res);"
          }
        ]
      }
    },
    "/v1/oauth/authorize": {
      "get": {
        "tags": [
          "OAuth"
        ],
        "summary": "Authorize OAuth request",
        "description": "Initiate OAuth 2.0 authorization flow with PKCE (FAPI 1.0 Advanced)",
        "operationId": "oauthAuthorize",
        "security": [],
        "parameters": [
          {
            "name": "response_type",
            "in": "query",
            "required": true,
            "schema": {
              "type": "string",
              "enum": [
                "code"
              ]
            }
          },
          {
            "name": "client_id",
            "in": "query",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "redirect_uri",
            "in": "query",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "scope",
            "in": "query",
            "required": true,
            "schema": {
              "type": "string"
            },
            "example": "openid accounts payments"
          },
          {
            "name": "state",
            "in": "query",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "code_challenge",
            "in": "query",
            "schema": {
              "type": "string"
            },
            "required": true,
            "description": "PKCE code challenge. The Base64URL-encoded SHA-256 hash of the code_verifier (S256 method). REQUIRED by FAPI 1.0 Advanced Section 5.2.2 for all authorization requests. The corresponding code_verifier must be provided at the token endpoint."
          },
          {
            "name": "code_challenge_method",
            "in": "query",
            "schema": {
              "type": "string",
              "enum": [
                "S256"
              ]
            },
            "required": true,
            "description": "PKCE code challenge method. MUST be S256 (SHA-256). Plain method is NOT supported per FAPI 1.0 Advanced security requirements."
          },
          {
            "name": "nonce",
            "in": "query",
            "required": true,
            "description": "Cryptographically random nonce value associating the client session with the ID Token and preventing replay attacks. REQUIRED by FAPI 1.0 Advanced Section 5.2.2-14 for all authorization requests. Must be unique per request with at least 128 bits of entropy (minimum 22 Base64url characters). The server MUST include the nonce claim in the issued ID Token.",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "request_uri",
            "in": "query",
            "required": false,
            "description": "FAPI 1.0 Advanced: URI referencing a Pushed Authorization Request (PAR). Mutually exclusive with request.",
            "schema": {
              "type": "string",
              "format": "uri"
            }
          },
          {
            "name": "request",
            "in": "query",
            "required": false,
            "description": "FAPI 1.0 Advanced: Signed JWT containing the authorization request parameters (Request Object). Mutually exclusive with request_uri.",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "acr_values",
            "in": "query",
            "required": false,
            "description": "Space-separated string of requested Authentication Context Class Reference values. e.g. \"urn:openbanking:psd2:sca\"",
            "schema": {
              "type": "string",
              "example": "urn:openbanking:psd2:sca"
            }
          },
          {
            "name": "claims",
            "in": "query",
            "required": false,
            "description": "JSON object requesting specific claims in the ID Token or UserInfo response (OIDC Core Section 5.5).",
            "schema": {
              "type": "string"
            }
          },
          {
            "$ref": "#/components/parameters/RequestId"
          },
          {
            "$ref": "#/components/parameters/Traceparent"
          },
          {
            "$ref": "#/components/parameters/Tracestate"
          },
          {
            "$ref": "#/components/parameters/AcceptLanguage"
          }
        ],
        "responses": {
          "302": {
            "description": "Redirect to authorization page",
            "headers": {
              "Location": {
                "schema": {
                  "type": "string",
                  "format": "uri"
                },
                "description": "Authorization page URL"
              },
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/XRateLimitLimit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/XRateLimitRemaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/XRateLimitReset"
              },
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "400": {
            "description": "Bad request",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              },
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                },
                "examples": {
                  "error": {
                    "$ref": "#/components/examples/ErrorBadRequest"
                  }
                }
              }
            },
            "headers": {
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/XRateLimitLimit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/XRateLimitRemaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/XRateLimitReset"
              },
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "403": {
            "$ref": "#/components/responses/Forbidden",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "404": {
            "$ref": "#/components/responses/NotFound",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "409": {
            "$ref": "#/components/responses/Conflict",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "429": {
            "$ref": "#/components/responses/TooManyRequests",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "500": {
            "$ref": "#/components/responses/InternalServerError",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          }
        },
        "x-codeSamples": [
          {
            "lang": "cURL",
            "label": "cURL",
            "source": "curl -X GET \"https://api.kangopenbanking.com/v1/oauth/authorize\" \\\n  -H \"Authorization: Bearer $KOB_ACCESS_TOKEN\" \\\n  -H \"Content-Type: application/json\""
          },
          {
            "lang": "JavaScript",
            "label": "Node.js",
            "source": "import { KangOpenBanking } from \"@kangopenbanking/sdk\";\n\nconst kob = new KangOpenBanking({ apiKey: process.env.KOB_API_KEY });\nconst res = await kob.request(\"GET\", \"/v1/oauth/authorize\");\nconsole.log(res);"
          },
          {
            "lang": "Python",
            "label": "Python",
            "source": "from kangopenbanking import KangOpenBanking\n\nkob = KangOpenBanking(api_key=os.environ[\"KOB_API_KEY\"])\nres = kob.request(\"GET\", \"/v1/oauth/authorize\")\nprint(res)"
          },
          {
            "lang": "PHP",
            "label": "PHP",
            "source": "<?php\n$kob = new KangOpenBanking\\KangOpenBanking(getenv('KOB_API_KEY'));\n$res = $kob->request('GET', '/v1/oauth/authorize');\nprint_r($res);"
          }
        ]
      }
    },
    "/v1/oauth/token": {
      "post": {
        "tags": [
          "OAuth"
        ],
        "summary": "Exchange authorization code for token",
        "operationId": "oauthToken",
        "security": [
          {},
          {
            "mtls": []
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/x-www-form-urlencoded": {
              "schema": {
                "type": "object",
                "required": [
                  "grant_type",
                  "client_id"
                ],
                "properties": {
                  "grant_type": {
                    "type": "string",
                    "enum": [
                      "authorization_code",
                      "refresh_token",
                      "client_credentials"
                    ],
                    "description": "OAuth 2.0 grant type"
                  },
                  "code": {
                    "type": "string",
                    "description": "Authorization code (required for authorization_code grant)"
                  },
                  "client_id": {
                    "type": "string"
                  },
                  "client_secret": {
                    "type": "string",
                    "description": "Client secret (required for client_credentials and refresh_token grants)"
                  },
                  "redirect_uri": {
                    "type": "string"
                  },
                  "code_verifier": {
                    "type": "string",
                    "description": "PKCE code verifier (required when code_challenge was used)"
                  },
                  "refresh_token": {
                    "type": "string",
                    "description": "Refresh token (required for refresh_token grant)"
                  },
                  "scope": {
                    "type": "string",
                    "description": "Space-delimited list of scopes (e.g. \"accounts payments\")",
                    "example": "accounts payments"
                  }
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Token issued",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "access_token": {
                      "type": "string"
                    },
                    "token_type": {
                      "type": "string",
                      "example": "Bearer"
                    },
                    "expires_in": {
                      "type": "integer",
                      "example": 3600
                    },
                    "refresh_token": {
                      "type": "string"
                    },
                    "scope": {
                      "type": "string",
                      "example": "openid accounts"
                    }
                  }
                },
                "example": {
                  "access_token": "eyJ...token",
                  "token_type": "Bearer",
                  "expires_in": 3600,
                  "refresh_token": "rf_abc123",
                  "scope": "openid accounts"
                }
              }
            },
            "headers": {
              "x-fapi-interaction-id": {
                "$ref": "#/components/headers/XFapiInteractionIdResponse"
              },
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/XRateLimitLimit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/XRateLimitRemaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/XRateLimitReset"
              },
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              },
              "traceparent": {
                "$ref": "#/components/headers/Traceparent"
              },
              "Content-Language": {
                "$ref": "#/components/headers/Content-Language"
              }
            }
          },
          "400": {
            "description": "Bad request",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              },
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                },
                "examples": {
                  "error": {
                    "$ref": "#/components/examples/ErrorBadRequest"
                  }
                }
              }
            },
            "headers": {
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/XRateLimitLimit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/XRateLimitRemaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/XRateLimitReset"
              },
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "403": {
            "$ref": "#/components/responses/Forbidden",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "404": {
            "$ref": "#/components/responses/NotFound",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "409": {
            "$ref": "#/components/responses/Conflict",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "429": {
            "$ref": "#/components/responses/TooManyRequests",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "500": {
            "$ref": "#/components/responses/InternalServerError",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          }
        },
        "description": "OAuth 2.0 Token Endpoint. Supports two client authentication modes: (1) Public clients using authorization_code + PKCE — no client authentication required, use an empty security context. (2) Confidential clients using mTLS (RFC 8705) — present the client certificate registered via /v1/certificates for certificate-bound access tokens required by FAPI 1.0 Advanced.  Supports mutual TLS (mTLS) client authentication per RFC 8705 for certificate-bound access tokens required by FAPI 1.0 Advanced.",
        "parameters": [
          {
            "$ref": "#/components/parameters/RequestId"
          },
          {
            "$ref": "#/components/parameters/Traceparent"
          },
          {
            "$ref": "#/components/parameters/Tracestate"
          },
          {
            "$ref": "#/components/parameters/AcceptLanguage"
          }
        ],
        "x-codeSamples": [
          {
            "lang": "cURL",
            "label": "cURL",
            "source": "curl -X POST \"https://api.kangopenbanking.com/v1/oauth/token\" \\\n  -H \"Authorization: Bearer $KOB_ACCESS_TOKEN\" \\\n  -H \"Content-Type: application/json\" \\\n  -d '{}'"
          },
          {
            "lang": "JavaScript",
            "label": "Node.js",
            "source": "import { KangOpenBanking } from \"@kangopenbanking/sdk\";\n\nconst kob = new KangOpenBanking({ apiKey: process.env.KOB_API_KEY });\nconst res = await kob.request(\"POST\", \"/v1/oauth/token\", { /* payload */ });\nconsole.log(res);"
          },
          {
            "lang": "Python",
            "label": "Python",
            "source": "from kangopenbanking import KangOpenBanking\n\nkob = KangOpenBanking(api_key=os.environ[\"KOB_API_KEY\"])\nres = kob.request(\"POST\", \"/v1/oauth/token\", json={})\nprint(res)"
          },
          {
            "lang": "PHP",
            "label": "PHP",
            "source": "<?php\n$kob = new KangOpenBanking\\KangOpenBanking(getenv('KOB_API_KEY'));\n$res = $kob->request('POST', '/v1/oauth/token', []);\nprint_r($res);"
          }
        ]
      }
    },
    "/v1/oauth/introspect": {
      "post": {
        "tags": [
          "OAuth"
        ],
        "summary": "Introspect access token",
        "operationId": "oauthIntrospect",
        "security": [
          {
            "bearerAuth": []
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/x-www-form-urlencoded": {
              "schema": {
                "type": "object",
                "required": [
                  "token"
                ],
                "properties": {
                  "token": {
                    "type": "string"
                  }
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Token introspection result",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "active": {
                      "type": "boolean"
                    },
                    "scope": {
                      "type": "string"
                    },
                    "client_id": {
                      "type": "string"
                    },
                    "exp": {
                      "type": "integer"
                    },
                    "sub": {
                      "type": "string"
                    }
                  }
                },
                "example": {
                  "active": true,
                  "scope": "string",
                  "client_id": "string",
                  "exp": 0,
                  "sub": "string"
                }
              }
            },
            "headers": {
              "x-fapi-interaction-id": {
                "$ref": "#/components/headers/XFapiInteractionIdResponse"
              },
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/XRateLimitLimit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/XRateLimitRemaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/XRateLimitReset"
              },
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              },
              "traceparent": {
                "$ref": "#/components/headers/Traceparent"
              },
              "Content-Language": {
                "$ref": "#/components/headers/Content-Language"
              }
            }
          },
          "400": {
            "description": "Bad request",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              },
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                },
                "examples": {
                  "error": {
                    "$ref": "#/components/examples/ErrorBadRequest"
                  }
                }
              }
            },
            "headers": {
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/XRateLimitLimit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/XRateLimitRemaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/XRateLimitReset"
              },
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "403": {
            "$ref": "#/components/responses/Forbidden",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "404": {
            "$ref": "#/components/responses/NotFound",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "409": {
            "$ref": "#/components/responses/Conflict",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "429": {
            "$ref": "#/components/responses/TooManyRequests",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "500": {
            "$ref": "#/components/responses/InternalServerError",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          }
        },
        "parameters": [
          {
            "$ref": "#/components/parameters/RequestId"
          },
          {
            "$ref": "#/components/parameters/Traceparent"
          },
          {
            "$ref": "#/components/parameters/Tracestate"
          },
          {
            "$ref": "#/components/parameters/AcceptLanguage"
          }
        ],
        "x-codeSamples": [
          {
            "lang": "cURL",
            "label": "cURL",
            "source": "curl -X POST \"https://api.kangopenbanking.com/v1/oauth/introspect\" \\\n  -H \"Authorization: Bearer $KOB_ACCESS_TOKEN\" \\\n  -H \"Content-Type: application/json\" \\\n  -d '{}'"
          },
          {
            "lang": "JavaScript",
            "label": "Node.js",
            "source": "import { KangOpenBanking } from \"@kangopenbanking/sdk\";\n\nconst kob = new KangOpenBanking({ apiKey: process.env.KOB_API_KEY });\nconst res = await kob.request(\"POST\", \"/v1/oauth/introspect\", { /* payload */ });\nconsole.log(res);"
          },
          {
            "lang": "Python",
            "label": "Python",
            "source": "from kangopenbanking import KangOpenBanking\n\nkob = KangOpenBanking(api_key=os.environ[\"KOB_API_KEY\"])\nres = kob.request(\"POST\", \"/v1/oauth/introspect\", json={})\nprint(res)"
          },
          {
            "lang": "PHP",
            "label": "PHP",
            "source": "<?php\n$kob = new KangOpenBanking\\KangOpenBanking(getenv('KOB_API_KEY'));\n$res = $kob->request('POST', '/v1/oauth/introspect', []);\nprint_r($res);"
          }
        ]
      }
    },
    "/v1/oauth/par": {
      "post": {
        "tags": [
          "OAuth"
        ],
        "summary": "Pushed Authorization Request",
        "operationId": "parEndpoint",
        "security": [
          {
            "mtls": []
          }
        ],
        "parameters": [
          {
            "name": "Idempotency-Key",
            "in": "header",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid"
            },
            "description": "Required on all POST/PUT endpoints. Unique key for idempotent request processing (UUID v4 recommended). Keys expire after 24 hours."
          },
          {
            "$ref": "#/components/parameters/RequestId"
          },
          {
            "$ref": "#/components/parameters/Traceparent"
          },
          {
            "$ref": "#/components/parameters/Tracestate"
          },
          {
            "$ref": "#/components/parameters/AcceptLanguage"
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/x-www-form-urlencoded": {
              "schema": {
                "type": "object",
                "required": [
                  "client_id",
                  "response_type",
                  "redirect_uri",
                  "scope"
                ],
                "properties": {
                  "client_id": {
                    "type": "string"
                  },
                  "response_type": {
                    "type": "string"
                  },
                  "redirect_uri": {
                    "type": "string"
                  },
                  "scope": {
                    "type": "string"
                  },
                  "state": {
                    "type": "string"
                  },
                  "code_challenge": {
                    "type": "string"
                  },
                  "code_challenge_method": {
                    "type": "string"
                  }
                }
              }
            }
          }
        },
        "responses": {
          "201": {
            "description": "PAR created",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "request_uri": {
                      "type": "string"
                    },
                    "expires_in": {
                      "type": "integer",
                      "example": 600
                    }
                  }
                },
                "example": {
                  "request_uri": "string",
                  "expires_in": 600
                }
              }
            },
            "headers": {
              "x-fapi-interaction-id": {
                "$ref": "#/components/headers/XFapiInteractionIdResponse"
              },
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/XRateLimitLimit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/XRateLimitRemaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/XRateLimitReset"
              },
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              },
              "traceparent": {
                "$ref": "#/components/headers/Traceparent"
              },
              "Content-Language": {
                "$ref": "#/components/headers/Content-Language"
              }
            }
          },
          "400": {
            "description": "Bad request",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              },
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                },
                "examples": {
                  "error": {
                    "$ref": "#/components/examples/ErrorBadRequest"
                  }
                }
              }
            },
            "headers": {
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/XRateLimitLimit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/XRateLimitRemaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/XRateLimitReset"
              },
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "403": {
            "$ref": "#/components/responses/Forbidden",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "404": {
            "$ref": "#/components/responses/NotFound",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "409": {
            "$ref": "#/components/responses/Conflict",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "429": {
            "$ref": "#/components/responses/TooManyRequests",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "500": {
            "$ref": "#/components/responses/InternalServerError",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          }
        },
        "x-codeSamples": [
          {
            "lang": "cURL",
            "label": "cURL",
            "source": "curl -X POST \"https://api.kangopenbanking.com/v1/oauth/par\" \\\n  -H \"Authorization: Bearer $KOB_ACCESS_TOKEN\" \\\n  -H \"Content-Type: application/json\" \\\n  -d '{}'"
          },
          {
            "lang": "JavaScript",
            "label": "Node.js",
            "source": "import { KangOpenBanking } from \"@kangopenbanking/sdk\";\n\nconst kob = new KangOpenBanking({ apiKey: process.env.KOB_API_KEY });\nconst res = await kob.request(\"POST\", \"/v1/oauth/par\", { /* payload */ });\nconsole.log(res);"
          },
          {
            "lang": "Python",
            "label": "Python",
            "source": "from kangopenbanking import KangOpenBanking\n\nkob = KangOpenBanking(api_key=os.environ[\"KOB_API_KEY\"])\nres = kob.request(\"POST\", \"/v1/oauth/par\", json={})\nprint(res)"
          },
          {
            "lang": "PHP",
            "label": "PHP",
            "source": "<?php\n$kob = new KangOpenBanking\\KangOpenBanking(getenv('KOB_API_KEY'));\n$res = $kob->request('POST', '/v1/oauth/par', []);\nprint_r($res);"
          }
        ]
      }
    },
    "/v1/dcr/register": {
      "post": {
        "tags": [
          "OAuth"
        ],
        "summary": "Dynamic Client Registration",
        "operationId": "dcrRegister",
        "security": [
          {
            "mtls": []
          }
        ],
        "parameters": [
          {
            "name": "Idempotency-Key",
            "in": "header",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid"
            },
            "description": "Required on all POST/PUT endpoints. Unique key for idempotent request processing (UUID v4 recommended). Keys expire after 24 hours."
          },
          {
            "$ref": "#/components/parameters/RequestId"
          },
          {
            "$ref": "#/components/parameters/Traceparent"
          },
          {
            "$ref": "#/components/parameters/Tracestate"
          },
          {
            "$ref": "#/components/parameters/AcceptLanguage"
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/DcrRegistrationRequest"
              },
              "example": {
                "software_statement": "eyJhbGciOiJQUzI1NiJ9.eyJzb2Z0d2FyZV9pZCI6InRwcF8wMDEiLCJzb2Z0d2FyZV9jbGllbnRfbmFtZSI6IkZpblRlY2ggQXBwIENhbWVyb3VuIiwic29mdHdhcmVfcm9sZXMiOlsiQUlTUCIsIlBJU1AiXX0.sig",
                "redirect_uris": [
                  "https://app.example.com/callback"
                ],
                "token_endpoint_auth_method": "tls_client_auth",
                "grant_types": [
                  "authorization_code",
                  "refresh_token"
                ],
                "scope": "accounts payments"
              }
            }
          }
        },
        "responses": {
          "201": {
            "description": "Client registered",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/DcrRegistrationResponse"
                },
                "example": {
                  "client_id": "tpp_a1b2c3d4-e5f6-7890-abcd-ef1234567890",
                  "client_secret": "kob_sec_7f3a9b2c4d5e6f1a8b9c0d1e2f3a4b5c6d7e8f9a0b1c2d3e4f5a6b7c8d9e0f",
                  "client_name": "FinTech App Cameroun",
                  "software_id": "tpp_001",
                  "software_roles": [
                    "AISP",
                    "PISP"
                  ],
                  "redirect_uris": [
                    "https://app.example.com/callback"
                  ],
                  "grant_types": [
                    "authorization_code",
                    "refresh_token"
                  ],
                  "response_types": [
                    "code"
                  ],
                  "token_endpoint_auth_method": "tls_client_auth",
                  "scope": "accounts payments",
                  "environment": "sandbox",
                  "client_id_issued_at": 1710504000
                }
              }
            },
            "headers": {
              "x-fapi-interaction-id": {
                "$ref": "#/components/headers/XFapiInteractionIdResponse"
              },
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/XRateLimitLimit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/XRateLimitRemaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/XRateLimitReset"
              },
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              },
              "traceparent": {
                "$ref": "#/components/headers/Traceparent"
              },
              "Content-Language": {
                "$ref": "#/components/headers/Content-Language"
              }
            }
          },
          "400": {
            "description": "Bad request",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              },
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                },
                "examples": {
                  "error": {
                    "$ref": "#/components/examples/ErrorBadRequest"
                  }
                }
              }
            },
            "headers": {
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/XRateLimitLimit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/XRateLimitRemaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/XRateLimitReset"
              },
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "403": {
            "$ref": "#/components/responses/Forbidden",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "404": {
            "$ref": "#/components/responses/NotFound",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "409": {
            "$ref": "#/components/responses/Conflict",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "429": {
            "$ref": "#/components/responses/TooManyRequests",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "500": {
            "$ref": "#/components/responses/InternalServerError",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          }
        },
        "x-codeSamples": [
          {
            "lang": "cURL",
            "label": "cURL",
            "source": "curl -X POST \"https://api.kangopenbanking.com/v1/dcr/register\" \\\n  -H \"Authorization: Bearer $KOB_ACCESS_TOKEN\" \\\n  -H \"Content-Type: application/json\" \\\n  -d '{}'"
          },
          {
            "lang": "JavaScript",
            "label": "Node.js",
            "source": "import { KangOpenBanking } from \"@kangopenbanking/sdk\";\n\nconst kob = new KangOpenBanking({ apiKey: process.env.KOB_API_KEY });\nconst res = await kob.request(\"POST\", \"/v1/dcr/register\", { /* payload */ });\nconsole.log(res);"
          },
          {
            "lang": "Python",
            "label": "Python",
            "source": "from kangopenbanking import KangOpenBanking\n\nkob = KangOpenBanking(api_key=os.environ[\"KOB_API_KEY\"])\nres = kob.request(\"POST\", \"/v1/dcr/register\", json={})\nprint(res)"
          },
          {
            "lang": "PHP",
            "label": "PHP",
            "source": "<?php\n$kob = new KangOpenBanking\\KangOpenBanking(getenv('KOB_API_KEY'));\n$res = $kob->request('POST', '/v1/dcr/register', []);\nprint_r($res);"
          }
        ]
      }
    },
    "/v1/oidc/.well-known/openid-configuration": {
      "get": {
        "tags": [
          "OAuth"
        ],
        "summary": "OIDC discovery",
        "operationId": "oidcConfig",
        "security": [],
        "responses": {
          "200": {
            "description": "OIDC configuration document",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "issuer": {
                      "type": "string"
                    },
                    "authorization_endpoint": {
                      "type": "string"
                    },
                    "token_endpoint": {
                      "type": "string"
                    },
                    "jwks_uri": {
                      "type": "string"
                    },
                    "response_types_supported": {
                      "type": "array",
                      "items": {
                        "type": "string"
                      }
                    },
                    "subject_types_supported": {
                      "type": "array",
                      "items": {
                        "type": "string"
                      }
                    },
                    "id_token_signing_alg_values_supported": {
                      "type": "array",
                      "items": {
                        "type": "string"
                      }
                    },
                    "userinfo_endpoint": {
                      "type": "string",
                      "example": "https://api.kangopenbanking.com/v1/oauth/userinfo",
                      "description": "URL of the UserInfo Endpoint (OIDC Core 1.0 Section 5.3)"
                    },
                    "registration_endpoint": {
                      "type": "string",
                      "example": "https://api.kangopenbanking.com/v1/dcr/register",
                      "description": "URL of the Dynamic Client Registration endpoint (RFC 7591)"
                    },
                    "scopes_supported": {
                      "type": "array",
                      "items": {
                        "type": "string"
                      },
                      "example": [
                        "openid",
                        "accounts",
                        "balances",
                        "transactions",
                        "payments",
                        "offline_access"
                      ],
                      "description": "List of OAuth 2.0 scope values supported"
                    },
                    "claims_supported": {
                      "type": "array",
                      "items": {
                        "type": "string"
                      },
                      "example": [
                        "sub",
                        "iss",
                        "auth_time",
                        "acr",
                        "name",
                        "given_name",
                        "family_name",
                        "email",
                        "phone_number"
                      ],
                      "description": "List of claim names supported in issued ID Tokens"
                    },
                    "token_endpoint_auth_methods_supported": {
                      "type": "array",
                      "items": {
                        "type": "string"
                      },
                      "example": [
                        "private_key_jwt",
                        "tls_client_auth",
                        "client_secret_basic"
                      ],
                      "description": "List of client authentication methods supported at the token endpoint. private_key_jwt required for FAPI 1.0 Advanced."
                    },
                    "request_object_signing_alg_values_supported": {
                      "type": "array",
                      "items": {
                        "type": "string"
                      },
                      "example": [
                        "PS256",
                        "ES256"
                      ],
                      "description": "Signing algorithms supported for Request Objects. PS256 required for FAPI 1.0 Advanced."
                    },
                    "token_endpoint_auth_signing_alg_values_supported": {
                      "type": "array",
                      "items": {
                        "type": "string"
                      },
                      "example": [
                        "PS256",
                        "ES256"
                      ],
                      "description": "Signing algorithms supported for JWT client authentication at the token endpoint."
                    },
                    "grant_types_supported": {
                      "type": "array",
                      "items": {
                        "type": "string"
                      },
                      "example": [
                        "authorization_code",
                        "refresh_token",
                        "client_credentials"
                      ],
                      "description": "List of OAuth 2.0 grant type values supported"
                    },
                    "require_pushed_authorization_requests": {
                      "type": "boolean",
                      "example": true,
                      "description": "If true, PAR (Pushed Authorisation Requests) are required. Required for FAPI 1.0 Advanced."
                    },
                    "mtls_endpoint_aliases": {
                      "type": "object",
                      "description": "mTLS endpoint aliases for certificate-bound access tokens (RFC 8705)",
                      "properties": {
                        "token_endpoint": {
                          "type": "string",
                          "example": "https://api.kangopenbanking.com/v1/oauth/token"
                        },
                        "par_endpoint": {
                          "type": "string",
                          "example": "https://api.kangopenbanking.com/v1/oauth/par"
                        }
                      }
                    },
                    "pushed_authorization_request_endpoint": {
                      "type": "string",
                      "format": "uri",
                      "description": "URL of the Pushed Authorisation Request (PAR) endpoint (RFC 9126). Clients SHOULD use PAR before calling the authorization endpoint.",
                      "example": "https://api.kangopenbanking.com/v1/oauth/par"
                    },
                    "backchannel_authentication_endpoint": {
                      "type": "string",
                      "format": "uri",
                      "description": "URL of the CIBA (Client-Initiated Backchannel Authentication) endpoint for decoupled authentication flows. Optional advanced FAPI feature for mobile banking step-up authentication.",
                      "example": "https://api.kangopenbanking.com/v1/auth/backchannel"
                    }
                  }
                },
                "example": {
                  "issuer": "string",
                  "authorization_endpoint": "string",
                  "token_endpoint": "string",
                  "jwks_uri": "string",
                  "response_types_supported": [
                    "string"
                  ],
                  "subject_types_supported": [
                    "string"
                  ],
                  "id_token_signing_alg_values_supported": [
                    "string"
                  ],
                  "userinfo_endpoint": "https://api.kangopenbanking.com/v1/oauth/userinfo",
                  "registration_endpoint": "https://api.kangopenbanking.com/v1/dcr/register",
                  "scopes_supported": [
                    "openid",
                    "accounts",
                    "balances",
                    "transactions",
                    "payments",
                    "offline_access"
                  ],
                  "claims_supported": [
                    "sub",
                    "iss",
                    "auth_time",
                    "acr",
                    "name",
                    "given_name",
                    "family_name",
                    "email",
                    "phone_number"
                  ],
                  "token_endpoint_auth_methods_supported": [
                    "private_key_jwt",
                    "tls_client_auth",
                    "client_secret_basic"
                  ],
                  "request_object_signing_alg_values_supported": [
                    "PS256",
                    "ES256"
                  ],
                  "token_endpoint_auth_signing_alg_values_supported": [
                    "PS256",
                    "ES256"
                  ],
                  "grant_types_supported": [
                    "authorization_code",
                    "refresh_token",
                    "client_credentials"
                  ],
                  "require_pushed_authorization_requests": true,
                  "mtls_endpoint_aliases": {
                    "token_endpoint": "https://api.kangopenbanking.com/v1/oauth/token",
                    "par_endpoint": "https://api.kangopenbanking.com/v1/oauth/par"
                  },
                  "pushed_authorization_request_endpoint": "https://api.kangopenbanking.com/v1/oauth/par",
                  "backchannel_authentication_endpoint": "https://api.kangopenbanking.com/v1/auth/backchannel"
                }
              }
            },
            "headers": {
              "x-fapi-interaction-id": {
                "$ref": "#/components/headers/XFapiInteractionIdResponse"
              },
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/XRateLimitLimit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/XRateLimitRemaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/XRateLimitReset"
              },
              "Cache-Control": {
                "$ref": "#/components/headers/CacheControl"
              },
              "ETag": {
                "$ref": "#/components/headers/ETag"
              },
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              },
              "traceparent": {
                "$ref": "#/components/headers/Traceparent"
              },
              "Content-Language": {
                "$ref": "#/components/headers/Content-Language"
              }
            }
          },
          "429": {
            "$ref": "#/components/responses/TooManyRequests",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "default": {
            "description": "Server error — see ProblemDetails for trace ID.",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            },
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/XRateLimitLimit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/XRateLimitRemaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/XRateLimitReset"
              }
            }
          }
        },
        "parameters": [
          {
            "$ref": "#/components/parameters/RequestId"
          },
          {
            "$ref": "#/components/parameters/Traceparent"
          },
          {
            "$ref": "#/components/parameters/Tracestate"
          },
          {
            "$ref": "#/components/parameters/AcceptLanguage"
          }
        ],
        "x-codeSamples": [
          {
            "lang": "cURL",
            "label": "cURL",
            "source": "curl -X GET \"https://api.kangopenbanking.com/v1/oidc/.well-known/openid-configuration\" \\\n  -H \"Authorization: Bearer $KOB_ACCESS_TOKEN\" \\\n  -H \"Content-Type: application/json\""
          },
          {
            "lang": "JavaScript",
            "label": "Node.js",
            "source": "import { KangOpenBanking } from \"@kangopenbanking/sdk\";\n\nconst kob = new KangOpenBanking({ apiKey: process.env.KOB_API_KEY });\nconst res = await kob.request(\"GET\", \"/v1/oidc/.well-known/openid-configuration\");\nconsole.log(res);"
          },
          {
            "lang": "Python",
            "label": "Python",
            "source": "from kangopenbanking import KangOpenBanking\n\nkob = KangOpenBanking(api_key=os.environ[\"KOB_API_KEY\"])\nres = kob.request(\"GET\", \"/v1/oidc/.well-known/openid-configuration\")\nprint(res)"
          },
          {
            "lang": "PHP",
            "label": "PHP",
            "source": "<?php\n$kob = new KangOpenBanking\\KangOpenBanking(getenv('KOB_API_KEY'));\n$res = $kob->request('GET', '/v1/oidc/.well-known/openid-configuration');\nprint_r($res);"
          }
        ]
      }
    },
    "/v1/jwks": {
      "get": {
        "tags": [
          "OAuth"
        ],
        "summary": "JSON Web Key Set",
        "operationId": "jwksEndpoint",
        "security": [],
        "responses": {
          "200": {
            "description": "Public keys for token verification",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "keys": {
                      "type": "array",
                      "items": {
                        "type": "object",
                        "properties": {
                          "kty": {
                            "type": "string"
                          },
                          "kid": {
                            "type": "string"
                          },
                          "use": {
                            "type": "string"
                          },
                          "n": {
                            "type": "string"
                          },
                          "e": {
                            "type": "string"
                          }
                        }
                      }
                    }
                  }
                },
                "example": {
                  "keys": [
                    {
                      "kty": "string",
                      "kid": "string",
                      "use": "string",
                      "n": "string",
                      "e": "string"
                    }
                  ]
                }
              }
            },
            "headers": {
              "x-fapi-interaction-id": {
                "$ref": "#/components/headers/XFapiInteractionIdResponse"
              },
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/XRateLimitLimit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/XRateLimitRemaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/XRateLimitReset"
              },
              "Cache-Control": {
                "$ref": "#/components/headers/CacheControl"
              },
              "ETag": {
                "$ref": "#/components/headers/ETag"
              },
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              },
              "traceparent": {
                "$ref": "#/components/headers/Traceparent"
              },
              "Content-Language": {
                "$ref": "#/components/headers/Content-Language"
              }
            }
          },
          "429": {
            "$ref": "#/components/responses/TooManyRequests",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "default": {
            "description": "Server error — see ProblemDetails for trace ID.",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            },
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/XRateLimitLimit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/XRateLimitRemaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/XRateLimitReset"
              }
            }
          }
        },
        "parameters": [
          {
            "$ref": "#/components/parameters/RequestId"
          },
          {
            "$ref": "#/components/parameters/Traceparent"
          },
          {
            "$ref": "#/components/parameters/Tracestate"
          },
          {
            "$ref": "#/components/parameters/AcceptLanguage"
          }
        ],
        "x-codeSamples": [
          {
            "lang": "cURL",
            "label": "cURL",
            "source": "curl -X GET \"https://api.kangopenbanking.com/v1/jwks\" \\\n  -H \"Authorization: Bearer $KOB_ACCESS_TOKEN\" \\\n  -H \"Content-Type: application/json\""
          },
          {
            "lang": "JavaScript",
            "label": "Node.js",
            "source": "import { KangOpenBanking } from \"@kangopenbanking/sdk\";\n\nconst kob = new KangOpenBanking({ apiKey: process.env.KOB_API_KEY });\nconst res = await kob.request(\"GET\", \"/v1/jwks\");\nconsole.log(res);"
          },
          {
            "lang": "Python",
            "label": "Python",
            "source": "from kangopenbanking import KangOpenBanking\n\nkob = KangOpenBanking(api_key=os.environ[\"KOB_API_KEY\"])\nres = kob.request(\"GET\", \"/v1/jwks\")\nprint(res)"
          },
          {
            "lang": "PHP",
            "label": "PHP",
            "source": "<?php\n$kob = new KangOpenBanking\\KangOpenBanking(getenv('KOB_API_KEY'));\n$res = $kob->request('GET', '/v1/jwks');\nprint_r($res);"
          }
        ],
        "description": "JSON Web Key Set.\n\n**Tag:** OAuth\n\nAuthenticate with a bearer token issued by `/v1/oauth/token`. All state-changing requests\n(POST, PUT, PATCH, DELETE) MUST include an `Idempotency-Key` header (UUID v4) to make\nretries safe — Kang will return the original response for any duplicate key within 24 hours.\n\nErrors follow [RFC 7807](https://datatracker.ietf.org/doc/html/rfc7807) and are returned with\n`Content-Type: application/problem+json`. The `code` field is stable and machine-readable.\nRate-limit headers (`X-RateLimit-Limit`, `X-RateLimit-Remaining`, `X-RateLimit-Reset`)\nare present on every response.\n\n**Key selection:** select the verification key whose `kid` matches the JWT header `kid`; treat `kid` as an opaque string and refresh this document when an unknown `kid` is seen. The signing-key lifecycle derives `kid` as an RFC 7638 JWK thumbprint; key rotation is pending certification, so do not pin a single key."
      }
    },
    "/v1/auth/phone/send-otp": {
      "post": {
        "tags": [
          "Authentication"
        ],
        "summary": "Send OTP to phone",
        "operationId": "phoneAuthSendOtp",
        "security": [],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "required": [
                  "phone_number"
                ],
                "properties": {
                  "phone_number": {
                    "type": "string",
                    "example": "+237670000000"
                  }
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "OTP sent",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "success": {
                      "type": "boolean",
                      "example": true
                    },
                    "message": {
                      "type": "string"
                    }
                  }
                },
                "example": {
                  "success": true,
                  "message": "string"
                }
              }
            },
            "headers": {
              "x-fapi-interaction-id": {
                "$ref": "#/components/headers/XFapiInteractionIdResponse"
              },
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/XRateLimitLimit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/XRateLimitRemaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/XRateLimitReset"
              },
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              },
              "traceparent": {
                "$ref": "#/components/headers/Traceparent"
              },
              "Content-Language": {
                "$ref": "#/components/headers/Content-Language"
              }
            }
          },
          "400": {
            "description": "Bad request",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              },
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                },
                "examples": {
                  "error": {
                    "$ref": "#/components/examples/ErrorBadRequest"
                  }
                }
              }
            },
            "headers": {
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/XRateLimitLimit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/XRateLimitRemaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/XRateLimitReset"
              },
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "403": {
            "$ref": "#/components/responses/Forbidden",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "404": {
            "$ref": "#/components/responses/NotFound",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "409": {
            "$ref": "#/components/responses/Conflict",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "429": {
            "$ref": "#/components/responses/TooManyRequests",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "500": {
            "$ref": "#/components/responses/InternalServerError",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          }
        },
        "parameters": [
          {
            "$ref": "#/components/parameters/RequestId"
          },
          {
            "$ref": "#/components/parameters/Traceparent"
          },
          {
            "$ref": "#/components/parameters/Tracestate"
          },
          {
            "$ref": "#/components/parameters/AcceptLanguage"
          }
        ],
        "x-codeSamples": [
          {
            "lang": "cURL",
            "label": "cURL",
            "source": "curl -X POST \"https://api.kangopenbanking.com/v1/auth/phone/send-otp\" \\\n  -H \"Authorization: Bearer $KOB_ACCESS_TOKEN\" \\\n  -H \"Content-Type: application/json\" \\\n  -d '{}'"
          },
          {
            "lang": "JavaScript",
            "label": "Node.js",
            "source": "import { KangOpenBanking } from \"@kangopenbanking/sdk\";\n\nconst kob = new KangOpenBanking({ apiKey: process.env.KOB_API_KEY });\nconst res = await kob.request(\"POST\", \"/v1/auth/phone/send-otp\", { /* payload */ });\nconsole.log(res);"
          },
          {
            "lang": "Python",
            "label": "Python",
            "source": "from kangopenbanking import KangOpenBanking\n\nkob = KangOpenBanking(api_key=os.environ[\"KOB_API_KEY\"])\nres = kob.request(\"POST\", \"/v1/auth/phone/send-otp\", json={})\nprint(res)"
          },
          {
            "lang": "PHP",
            "label": "PHP",
            "source": "<?php\n$kob = new KangOpenBanking\\KangOpenBanking(getenv('KOB_API_KEY'));\n$res = $kob->request('POST', '/v1/auth/phone/send-otp', []);\nprint_r($res);"
          }
        ]
      }
    },
    "/v1/auth/phone/verify-otp": {
      "post": {
        "tags": [
          "Authentication"
        ],
        "summary": "Verify OTP",
        "operationId": "phoneAuthVerifyOtp",
        "security": [],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "required": [
                  "phone_number",
                  "otp_code"
                ],
                "properties": {
                  "phone_number": {
                    "type": "string"
                  },
                  "otp_code": {
                    "type": "string"
                  }
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Authentication successful",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "access_token": {
                      "type": "string"
                    },
                    "token_type": {
                      "type": "string",
                      "example": "Bearer"
                    },
                    "expires_in": {
                      "type": "integer",
                      "example": 3600
                    },
                    "refresh_token": {
                      "type": "string"
                    },
                    "user_id": {
                      "type": "string",
                      "format": "uuid"
                    }
                  }
                },
                "example": {
                  "access_token": "string",
                  "token_type": "Bearer",
                  "expires_in": 3600,
                  "refresh_token": "string",
                  "user_id": "00000000-0000-4000-8000-000000000000"
                }
              }
            },
            "headers": {
              "x-fapi-interaction-id": {
                "$ref": "#/components/headers/XFapiInteractionIdResponse"
              },
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/XRateLimitLimit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/XRateLimitRemaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/XRateLimitReset"
              },
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              },
              "traceparent": {
                "$ref": "#/components/headers/Traceparent"
              },
              "Content-Language": {
                "$ref": "#/components/headers/Content-Language"
              }
            }
          },
          "400": {
            "description": "Bad request",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              },
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                },
                "examples": {
                  "error": {
                    "$ref": "#/components/examples/ErrorBadRequest"
                  }
                }
              }
            },
            "headers": {
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/XRateLimitLimit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/XRateLimitRemaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/XRateLimitReset"
              },
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "403": {
            "$ref": "#/components/responses/Forbidden",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "404": {
            "$ref": "#/components/responses/NotFound",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "409": {
            "$ref": "#/components/responses/Conflict",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "429": {
            "$ref": "#/components/responses/TooManyRequests",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "500": {
            "$ref": "#/components/responses/InternalServerError",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          }
        },
        "parameters": [
          {
            "$ref": "#/components/parameters/RequestId"
          },
          {
            "$ref": "#/components/parameters/Traceparent"
          },
          {
            "$ref": "#/components/parameters/Tracestate"
          },
          {
            "$ref": "#/components/parameters/AcceptLanguage"
          }
        ],
        "x-codeSamples": [
          {
            "lang": "cURL",
            "label": "cURL",
            "source": "curl -X POST \"https://api.kangopenbanking.com/v1/auth/phone/verify-otp\" \\\n  -H \"Authorization: Bearer $KOB_ACCESS_TOKEN\" \\\n  -H \"Content-Type: application/json\" \\\n  -d '{}'"
          },
          {
            "lang": "JavaScript",
            "label": "Node.js",
            "source": "import { KangOpenBanking } from \"@kangopenbanking/sdk\";\n\nconst kob = new KangOpenBanking({ apiKey: process.env.KOB_API_KEY });\nconst res = await kob.request(\"POST\", \"/v1/auth/phone/verify-otp\", { /* payload */ });\nconsole.log(res);"
          },
          {
            "lang": "Python",
            "label": "Python",
            "source": "from kangopenbanking import KangOpenBanking\n\nkob = KangOpenBanking(api_key=os.environ[\"KOB_API_KEY\"])\nres = kob.request(\"POST\", \"/v1/auth/phone/verify-otp\", json={})\nprint(res)"
          },
          {
            "lang": "PHP",
            "label": "PHP",
            "source": "<?php\n$kob = new KangOpenBanking\\KangOpenBanking(getenv('KOB_API_KEY'));\n$res = $kob->request('POST', '/v1/auth/phone/verify-otp', []);\nprint_r($res);"
          }
        ]
      }
    },
    "/v1/auth/phone/pin-login": {
      "post": {
        "tags": [
          "Authentication"
        ],
        "summary": "Login with PIN",
        "operationId": "phoneAuthPinLogin",
        "security": [],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "required": [
                  "phone_number",
                  "pin"
                ],
                "properties": {
                  "phone_number": {
                    "type": "string"
                  },
                  "pin": {
                    "type": "string",
                    "minLength": 4,
                    "maxLength": 6
                  }
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Authentication successful",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "access_token": {
                      "type": "string"
                    },
                    "token_type": {
                      "type": "string",
                      "example": "Bearer"
                    },
                    "expires_in": {
                      "type": "integer",
                      "example": 3600
                    },
                    "refresh_token": {
                      "type": "string"
                    },
                    "user_id": {
                      "type": "string",
                      "format": "uuid"
                    }
                  }
                },
                "example": {
                  "access_token": "string",
                  "token_type": "Bearer",
                  "expires_in": 3600,
                  "refresh_token": "string",
                  "user_id": "00000000-0000-4000-8000-000000000000"
                }
              }
            },
            "headers": {
              "x-fapi-interaction-id": {
                "$ref": "#/components/headers/XFapiInteractionIdResponse"
              },
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/XRateLimitLimit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/XRateLimitRemaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/XRateLimitReset"
              },
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              },
              "traceparent": {
                "$ref": "#/components/headers/Traceparent"
              },
              "Content-Language": {
                "$ref": "#/components/headers/Content-Language"
              }
            }
          },
          "400": {
            "description": "Bad request",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              },
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                },
                "examples": {
                  "error": {
                    "$ref": "#/components/examples/ErrorBadRequest"
                  }
                }
              }
            },
            "headers": {
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/XRateLimitLimit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/XRateLimitRemaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/XRateLimitReset"
              },
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "403": {
            "$ref": "#/components/responses/Forbidden",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "404": {
            "$ref": "#/components/responses/NotFound",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "409": {
            "$ref": "#/components/responses/Conflict",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "429": {
            "$ref": "#/components/responses/TooManyRequests",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "500": {
            "$ref": "#/components/responses/InternalServerError",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          }
        },
        "parameters": [
          {
            "$ref": "#/components/parameters/RequestId"
          },
          {
            "$ref": "#/components/parameters/Traceparent"
          },
          {
            "$ref": "#/components/parameters/Tracestate"
          },
          {
            "$ref": "#/components/parameters/AcceptLanguage"
          }
        ],
        "x-codeSamples": [
          {
            "lang": "cURL",
            "label": "cURL",
            "source": "curl -X POST \"https://api.kangopenbanking.com/v1/auth/phone/pin-login\" \\\n  -H \"Authorization: Bearer $KOB_ACCESS_TOKEN\" \\\n  -H \"Content-Type: application/json\" \\\n  -d '{}'"
          },
          {
            "lang": "JavaScript",
            "label": "Node.js",
            "source": "import { KangOpenBanking } from \"@kangopenbanking/sdk\";\n\nconst kob = new KangOpenBanking({ apiKey: process.env.KOB_API_KEY });\nconst res = await kob.request(\"POST\", \"/v1/auth/phone/pin-login\", { /* payload */ });\nconsole.log(res);"
          },
          {
            "lang": "Python",
            "label": "Python",
            "source": "from kangopenbanking import KangOpenBanking\n\nkob = KangOpenBanking(api_key=os.environ[\"KOB_API_KEY\"])\nres = kob.request(\"POST\", \"/v1/auth/phone/pin-login\", json={})\nprint(res)"
          },
          {
            "lang": "PHP",
            "label": "PHP",
            "source": "<?php\n$kob = new KangOpenBanking\\KangOpenBanking(getenv('KOB_API_KEY'));\n$res = $kob->request('POST', '/v1/auth/phone/pin-login', []);\nprint_r($res);"
          }
        ]
      }
    },
    "/v1/auth/pin/set": {
      "post": {
        "tags": [
          "Authentication"
        ],
        "summary": "Set PIN code",
        "operationId": "pinCodeSet",
        "security": [
          {
            "bearerAuth": []
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "required": [
                  "pin"
                ],
                "properties": {
                  "pin": {
                    "type": "string"
                  }
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "PIN set",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "success": {
                      "type": "boolean",
                      "example": true
                    },
                    "message": {
                      "type": "string"
                    }
                  }
                },
                "example": {
                  "success": true,
                  "message": "string"
                }
              }
            },
            "headers": {
              "x-fapi-interaction-id": {
                "$ref": "#/components/headers/XFapiInteractionIdResponse"
              },
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/XRateLimitLimit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/XRateLimitRemaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/XRateLimitReset"
              },
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              },
              "traceparent": {
                "$ref": "#/components/headers/Traceparent"
              },
              "Content-Language": {
                "$ref": "#/components/headers/Content-Language"
              }
            }
          },
          "400": {
            "description": "Bad request",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              },
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                },
                "examples": {
                  "error": {
                    "$ref": "#/components/examples/ErrorBadRequest"
                  }
                }
              }
            },
            "headers": {
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/XRateLimitLimit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/XRateLimitRemaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/XRateLimitReset"
              },
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "403": {
            "$ref": "#/components/responses/Forbidden",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "404": {
            "$ref": "#/components/responses/NotFound",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "409": {
            "$ref": "#/components/responses/Conflict",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "429": {
            "$ref": "#/components/responses/TooManyRequests",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "500": {
            "$ref": "#/components/responses/InternalServerError",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          }
        },
        "parameters": [
          {
            "$ref": "#/components/parameters/RequestId"
          },
          {
            "$ref": "#/components/parameters/Traceparent"
          },
          {
            "$ref": "#/components/parameters/Tracestate"
          },
          {
            "$ref": "#/components/parameters/AcceptLanguage"
          }
        ],
        "x-codeSamples": [
          {
            "lang": "cURL",
            "label": "cURL",
            "source": "curl -X POST \"https://api.kangopenbanking.com/v1/auth/pin/set\" \\\n  -H \"Authorization: Bearer $KOB_ACCESS_TOKEN\" \\\n  -H \"Content-Type: application/json\" \\\n  -d '{}'"
          },
          {
            "lang": "JavaScript",
            "label": "Node.js",
            "source": "import { KangOpenBanking } from \"@kangopenbanking/sdk\";\n\nconst kob = new KangOpenBanking({ apiKey: process.env.KOB_API_KEY });\nconst res = await kob.request(\"POST\", \"/v1/auth/pin/set\", { /* payload */ });\nconsole.log(res);"
          },
          {
            "lang": "Python",
            "label": "Python",
            "source": "from kangopenbanking import KangOpenBanking\n\nkob = KangOpenBanking(api_key=os.environ[\"KOB_API_KEY\"])\nres = kob.request(\"POST\", \"/v1/auth/pin/set\", json={})\nprint(res)"
          },
          {
            "lang": "PHP",
            "label": "PHP",
            "source": "<?php\n$kob = new KangOpenBanking\\KangOpenBanking(getenv('KOB_API_KEY'));\n$res = $kob->request('POST', '/v1/auth/pin/set', []);\nprint_r($res);"
          }
        ]
      }
    },
    "/v1/auth/pin/verify": {
      "post": {
        "tags": [
          "Authentication"
        ],
        "summary": "Verify PIN code",
        "operationId": "pinCodeVerify",
        "security": [
          {
            "bearerAuth": []
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "required": [
                  "pin"
                ],
                "properties": {
                  "pin": {
                    "type": "string"
                  }
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "PIN verified",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "success": {
                      "type": "boolean",
                      "example": true
                    },
                    "message": {
                      "type": "string"
                    }
                  }
                },
                "example": {
                  "success": true,
                  "message": "string"
                }
              }
            },
            "headers": {
              "x-fapi-interaction-id": {
                "$ref": "#/components/headers/XFapiInteractionIdResponse"
              },
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/XRateLimitLimit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/XRateLimitRemaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/XRateLimitReset"
              },
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              },
              "traceparent": {
                "$ref": "#/components/headers/Traceparent"
              },
              "Content-Language": {
                "$ref": "#/components/headers/Content-Language"
              }
            }
          },
          "400": {
            "description": "Bad request",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              },
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                },
                "examples": {
                  "error": {
                    "$ref": "#/components/examples/ErrorBadRequest"
                  }
                }
              }
            },
            "headers": {
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/XRateLimitLimit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/XRateLimitRemaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/XRateLimitReset"
              },
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "403": {
            "$ref": "#/components/responses/Forbidden",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "404": {
            "$ref": "#/components/responses/NotFound",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "409": {
            "$ref": "#/components/responses/Conflict",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "429": {
            "$ref": "#/components/responses/TooManyRequests",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "500": {
            "$ref": "#/components/responses/InternalServerError",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          }
        },
        "parameters": [
          {
            "$ref": "#/components/parameters/RequestId"
          },
          {
            "$ref": "#/components/parameters/Traceparent"
          },
          {
            "$ref": "#/components/parameters/Tracestate"
          },
          {
            "$ref": "#/components/parameters/AcceptLanguage"
          }
        ],
        "x-codeSamples": [
          {
            "lang": "cURL",
            "label": "cURL",
            "source": "curl -X POST \"https://api.kangopenbanking.com/v1/auth/pin/verify\" \\\n  -H \"Authorization: Bearer $KOB_ACCESS_TOKEN\" \\\n  -H \"Content-Type: application/json\" \\\n  -d '{}'"
          },
          {
            "lang": "JavaScript",
            "label": "Node.js",
            "source": "import { KangOpenBanking } from \"@kangopenbanking/sdk\";\n\nconst kob = new KangOpenBanking({ apiKey: process.env.KOB_API_KEY });\nconst res = await kob.request(\"POST\", \"/v1/auth/pin/verify\", { /* payload */ });\nconsole.log(res);"
          },
          {
            "lang": "Python",
            "label": "Python",
            "source": "from kangopenbanking import KangOpenBanking\n\nkob = KangOpenBanking(api_key=os.environ[\"KOB_API_KEY\"])\nres = kob.request(\"POST\", \"/v1/auth/pin/verify\", json={})\nprint(res)"
          },
          {
            "lang": "PHP",
            "label": "PHP",
            "source": "<?php\n$kob = new KangOpenBanking\\KangOpenBanking(getenv('KOB_API_KEY'));\n$res = $kob->request('POST', '/v1/auth/pin/verify', []);\nprint_r($res);"
          }
        ]
      }
    },
    "/v1/auth/password/reset-with-pin": {
      "post": {
        "tags": [
          "Authentication"
        ],
        "summary": "Reset password with PIN",
        "operationId": "passwordResetWithPin",
        "security": [],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "required": [
                  "phone_number",
                  "pin",
                  "new_password"
                ],
                "properties": {
                  "phone_number": {
                    "type": "string"
                  },
                  "pin": {
                    "type": "string"
                  },
                  "new_password": {
                    "type": "string"
                  }
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Password reset",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "success": {
                      "type": "boolean",
                      "example": true
                    },
                    "message": {
                      "type": "string"
                    }
                  }
                },
                "example": {
                  "success": true,
                  "message": "string"
                }
              }
            },
            "headers": {
              "x-fapi-interaction-id": {
                "$ref": "#/components/headers/XFapiInteractionIdResponse"
              },
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/XRateLimitLimit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/XRateLimitRemaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/XRateLimitReset"
              },
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              },
              "traceparent": {
                "$ref": "#/components/headers/Traceparent"
              },
              "Content-Language": {
                "$ref": "#/components/headers/Content-Language"
              }
            }
          },
          "400": {
            "description": "Bad request",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              },
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                },
                "examples": {
                  "error": {
                    "$ref": "#/components/examples/ErrorBadRequest"
                  }
                }
              }
            },
            "headers": {
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/XRateLimitLimit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/XRateLimitRemaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/XRateLimitReset"
              },
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "403": {
            "$ref": "#/components/responses/Forbidden",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "404": {
            "$ref": "#/components/responses/NotFound",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "409": {
            "$ref": "#/components/responses/Conflict",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "429": {
            "$ref": "#/components/responses/TooManyRequests",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "500": {
            "$ref": "#/components/responses/InternalServerError",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          }
        },
        "parameters": [
          {
            "$ref": "#/components/parameters/RequestId"
          },
          {
            "$ref": "#/components/parameters/Traceparent"
          },
          {
            "$ref": "#/components/parameters/Tracestate"
          },
          {
            "$ref": "#/components/parameters/AcceptLanguage"
          }
        ],
        "x-codeSamples": [
          {
            "lang": "cURL",
            "label": "cURL",
            "source": "curl -X POST \"https://api.kangopenbanking.com/v1/auth/password/reset-with-pin\" \\\n  -H \"Authorization: Bearer $KOB_ACCESS_TOKEN\" \\\n  -H \"Content-Type: application/json\" \\\n  -d '{}'"
          },
          {
            "lang": "JavaScript",
            "label": "Node.js",
            "source": "import { KangOpenBanking } from \"@kangopenbanking/sdk\";\n\nconst kob = new KangOpenBanking({ apiKey: process.env.KOB_API_KEY });\nconst res = await kob.request(\"POST\", \"/v1/auth/password/reset-with-pin\", { /* payload */ });\nconsole.log(res);"
          },
          {
            "lang": "Python",
            "label": "Python",
            "source": "from kangopenbanking import KangOpenBanking\n\nkob = KangOpenBanking(api_key=os.environ[\"KOB_API_KEY\"])\nres = kob.request(\"POST\", \"/v1/auth/password/reset-with-pin\", json={})\nprint(res)"
          },
          {
            "lang": "PHP",
            "label": "PHP",
            "source": "<?php\n$kob = new KangOpenBanking\\KangOpenBanking(getenv('KOB_API_KEY'));\n$res = $kob->request('POST', '/v1/auth/password/reset-with-pin', []);\nprint_r($res);"
          }
        ]
      }
    },
    "/v1/security/captcha/generate": {
      "post": {
        "tags": [
          "Security"
        ],
        "summary": "Generate CAPTCHA",
        "operationId": "captchaGenerate",
        "security": [],
        "responses": {
          "200": {
            "description": "CAPTCHA challenge",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "challenge_id": {
                      "type": "string",
                      "format": "uuid"
                    },
                    "image_base64": {
                      "type": "string"
                    },
                    "question": {
                      "type": "string"
                    },
                    "expires_at": {
                      "type": "string",
                      "format": "date-time"
                    }
                  }
                },
                "example": {
                  "challenge_id": "00000000-0000-4000-8000-000000000000",
                  "image_base64": "string",
                  "question": "string",
                  "expires_at": "2026-01-01T00:00:00Z"
                }
              }
            },
            "headers": {
              "x-fapi-interaction-id": {
                "$ref": "#/components/headers/XFapiInteractionIdResponse"
              },
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/XRateLimitLimit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/XRateLimitRemaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/XRateLimitReset"
              },
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              },
              "traceparent": {
                "$ref": "#/components/headers/Traceparent"
              },
              "Content-Language": {
                "$ref": "#/components/headers/Content-Language"
              }
            }
          },
          "400": {
            "description": "Bad request",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              },
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                },
                "examples": {
                  "error": {
                    "$ref": "#/components/examples/ErrorBadRequest"
                  }
                }
              }
            },
            "headers": {
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/XRateLimitLimit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/XRateLimitRemaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/XRateLimitReset"
              },
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "403": {
            "$ref": "#/components/responses/Forbidden",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "404": {
            "$ref": "#/components/responses/NotFound",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "409": {
            "$ref": "#/components/responses/Conflict",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "429": {
            "$ref": "#/components/responses/TooManyRequests",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "500": {
            "$ref": "#/components/responses/InternalServerError",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          }
        },
        "parameters": [
          {
            "$ref": "#/components/parameters/RequestId"
          },
          {
            "$ref": "#/components/parameters/Traceparent"
          },
          {
            "$ref": "#/components/parameters/Tracestate"
          },
          {
            "$ref": "#/components/parameters/AcceptLanguage"
          }
        ],
        "x-codeSamples": [
          {
            "lang": "cURL",
            "label": "cURL",
            "source": "curl -X POST \"https://api.kangopenbanking.com/v1/security/captcha/generate\" \\\n  -H \"Authorization: Bearer $KOB_ACCESS_TOKEN\" \\\n  -H \"Content-Type: application/json\""
          },
          {
            "lang": "JavaScript",
            "label": "Node.js",
            "source": "import { KangOpenBanking } from \"@kangopenbanking/sdk\";\n\nconst kob = new KangOpenBanking({ apiKey: process.env.KOB_API_KEY });\nconst res = await kob.request(\"POST\", \"/v1/security/captcha/generate\");\nconsole.log(res);"
          },
          {
            "lang": "Python",
            "label": "Python",
            "source": "from kangopenbanking import KangOpenBanking\n\nkob = KangOpenBanking(api_key=os.environ[\"KOB_API_KEY\"])\nres = kob.request(\"POST\", \"/v1/security/captcha/generate\")\nprint(res)"
          },
          {
            "lang": "PHP",
            "label": "PHP",
            "source": "<?php\n$kob = new KangOpenBanking\\KangOpenBanking(getenv('KOB_API_KEY'));\n$res = $kob->request('POST', '/v1/security/captcha/generate');\nprint_r($res);"
          }
        ]
      }
    },
    "/v1/security/captcha/verify": {
      "post": {
        "tags": [
          "Security"
        ],
        "summary": "Verify CAPTCHA",
        "operationId": "captchaVerify",
        "security": [],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "required": [
                  "challenge_id",
                  "response"
                ],
                "properties": {
                  "challenge_id": {
                    "type": "string"
                  },
                  "response": {
                    "type": "string"
                  }
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "CAPTCHA verified",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "success": {
                      "type": "boolean",
                      "example": true
                    },
                    "message": {
                      "type": "string"
                    }
                  }
                },
                "example": {
                  "success": true,
                  "message": "string"
                }
              }
            },
            "headers": {
              "x-fapi-interaction-id": {
                "$ref": "#/components/headers/XFapiInteractionIdResponse"
              },
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/XRateLimitLimit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/XRateLimitRemaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/XRateLimitReset"
              },
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              },
              "traceparent": {
                "$ref": "#/components/headers/Traceparent"
              },
              "Content-Language": {
                "$ref": "#/components/headers/Content-Language"
              }
            }
          },
          "400": {
            "description": "Bad request",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              },
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                },
                "examples": {
                  "error": {
                    "$ref": "#/components/examples/ErrorBadRequest"
                  }
                }
              }
            },
            "headers": {
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/XRateLimitLimit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/XRateLimitRemaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/XRateLimitReset"
              },
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "403": {
            "$ref": "#/components/responses/Forbidden",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "404": {
            "$ref": "#/components/responses/NotFound",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "409": {
            "$ref": "#/components/responses/Conflict",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "429": {
            "$ref": "#/components/responses/TooManyRequests",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "500": {
            "$ref": "#/components/responses/InternalServerError",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          }
        },
        "parameters": [
          {
            "$ref": "#/components/parameters/RequestId"
          },
          {
            "$ref": "#/components/parameters/Traceparent"
          },
          {
            "$ref": "#/components/parameters/Tracestate"
          },
          {
            "$ref": "#/components/parameters/AcceptLanguage"
          }
        ],
        "x-codeSamples": [
          {
            "lang": "cURL",
            "label": "cURL",
            "source": "curl -X POST \"https://api.kangopenbanking.com/v1/security/captcha/verify\" \\\n  -H \"Authorization: Bearer $KOB_ACCESS_TOKEN\" \\\n  -H \"Content-Type: application/json\" \\\n  -d '{}'"
          },
          {
            "lang": "JavaScript",
            "label": "Node.js",
            "source": "import { KangOpenBanking } from \"@kangopenbanking/sdk\";\n\nconst kob = new KangOpenBanking({ apiKey: process.env.KOB_API_KEY });\nconst res = await kob.request(\"POST\", \"/v1/security/captcha/verify\", { /* payload */ });\nconsole.log(res);"
          },
          {
            "lang": "Python",
            "label": "Python",
            "source": "from kangopenbanking import KangOpenBanking\n\nkob = KangOpenBanking(api_key=os.environ[\"KOB_API_KEY\"])\nres = kob.request(\"POST\", \"/v1/security/captcha/verify\", json={})\nprint(res)"
          },
          {
            "lang": "PHP",
            "label": "PHP",
            "source": "<?php\n$kob = new KangOpenBanking\\KangOpenBanking(getenv('KOB_API_KEY'));\n$res = $kob->request('POST', '/v1/security/captcha/verify', []);\nprint_r($res);"
          }
        ]
      }
    },
    "/v1/security/sca/initiate": {
      "post": {
        "tags": [
          "Security"
        ],
        "summary": "Initiate SCA",
        "operationId": "scaInitiate",
        "security": [
          {
            "bearerAuth": []
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "required": [
                  "action_type"
                ],
                "properties": {
                  "action_type": {
                    "type": "string",
                    "enum": [
                      "payment",
                      "consent",
                      "account_update"
                    ]
                  }
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "SCA challenge issued",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "challenge_id": {
                      "type": "string",
                      "format": "uuid"
                    },
                    "challenge_type": {
                      "type": "string",
                      "enum": [
                        "otp",
                        "biometric",
                        "pin"
                      ]
                    },
                    "expires_at": {
                      "type": "string",
                      "format": "date-time"
                    }
                  }
                },
                "example": {
                  "challenge_id": "00000000-0000-4000-8000-000000000000",
                  "challenge_type": "otp",
                  "expires_at": "2026-01-01T00:00:00Z"
                }
              }
            },
            "headers": {
              "x-fapi-interaction-id": {
                "$ref": "#/components/headers/XFapiInteractionIdResponse"
              },
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/XRateLimitLimit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/XRateLimitRemaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/XRateLimitReset"
              },
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              },
              "traceparent": {
                "$ref": "#/components/headers/Traceparent"
              },
              "Content-Language": {
                "$ref": "#/components/headers/Content-Language"
              }
            }
          },
          "400": {
            "description": "Bad request",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              },
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                },
                "examples": {
                  "error": {
                    "$ref": "#/components/examples/ErrorBadRequest"
                  }
                }
              }
            },
            "headers": {
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/XRateLimitLimit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/XRateLimitRemaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/XRateLimitReset"
              },
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "403": {
            "$ref": "#/components/responses/Forbidden",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "404": {
            "$ref": "#/components/responses/NotFound",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "409": {
            "$ref": "#/components/responses/Conflict",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "429": {
            "$ref": "#/components/responses/TooManyRequests",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "500": {
            "$ref": "#/components/responses/InternalServerError",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          }
        },
        "parameters": [
          {
            "$ref": "#/components/parameters/RequestId"
          },
          {
            "$ref": "#/components/parameters/Traceparent"
          },
          {
            "$ref": "#/components/parameters/Tracestate"
          },
          {
            "$ref": "#/components/parameters/AcceptLanguage"
          }
        ],
        "x-codeSamples": [
          {
            "lang": "cURL",
            "label": "cURL",
            "source": "curl -X POST \"https://api.kangopenbanking.com/v1/security/sca/initiate\" \\\n  -H \"Authorization: Bearer $KOB_ACCESS_TOKEN\" \\\n  -H \"Content-Type: application/json\" \\\n  -d '{}'"
          },
          {
            "lang": "JavaScript",
            "label": "Node.js",
            "source": "import { KangOpenBanking } from \"@kangopenbanking/sdk\";\n\nconst kob = new KangOpenBanking({ apiKey: process.env.KOB_API_KEY });\nconst res = await kob.request(\"POST\", \"/v1/security/sca/initiate\", { /* payload */ });\nconsole.log(res);"
          },
          {
            "lang": "Python",
            "label": "Python",
            "source": "from kangopenbanking import KangOpenBanking\n\nkob = KangOpenBanking(api_key=os.environ[\"KOB_API_KEY\"])\nres = kob.request(\"POST\", \"/v1/security/sca/initiate\", json={})\nprint(res)"
          },
          {
            "lang": "PHP",
            "label": "PHP",
            "source": "<?php\n$kob = new KangOpenBanking\\KangOpenBanking(getenv('KOB_API_KEY'));\n$res = $kob->request('POST', '/v1/security/sca/initiate', []);\nprint_r($res);"
          }
        ]
      }
    },
    "/v1/security/sca/verify": {
      "post": {
        "tags": [
          "Security"
        ],
        "summary": "Verify SCA",
        "operationId": "scaVerify",
        "security": [
          {
            "bearerAuth": []
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "required": [
                  "challenge_id",
                  "response"
                ],
                "properties": {
                  "challenge_id": {
                    "type": "string"
                  },
                  "response": {
                    "type": "string"
                  }
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "SCA verified",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "success": {
                      "type": "boolean",
                      "example": true
                    },
                    "message": {
                      "type": "string"
                    }
                  }
                },
                "example": {
                  "success": true,
                  "message": "string"
                }
              }
            },
            "headers": {
              "x-fapi-interaction-id": {
                "$ref": "#/components/headers/XFapiInteractionIdResponse"
              },
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/XRateLimitLimit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/XRateLimitRemaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/XRateLimitReset"
              },
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              },
              "traceparent": {
                "$ref": "#/components/headers/Traceparent"
              },
              "Content-Language": {
                "$ref": "#/components/headers/Content-Language"
              }
            }
          },
          "400": {
            "description": "Bad request",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              },
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                },
                "examples": {
                  "error": {
                    "$ref": "#/components/examples/ErrorBadRequest"
                  }
                }
              }
            },
            "headers": {
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/XRateLimitLimit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/XRateLimitRemaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/XRateLimitReset"
              },
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "403": {
            "$ref": "#/components/responses/Forbidden",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "404": {
            "$ref": "#/components/responses/NotFound",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "409": {
            "$ref": "#/components/responses/Conflict",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "429": {
            "$ref": "#/components/responses/TooManyRequests",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "500": {
            "$ref": "#/components/responses/InternalServerError",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          }
        },
        "parameters": [
          {
            "$ref": "#/components/parameters/RequestId"
          },
          {
            "$ref": "#/components/parameters/Traceparent"
          },
          {
            "$ref": "#/components/parameters/Tracestate"
          },
          {
            "$ref": "#/components/parameters/AcceptLanguage"
          }
        ],
        "x-codeSamples": [
          {
            "lang": "cURL",
            "label": "cURL",
            "source": "curl -X POST \"https://api.kangopenbanking.com/v1/security/sca/verify\" \\\n  -H \"Authorization: Bearer $KOB_ACCESS_TOKEN\" \\\n  -H \"Content-Type: application/json\" \\\n  -d '{}'"
          },
          {
            "lang": "JavaScript",
            "label": "Node.js",
            "source": "import { KangOpenBanking } from \"@kangopenbanking/sdk\";\n\nconst kob = new KangOpenBanking({ apiKey: process.env.KOB_API_KEY });\nconst res = await kob.request(\"POST\", \"/v1/security/sca/verify\", { /* payload */ });\nconsole.log(res);"
          },
          {
            "lang": "Python",
            "label": "Python",
            "source": "from kangopenbanking import KangOpenBanking\n\nkob = KangOpenBanking(api_key=os.environ[\"KOB_API_KEY\"])\nres = kob.request(\"POST\", \"/v1/security/sca/verify\", json={})\nprint(res)"
          },
          {
            "lang": "PHP",
            "label": "PHP",
            "source": "<?php\n$kob = new KangOpenBanking\\KangOpenBanking(getenv('KOB_API_KEY'));\n$res = $kob->request('POST', '/v1/security/sca/verify', []);\nprint_r($res);"
          }
        ]
      }
    },
    "/v1/certificates": {
      "post": {
        "tags": [
          "Certificates"
        ],
        "summary": "Upload certificate",
        "operationId": "certificateUpload",
        "security": [
          {
            "bearerAuth": []
          }
        ],
        "parameters": [
          {
            "name": "Idempotency-Key",
            "in": "header",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid"
            },
            "description": "Required on all POST/PUT endpoints. Unique key for idempotent request processing (UUID v4 recommended). Keys expire after 24 hours."
          },
          {
            "$ref": "#/components/parameters/RequestId"
          },
          {
            "$ref": "#/components/parameters/Traceparent"
          },
          {
            "$ref": "#/components/parameters/Tracestate"
          },
          {
            "$ref": "#/components/parameters/AcceptLanguage"
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "required": [
                  "certificate_pem"
                ],
                "properties": {
                  "certificate_pem": {
                    "type": "string"
                  },
                  "tpp_registration_id": {
                    "type": "string"
                  }
                }
              }
            }
          }
        },
        "responses": {
          "201": {
            "description": "Certificate uploaded",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Certificate"
                },
                "example": {
                  "id": "00000000-0000-4000-8000-000000000000",
                  "thumbprint": "string",
                  "fingerprint": "string",
                  "subject_dn": "string",
                  "issuer_dn": "string",
                  "serial_number": "string",
                  "valid_from": "2026-01-01T00:00:00Z",
                  "valid_until": "2026-01-01T00:00:00Z",
                  "is_revoked": true
                }
              }
            },
            "headers": {
              "x-fapi-interaction-id": {
                "$ref": "#/components/headers/XFapiInteractionIdResponse"
              },
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/XRateLimitLimit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/XRateLimitRemaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/XRateLimitReset"
              },
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              },
              "traceparent": {
                "$ref": "#/components/headers/Traceparent"
              },
              "Content-Language": {
                "$ref": "#/components/headers/Content-Language"
              }
            }
          },
          "400": {
            "description": "Bad request",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              },
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                },
                "examples": {
                  "error": {
                    "$ref": "#/components/examples/ErrorBadRequest"
                  }
                }
              }
            },
            "headers": {
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/XRateLimitLimit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/XRateLimitRemaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/XRateLimitReset"
              },
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "403": {
            "$ref": "#/components/responses/Forbidden",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "404": {
            "$ref": "#/components/responses/NotFound",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "409": {
            "$ref": "#/components/responses/Conflict",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "429": {
            "$ref": "#/components/responses/TooManyRequests",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "500": {
            "$ref": "#/components/responses/InternalServerError",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          }
        },
        "x-codeSamples": [
          {
            "lang": "cURL",
            "label": "cURL",
            "source": "curl -X POST \"https://api.kangopenbanking.com/v1/certificates\" \\\n  -H \"Authorization: Bearer $KOB_ACCESS_TOKEN\" \\\n  -H \"Content-Type: application/json\" \\\n  -d '{}'"
          },
          {
            "lang": "JavaScript",
            "label": "Node.js",
            "source": "import { KangOpenBanking } from \"@kangopenbanking/sdk\";\n\nconst kob = new KangOpenBanking({ apiKey: process.env.KOB_API_KEY });\nconst res = await kob.request(\"POST\", \"/v1/certificates\", { /* payload */ });\nconsole.log(res);"
          },
          {
            "lang": "Python",
            "label": "Python",
            "source": "from kangopenbanking import KangOpenBanking\n\nkob = KangOpenBanking(api_key=os.environ[\"KOB_API_KEY\"])\nres = kob.request(\"POST\", \"/v1/certificates\", json={})\nprint(res)"
          },
          {
            "lang": "PHP",
            "label": "PHP",
            "source": "<?php\n$kob = new KangOpenBanking\\KangOpenBanking(getenv('KOB_API_KEY'));\n$res = $kob->request('POST', '/v1/certificates', []);\nprint_r($res);"
          }
        ]
      },
      "get": {
        "tags": [
          "Certificates"
        ],
        "summary": "List certificates",
        "operationId": "certificateList",
        "security": [
          {
            "bearerAuth": []
          }
        ],
        "parameters": [
          {
            "name": "tpp_registration_id",
            "in": "query",
            "schema": {
              "type": "string"
            }
          },
          {
            "$ref": "#/components/parameters/PageParam"
          },
          {
            "$ref": "#/components/parameters/LimitParam"
          },
          {
            "$ref": "#/components/parameters/CursorParam"
          },
          {
            "$ref": "#/components/parameters/RequestId"
          },
          {
            "$ref": "#/components/parameters/Traceparent"
          },
          {
            "$ref": "#/components/parameters/Tracestate"
          },
          {
            "$ref": "#/components/parameters/AcceptLanguage"
          }
        ],
        "responses": {
          "200": {
            "description": "Certificates list",
            "content": {
              "application/json": {
                "schema": {
                  "allOf": [
                    {
                      "$ref": "#/components/schemas/PaginatedResponse"
                    },
                    {
                      "type": "object",
                      "properties": {
                        "data": {
                          "type": "array",
                          "items": {
                            "$ref": "#/components/schemas/Certificate"
                          }
                        }
                      }
                    }
                  ]
                },
                "example": {
                  "data": [
                    {
                      "id": "f1d6f4a0-1d4e-4a3a-9e0a-1a2b3c4d5e6f",
                      "thumbprint": "XAF",
                      "fingerprint": "XAF",
                      "subject_dn": "XAF",
                      "issuer_dn": "XAF",
                      "serial_number": "XAF",
                      "valid_from": "2026-01-31T12:00:00Z",
                      "valid_until": "2026-01-31T12:00:00Z",
                      "is_revoked": false
                    }
                  ],
                  "pagination": {
                    "page": 1,
                    "limit": 20,
                    "total": 150,
                    "has_next": true,
                    "next_cursor": "eyJpZCI6IjEyMyJ9"
                  },
                  "meta": {
                    "request_id": "550e8400-e29b-41d4-a716-446655440000",
                    "timestamp": "2025-03-27T12:00:00Z",
                    "api_version": "4.3.0"
                  }
                }
              }
            },
            "headers": {
              "x-fapi-interaction-id": {
                "$ref": "#/components/headers/XFapiInteractionIdResponse"
              },
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/XRateLimitLimit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/XRateLimitRemaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/XRateLimitReset"
              },
              "Cache-Control": {
                "$ref": "#/components/headers/CacheControl"
              },
              "ETag": {
                "$ref": "#/components/headers/ETag"
              },
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              },
              "traceparent": {
                "$ref": "#/components/headers/Traceparent"
              },
              "Content-Language": {
                "$ref": "#/components/headers/Content-Language"
              }
            }
          },
          "400": {
            "description": "Bad request",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              },
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                },
                "examples": {
                  "error": {
                    "$ref": "#/components/examples/ErrorBadRequest"
                  }
                }
              }
            },
            "headers": {
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/XRateLimitLimit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/XRateLimitRemaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/XRateLimitReset"
              },
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "403": {
            "$ref": "#/components/responses/Forbidden",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "404": {
            "$ref": "#/components/responses/NotFound",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "409": {
            "$ref": "#/components/responses/Conflict",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "429": {
            "$ref": "#/components/responses/TooManyRequests",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "500": {
            "$ref": "#/components/responses/InternalServerError",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          }
        },
        "x-codeSamples": [
          {
            "lang": "cURL",
            "label": "cURL",
            "source": "curl -X GET \"https://api.kangopenbanking.com/v1/certificates\" \\\n  -H \"Authorization: Bearer $KOB_ACCESS_TOKEN\" \\\n  -H \"Content-Type: application/json\""
          },
          {
            "lang": "JavaScript",
            "label": "Node.js",
            "source": "import { KangOpenBanking } from \"@kangopenbanking/sdk\";\n\nconst kob = new KangOpenBanking({ apiKey: process.env.KOB_API_KEY });\nconst res = await kob.request(\"GET\", \"/v1/certificates\");\nconsole.log(res);"
          },
          {
            "lang": "Python",
            "label": "Python",
            "source": "from kangopenbanking import KangOpenBanking\n\nkob = KangOpenBanking(api_key=os.environ[\"KOB_API_KEY\"])\nres = kob.request(\"GET\", \"/v1/certificates\")\nprint(res)"
          },
          {
            "lang": "PHP",
            "label": "PHP",
            "source": "<?php\n$kob = new KangOpenBanking\\KangOpenBanking(getenv('KOB_API_KEY'));\n$res = $kob->request('GET', '/v1/certificates');\nprint_r($res);"
          }
        ]
      }
    },
    "/v1/certificates/revoke": {
      "post": {
        "tags": [
          "Certificates"
        ],
        "summary": "Revoke certificate",
        "operationId": "certificateRevoke",
        "security": [
          {
            "bearerAuth": []
          }
        ],
        "parameters": [
          {
            "name": "Idempotency-Key",
            "in": "header",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid"
            },
            "description": "Required on all POST/PUT endpoints. Unique key for idempotent request processing (UUID v4 recommended). Keys expire after 24 hours."
          },
          {
            "$ref": "#/components/parameters/RequestId"
          },
          {
            "$ref": "#/components/parameters/Traceparent"
          },
          {
            "$ref": "#/components/parameters/Tracestate"
          },
          {
            "$ref": "#/components/parameters/AcceptLanguage"
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "required": [
                  "certificate_id",
                  "reason"
                ],
                "properties": {
                  "certificate_id": {
                    "type": "string"
                  },
                  "reason": {
                    "type": "string",
                    "enum": [
                      "key_compromise",
                      "ca_compromise",
                      "affiliation_changed",
                      "superseded",
                      "cessation_of_operation"
                    ]
                  }
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Certificate revoked",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "success": {
                      "type": "boolean",
                      "example": true
                    },
                    "message": {
                      "type": "string"
                    }
                  }
                },
                "example": {
                  "success": true,
                  "message": "string"
                }
              }
            },
            "headers": {
              "x-fapi-interaction-id": {
                "$ref": "#/components/headers/XFapiInteractionIdResponse"
              },
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/XRateLimitLimit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/XRateLimitRemaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/XRateLimitReset"
              },
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              },
              "traceparent": {
                "$ref": "#/components/headers/Traceparent"
              },
              "Content-Language": {
                "$ref": "#/components/headers/Content-Language"
              }
            }
          },
          "400": {
            "description": "Bad request",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              },
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                },
                "examples": {
                  "error": {
                    "$ref": "#/components/examples/ErrorBadRequest"
                  }
                }
              }
            },
            "headers": {
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/XRateLimitLimit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/XRateLimitRemaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/XRateLimitReset"
              },
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "403": {
            "$ref": "#/components/responses/Forbidden",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "404": {
            "$ref": "#/components/responses/NotFound",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "409": {
            "$ref": "#/components/responses/Conflict",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "429": {
            "$ref": "#/components/responses/TooManyRequests",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "500": {
            "$ref": "#/components/responses/InternalServerError",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          }
        },
        "x-codeSamples": [
          {
            "lang": "cURL",
            "label": "cURL",
            "source": "curl -X POST \"https://api.kangopenbanking.com/v1/certificates/revoke\" \\\n  -H \"Authorization: Bearer $KOB_ACCESS_TOKEN\" \\\n  -H \"Content-Type: application/json\" \\\n  -d '{}'"
          },
          {
            "lang": "JavaScript",
            "label": "Node.js",
            "source": "import { KangOpenBanking } from \"@kangopenbanking/sdk\";\n\nconst kob = new KangOpenBanking({ apiKey: process.env.KOB_API_KEY });\nconst res = await kob.request(\"POST\", \"/v1/certificates/revoke\", { /* payload */ });\nconsole.log(res);"
          },
          {
            "lang": "Python",
            "label": "Python",
            "source": "from kangopenbanking import KangOpenBanking\n\nkob = KangOpenBanking(api_key=os.environ[\"KOB_API_KEY\"])\nres = kob.request(\"POST\", \"/v1/certificates/revoke\", json={})\nprint(res)"
          },
          {
            "lang": "PHP",
            "label": "PHP",
            "source": "<?php\n$kob = new KangOpenBanking\\KangOpenBanking(getenv('KOB_API_KEY'));\n$res = $kob->request('POST', '/v1/certificates/revoke', []);\nprint_r($res);"
          }
        ]
      }
    },
    "/v1/aisp/consents": {
      "post": {
        "tags": [
          "AISP"
        ],
        "summary": "Create AISP consent",
        "operationId": "aispCreateConsent",
        "security": [
          {
            "bearerAuth": []
          }
        ],
        "parameters": [
          {
            "name": "Idempotency-Key",
            "in": "header",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid"
            },
            "description": "Required on all POST/PUT endpoints. Unique key for idempotent request processing (UUID v4 recommended). Keys expire after 24 hours."
          },
          {
            "$ref": "#/components/parameters/RequestId"
          },
          {
            "$ref": "#/components/parameters/Traceparent"
          },
          {
            "$ref": "#/components/parameters/Tracestate"
          },
          {
            "$ref": "#/components/parameters/AcceptLanguage"
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "required": [
                  "permissions",
                  "expiration_date"
                ],
                "properties": {
                  "permissions": {
                    "type": "array",
                    "items": {
                      "type": "string",
                      "enum": [
                        "ReadAccountsDetail",
                        "ReadBalances",
                        "ReadTransactionsDetail",
                        "ReadBeneficiariesDetail",
                        "ReadStandingOrdersDetail",
                        "ReadDirectDebitsDetail"
                      ]
                    },
                    "example": [
                      "ReadAccountsDetail",
                      "ReadBalances",
                      "ReadTransactionsDetail"
                    ]
                  },
                  "expiration_date": {
                    "type": "string",
                    "format": "date-time"
                  },
                  "transaction_from_date": {
                    "type": "string",
                    "format": "date"
                  },
                  "transaction_to_date": {
                    "type": "string",
                    "format": "date"
                  }
                }
              }
            }
          }
        },
        "responses": {
          "201": {
            "description": "Consent created",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Consent"
                },
                "example": {
                  "consent_id": "string",
                  "status": "AwaitingAuthorisation",
                  "permissions": [
                    "string"
                  ],
                  "expiration_date": "2026-01-01T00:00:00Z",
                  "created_at": "2026-01-01T00:00:00Z"
                }
              }
            },
            "headers": {
              "x-fapi-interaction-id": {
                "$ref": "#/components/headers/XFapiInteractionIdResponse"
              },
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/XRateLimitLimit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/XRateLimitRemaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/XRateLimitReset"
              },
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              },
              "traceparent": {
                "$ref": "#/components/headers/Traceparent"
              },
              "Content-Language": {
                "$ref": "#/components/headers/Content-Language"
              }
            }
          },
          "400": {
            "description": "Bad request",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              },
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                },
                "examples": {
                  "error": {
                    "$ref": "#/components/examples/ErrorBadRequest"
                  }
                }
              }
            },
            "headers": {
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/XRateLimitLimit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/XRateLimitRemaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/XRateLimitReset"
              },
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "403": {
            "$ref": "#/components/responses/Forbidden",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "404": {
            "$ref": "#/components/responses/NotFound",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "409": {
            "$ref": "#/components/responses/Conflict",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "429": {
            "$ref": "#/components/responses/TooManyRequests",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "500": {
            "$ref": "#/components/responses/InternalServerError",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          }
        },
        "x-codeSamples": [
          {
            "lang": "cURL",
            "label": "cURL",
            "source": "curl -X POST \"https://api.kangopenbanking.com/v1/aisp/consents\" \\\n  -H \"Authorization: Bearer $KOB_ACCESS_TOKEN\" \\\n  -H \"Content-Type: application/json\" \\\n  -d '{}'"
          },
          {
            "lang": "JavaScript",
            "label": "Node.js",
            "source": "import { KangOpenBanking } from \"@kangopenbanking/sdk\";\n\nconst kob = new KangOpenBanking({ apiKey: process.env.KOB_API_KEY });\nconst res = await kob.request(\"POST\", \"/v1/aisp/consents\", { /* payload */ });\nconsole.log(res);"
          },
          {
            "lang": "Python",
            "label": "Python",
            "source": "from kangopenbanking import KangOpenBanking\n\nkob = KangOpenBanking(api_key=os.environ[\"KOB_API_KEY\"])\nres = kob.request(\"POST\", \"/v1/aisp/consents\", json={})\nprint(res)"
          },
          {
            "lang": "PHP",
            "label": "PHP",
            "source": "<?php\n$kob = new KangOpenBanking\\KangOpenBanking(getenv('KOB_API_KEY'));\n$res = $kob->request('POST', '/v1/aisp/consents', []);\nprint_r($res);"
          }
        ]
      }
    },
    "/v1/aisp/accounts": {
      "get": {
        "tags": [
          "AISP"
        ],
        "summary": "List accounts",
        "operationId": "aispAccounts",
        "security": [
          {
            "bearerAuth": []
          }
        ],
        "parameters": [
          {
            "name": "x-consent-id",
            "in": "header",
            "required": true,
            "schema": {
              "type": "string"
            },
            "description": "Authorised AISP consent ID. Required for all account information endpoints."
          },
          {
            "name": "limit",
            "in": "query",
            "schema": {
              "type": "integer",
              "default": 25,
              "maximum": 100
            },
            "description": "Items per page"
          },
          {
            "name": "offset",
            "in": "query",
            "schema": {
              "type": "integer",
              "default": 0
            },
            "description": "Items to skip Legacy: kept for backwards compatibility — prefer starting_after/ending_before (see x-pagination)."
          },
          {
            "name": "sort_by",
            "in": "query",
            "schema": {
              "type": "string",
              "default": "created_at"
            },
            "description": "Sort field"
          },
          {
            "name": "sort_order",
            "in": "query",
            "schema": {
              "type": "string",
              "enum": [
                "asc",
                "desc"
              ],
              "default": "desc"
            },
            "description": "Sort direction"
          },
          {
            "$ref": "#/components/parameters/XFapiInteractionId"
          },
          {
            "$ref": "#/components/parameters/XFapiCustomerIpAddress"
          },
          {
            "$ref": "#/components/parameters/XFapiAuthDate"
          },
          {
            "name": "starting_after",
            "in": "query",
            "required": false,
            "description": "Cursor pagination — returns the page of results AFTER this resource id. Mutually exclusive with offset/ending_before. Preferred for new integrations (see x-pagination).",
            "schema": {
              "type": "string",
              "example": "acc_01HZQ..."
            }
          },
          {
            "name": "ending_before",
            "in": "query",
            "required": false,
            "description": "Cursor pagination — returns the page of results BEFORE this resource id. Mutually exclusive with offset/starting_after.",
            "schema": {
              "type": "string",
              "example": "acc_01HZQ..."
            }
          },
          {
            "$ref": "#/components/parameters/RequestId"
          },
          {
            "$ref": "#/components/parameters/Traceparent"
          },
          {
            "$ref": "#/components/parameters/Tracestate"
          },
          {
            "$ref": "#/components/parameters/AcceptLanguage"
          }
        ],
        "responses": {
          "200": {
            "description": "Accounts list",
            "content": {
              "application/json": {
                "schema": {
                  "allOf": [
                    {
                      "$ref": "#/components/schemas/PaginatedResponse"
                    },
                    {
                      "type": "object",
                      "properties": {
                        "data": {
                          "type": "array",
                          "items": {
                            "$ref": "#/components/schemas/Account"
                          }
                        }
                      }
                    }
                  ]
                },
                "example": {
                  "data": [
                    {
                      "account_id": "f1d6f4a0-1d4e-4a3a-9e0a-1a2b3c4d5e6f",
                      "account_number": "CM21 10003 00100 0123456789 023",
                      "account_type": "checking",
                      "account_subtype": "personal_current",
                      "identification_scheme": "LOCAL_BANK",
                      "identification_value": "XAF",
                      "currency": "XAF",
                      "balance": "1500000",
                      "account_holder_name": "Jean-Pierre Kamga",
                      "status": "active",
                      "opened_date": "2025-03-15",
                      "rib_bank_code": "10005",
                      "rib_branch_code": "00100",
                      "rib_account_number": "01234567890",
                      "rib_key": "23",
                      "swift_bic": "AFRIACMCXXX",
                      "account_country": "CM"
                    }
                  ],
                  "pagination": {
                    "page": 1,
                    "limit": 20,
                    "total": 150,
                    "has_next": true,
                    "next_cursor": "eyJpZCI6IjEyMyJ9"
                  },
                  "meta": {
                    "request_id": "550e8400-e29b-41d4-a716-446655440000",
                    "timestamp": "2025-03-27T12:00:00Z",
                    "api_version": "4.3.0"
                  }
                }
              }
            },
            "headers": {
              "x-fapi-interaction-id": {
                "$ref": "#/components/headers/XFapiInteractionIdResponse"
              },
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/XRateLimitLimit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/XRateLimitRemaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/XRateLimitReset"
              },
              "Cache-Control": {
                "$ref": "#/components/headers/CacheControl"
              },
              "ETag": {
                "$ref": "#/components/headers/ETag"
              },
              "X-Pagination-Mode": {
                "description": "Either `cursor` or `offset` — echoes which mode the gateway interpreted.",
                "schema": {
                  "type": "string",
                  "enum": [
                    "cursor",
                    "offset"
                  ]
                }
              },
              "X-Pagination-Has-More": {
                "description": "Boolean (`true`/`false`) — whether more results are available.",
                "schema": {
                  "type": "string"
                }
              },
              "X-Pagination-Next-Cursor": {
                "description": "Resource id to pass as `starting_after` for the next page (cursor mode only).",
                "schema": {
                  "type": "string"
                }
              },
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              },
              "traceparent": {
                "$ref": "#/components/headers/Traceparent"
              },
              "Content-Language": {
                "$ref": "#/components/headers/Content-Language"
              }
            }
          },
          "400": {
            "description": "Bad request",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              },
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                },
                "examples": {
                  "error": {
                    "$ref": "#/components/examples/ErrorBadRequest"
                  }
                }
              }
            },
            "headers": {
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/XRateLimitLimit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/XRateLimitRemaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/XRateLimitReset"
              },
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "403": {
            "$ref": "#/components/responses/Forbidden",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "404": {
            "$ref": "#/components/responses/NotFound",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "409": {
            "$ref": "#/components/responses/Conflict",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "429": {
            "$ref": "#/components/responses/TooManyRequests",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "500": {
            "$ref": "#/components/responses/InternalServerError",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          }
        },
        "x-pagination-style": "cursor",
        "x-codeSamples": [
          {
            "lang": "cURL",
            "label": "cURL",
            "source": "curl -X GET \"https://api.kangopenbanking.com/v1/aisp/accounts\" \\\n  -H \"Authorization: Bearer $KOB_ACCESS_TOKEN\" \\\n  -H \"Content-Type: application/json\""
          },
          {
            "lang": "JavaScript",
            "label": "Node.js",
            "source": "import { KangOpenBanking } from \"@kangopenbanking/sdk\";\n\nconst kob = new KangOpenBanking({ apiKey: process.env.KOB_API_KEY });\nconst res = await kob.request(\"GET\", \"/v1/aisp/accounts\");\nconsole.log(res);"
          },
          {
            "lang": "Python",
            "label": "Python",
            "source": "from kangopenbanking import KangOpenBanking\n\nkob = KangOpenBanking(api_key=os.environ[\"KOB_API_KEY\"])\nres = kob.request(\"GET\", \"/v1/aisp/accounts\")\nprint(res)"
          },
          {
            "lang": "PHP",
            "label": "PHP",
            "source": "<?php\n$kob = new KangOpenBanking\\KangOpenBanking(getenv('KOB_API_KEY'));\n$res = $kob->request('GET', '/v1/aisp/accounts');\nprint_r($res);"
          }
        ]
      }
    },
    "/v1/aisp/accounts/{accountId}": {
      "get": {
        "tags": [
          "AISP"
        ],
        "summary": "Get account details",
        "operationId": "aispAccountDetail",
        "security": [
          {
            "bearerAuth": []
          }
        ],
        "parameters": [
          {
            "name": "accountId",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "x-consent-id",
            "in": "header",
            "required": true,
            "schema": {
              "type": "string"
            },
            "description": "Authorised AISP consent ID. Required for all account information endpoints."
          },
          {
            "$ref": "#/components/parameters/XFapiInteractionId"
          },
          {
            "$ref": "#/components/parameters/XFapiCustomerIpAddress"
          },
          {
            "$ref": "#/components/parameters/XFapiAuthDate"
          },
          {
            "$ref": "#/components/parameters/RequestId"
          },
          {
            "$ref": "#/components/parameters/Traceparent"
          },
          {
            "$ref": "#/components/parameters/Tracestate"
          },
          {
            "$ref": "#/components/parameters/AcceptLanguage"
          }
        ],
        "responses": {
          "200": {
            "description": "Account details",
            "content": {
              "application/json": {
                "schema": {
                  "allOf": [
                    {
                      "$ref": "#/components/schemas/StandardResponse"
                    },
                    {
                      "type": "object",
                      "properties": {
                        "data": {
                          "$ref": "#/components/schemas/Account"
                        }
                      }
                    }
                  ]
                },
                "example": {
                  "data": {
                    "account_id": "00000000-0000-4000-8000-000000000000",
                    "account_number": "CM21 10003 00100 0123456789 023",
                    "account_type": "checking",
                    "account_subtype": "personal_current",
                    "identification_scheme": "LOCAL_BANK",
                    "identification_value": "string",
                    "currency": "XAF",
                    "balance": "1500000",
                    "account_holder_name": "Jean-Pierre Kamga",
                    "status": "active",
                    "opened_date": "2025-03-15",
                    "rib_bank_code": "10005",
                    "rib_branch_code": "00100",
                    "rib_account_number": "01234567890",
                    "rib_key": "23",
                    "swift_bic": "AFRIACMCXXX",
                    "account_country": "CM"
                  },
                  "meta": {
                    "request_id": "550e8400-e29b-41d4-a716-446655440000",
                    "timestamp": "2025-03-27T12:00:00Z",
                    "api_version": "4.3.0"
                  }
                }
              }
            },
            "headers": {
              "x-fapi-interaction-id": {
                "$ref": "#/components/headers/XFapiInteractionIdResponse"
              },
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/XRateLimitLimit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/XRateLimitRemaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/XRateLimitReset"
              },
              "Cache-Control": {
                "$ref": "#/components/headers/CacheControl"
              },
              "ETag": {
                "$ref": "#/components/headers/ETag"
              },
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              },
              "traceparent": {
                "$ref": "#/components/headers/Traceparent"
              },
              "Content-Language": {
                "$ref": "#/components/headers/Content-Language"
              }
            }
          },
          "400": {
            "description": "Bad request",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              },
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                },
                "examples": {
                  "error": {
                    "$ref": "#/components/examples/ErrorBadRequest"
                  }
                }
              }
            },
            "headers": {
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/XRateLimitLimit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/XRateLimitRemaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/XRateLimitReset"
              },
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "403": {
            "$ref": "#/components/responses/Forbidden",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "404": {
            "$ref": "#/components/responses/NotFound",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "409": {
            "$ref": "#/components/responses/Conflict",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "429": {
            "$ref": "#/components/responses/TooManyRequests",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "500": {
            "$ref": "#/components/responses/InternalServerError",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          }
        },
        "x-codeSamples": [
          {
            "lang": "cURL",
            "label": "cURL",
            "source": "curl -X GET \"https://api.kangopenbanking.com/v1/aisp/accounts/{accountId}\" \\\n  -H \"Authorization: Bearer $KOB_ACCESS_TOKEN\" \\\n  -H \"Content-Type: application/json\""
          },
          {
            "lang": "JavaScript",
            "label": "Node.js",
            "source": "import { KangOpenBanking } from \"@kangopenbanking/sdk\";\n\nconst kob = new KangOpenBanking({ apiKey: process.env.KOB_API_KEY });\nconst res = await kob.request(\"GET\", \"/v1/aisp/accounts/{accountId}\");\nconsole.log(res);"
          },
          {
            "lang": "Python",
            "label": "Python",
            "source": "from kangopenbanking import KangOpenBanking\n\nkob = KangOpenBanking(api_key=os.environ[\"KOB_API_KEY\"])\nres = kob.request(\"GET\", \"/v1/aisp/accounts/{accountId}\")\nprint(res)"
          },
          {
            "lang": "PHP",
            "label": "PHP",
            "source": "<?php\n$kob = new KangOpenBanking\\KangOpenBanking(getenv('KOB_API_KEY'));\n$res = $kob->request('GET', '/v1/aisp/accounts/{accountId}');\nprint_r($res);"
          }
        ]
      }
    },
    "/v1/aisp/accounts/{accountId}/balances": {
      "get": {
        "tags": [
          "AISP"
        ],
        "summary": "Get account balances",
        "operationId": "aispBalances",
        "security": [
          {
            "bearerAuth": []
          }
        ],
        "parameters": [
          {
            "name": "accountId",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "x-consent-id",
            "in": "header",
            "required": true,
            "schema": {
              "type": "string"
            },
            "description": "Authorised AISP consent ID. Required for all account information endpoints."
          },
          {
            "$ref": "#/components/parameters/XFapiInteractionId"
          },
          {
            "$ref": "#/components/parameters/XFapiCustomerIpAddress"
          },
          {
            "$ref": "#/components/parameters/XFapiAuthDate"
          },
          {
            "$ref": "#/components/parameters/RequestId"
          },
          {
            "$ref": "#/components/parameters/Traceparent"
          },
          {
            "$ref": "#/components/parameters/Tracestate"
          },
          {
            "$ref": "#/components/parameters/AcceptLanguage"
          }
        ],
        "responses": {
          "200": {
            "description": "Account balances",
            "content": {
              "application/json": {
                "schema": {
                  "allOf": [
                    {
                      "$ref": "#/components/schemas/PaginatedResponse"
                    },
                    {
                      "type": "object",
                      "properties": {
                        "data": {
                          "type": "array",
                          "items": {
                            "$ref": "#/components/schemas/Balance"
                          }
                        }
                      }
                    }
                  ]
                },
                "example": {
                  "data": [
                    {
                      "balance_type": "ClosingAvailable",
                      "amount": "1500000",
                      "currency": "XAF",
                      "credit_debit_indicator": "Credit",
                      "date_time": "2026-01-31T12:00:00Z"
                    }
                  ],
                  "pagination": {
                    "page": 1,
                    "limit": 20,
                    "total": 150,
                    "has_next": true,
                    "next_cursor": "eyJpZCI6IjEyMyJ9"
                  },
                  "meta": {
                    "request_id": "550e8400-e29b-41d4-a716-446655440000",
                    "timestamp": "2025-03-27T12:00:00Z",
                    "api_version": "4.3.0"
                  }
                }
              }
            },
            "headers": {
              "x-fapi-interaction-id": {
                "$ref": "#/components/headers/XFapiInteractionIdResponse"
              },
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/XRateLimitLimit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/XRateLimitRemaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/XRateLimitReset"
              },
              "Cache-Control": {
                "$ref": "#/components/headers/CacheControl"
              },
              "ETag": {
                "$ref": "#/components/headers/ETag"
              },
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              },
              "traceparent": {
                "$ref": "#/components/headers/Traceparent"
              },
              "Content-Language": {
                "$ref": "#/components/headers/Content-Language"
              }
            }
          },
          "400": {
            "description": "Bad request",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              },
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                },
                "examples": {
                  "error": {
                    "$ref": "#/components/examples/ErrorBadRequest"
                  }
                }
              }
            },
            "headers": {
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/XRateLimitLimit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/XRateLimitRemaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/XRateLimitReset"
              },
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "403": {
            "$ref": "#/components/responses/Forbidden",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "404": {
            "$ref": "#/components/responses/NotFound",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "409": {
            "$ref": "#/components/responses/Conflict",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "429": {
            "$ref": "#/components/responses/TooManyRequests",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "500": {
            "$ref": "#/components/responses/InternalServerError",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          }
        },
        "x-pagination-style": "cursor",
        "x-codeSamples": [
          {
            "lang": "cURL",
            "label": "cURL",
            "source": "curl -X GET \"https://api.kangopenbanking.com/v1/aisp/accounts/{accountId}/balances\" \\\n  -H \"Authorization: Bearer $KOB_ACCESS_TOKEN\" \\\n  -H \"Content-Type: application/json\""
          },
          {
            "lang": "JavaScript",
            "label": "Node.js",
            "source": "import { KangOpenBanking } from \"@kangopenbanking/sdk\";\n\nconst kob = new KangOpenBanking({ apiKey: process.env.KOB_API_KEY });\nconst res = await kob.request(\"GET\", \"/v1/aisp/accounts/{accountId}/balances\");\nconsole.log(res);"
          },
          {
            "lang": "Python",
            "label": "Python",
            "source": "from kangopenbanking import KangOpenBanking\n\nkob = KangOpenBanking(api_key=os.environ[\"KOB_API_KEY\"])\nres = kob.request(\"GET\", \"/v1/aisp/accounts/{accountId}/balances\")\nprint(res)"
          },
          {
            "lang": "PHP",
            "label": "PHP",
            "source": "<?php\n$kob = new KangOpenBanking\\KangOpenBanking(getenv('KOB_API_KEY'));\n$res = $kob->request('GET', '/v1/aisp/accounts/{accountId}/balances');\nprint_r($res);"
          }
        ]
      }
    },
    "/v1/aisp/accounts/{accountId}/transactions": {
      "get": {
        "tags": [
          "AISP"
        ],
        "summary": "List transactions",
        "operationId": "aispTransactions",
        "security": [
          {
            "bearerAuth": []
          }
        ],
        "parameters": [
          {
            "name": "accountId",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "x-consent-id",
            "in": "header",
            "required": true,
            "schema": {
              "type": "string"
            },
            "description": "Authorised AISP consent ID. Required for all account information endpoints."
          },
          {
            "name": "from_date",
            "in": "query",
            "schema": {
              "type": "string",
              "format": "date"
            }
          },
          {
            "name": "to_date",
            "in": "query",
            "schema": {
              "type": "string",
              "format": "date"
            }
          },
          {
            "name": "limit",
            "in": "query",
            "schema": {
              "type": "integer",
              "default": 25,
              "maximum": 100
            },
            "description": "Items per page"
          },
          {
            "name": "offset",
            "in": "query",
            "schema": {
              "type": "integer",
              "default": 0
            },
            "description": "Items to skip Legacy: kept for backwards compatibility — prefer starting_after/ending_before (see x-pagination)."
          },
          {
            "name": "sort_by",
            "in": "query",
            "schema": {
              "type": "string",
              "default": "created_at"
            },
            "description": "Sort field"
          },
          {
            "name": "sort_order",
            "in": "query",
            "schema": {
              "type": "string",
              "enum": [
                "asc",
                "desc"
              ],
              "default": "desc"
            },
            "description": "Sort direction"
          },
          {
            "$ref": "#/components/parameters/XFapiInteractionId"
          },
          {
            "$ref": "#/components/parameters/XFapiCustomerIpAddress"
          },
          {
            "$ref": "#/components/parameters/XFapiAuthDate"
          },
          {
            "name": "starting_after",
            "in": "query",
            "required": false,
            "description": "Cursor pagination — returns the page of results AFTER this resource id. Mutually exclusive with offset/ending_before. Preferred for new integrations (see x-pagination).",
            "schema": {
              "type": "string",
              "example": "acc_01HZQ..."
            }
          },
          {
            "name": "ending_before",
            "in": "query",
            "required": false,
            "description": "Cursor pagination — returns the page of results BEFORE this resource id. Mutually exclusive with offset/starting_after.",
            "schema": {
              "type": "string",
              "example": "acc_01HZQ..."
            }
          },
          {
            "$ref": "#/components/parameters/RequestId"
          },
          {
            "$ref": "#/components/parameters/Traceparent"
          },
          {
            "$ref": "#/components/parameters/Tracestate"
          },
          {
            "$ref": "#/components/parameters/AcceptLanguage"
          }
        ],
        "responses": {
          "200": {
            "description": "Transactions list",
            "content": {
              "application/json": {
                "schema": {
                  "allOf": [
                    {
                      "$ref": "#/components/schemas/PaginatedResponse"
                    },
                    {
                      "type": "object",
                      "properties": {
                        "data": {
                          "type": "array",
                          "items": {
                            "$ref": "#/components/schemas/Transaction"
                          }
                        }
                      }
                    }
                  ]
                },
                "example": {
                  "data": [
                    {
                      "transaction_id": "f1d6f4a0-1d4e-4a3a-9e0a-1a2b3c4d5e6f",
                      "amount": "25000",
                      "currency": "XAF",
                      "type": "debit",
                      "description": "Mobile Money transfer from 237650000000",
                      "balance_after": "1475000",
                      "booking_date": "2026-01-31",
                      "value_date": "2026-01-31",
                      "timestamp": "2026-01-31T12:00:00Z",
                      "AccountId": "XAF",
                      "TransactionId": "XAF",
                      "Amount": "1000",
                      "Currency": "XAF",
                      "CreditDebitIndicator": "Credit",
                      "BookingDateTime": "2026-01-31T12:00:00Z",
                      "ValueDateTime": "2026-01-31T12:00:00Z",
                      "TransactionInformation": "Payment for Invoice INV-2025-001 — Professional Services",
                      "Status": "Booked"
                    }
                  ],
                  "pagination": {
                    "page": 1,
                    "limit": 20,
                    "total": 150,
                    "has_next": true,
                    "next_cursor": "eyJpZCI6IjEyMyJ9"
                  },
                  "meta": {
                    "request_id": "550e8400-e29b-41d4-a716-446655440000",
                    "timestamp": "2025-03-27T12:00:00Z",
                    "api_version": "4.3.0"
                  }
                }
              }
            },
            "headers": {
              "x-fapi-interaction-id": {
                "$ref": "#/components/headers/XFapiInteractionIdResponse"
              },
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/XRateLimitLimit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/XRateLimitRemaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/XRateLimitReset"
              },
              "Cache-Control": {
                "$ref": "#/components/headers/CacheControl"
              },
              "ETag": {
                "$ref": "#/components/headers/ETag"
              },
              "X-Pagination-Mode": {
                "description": "Either `cursor` or `offset` — echoes which mode the gateway interpreted.",
                "schema": {
                  "type": "string",
                  "enum": [
                    "cursor",
                    "offset"
                  ]
                }
              },
              "X-Pagination-Has-More": {
                "description": "Boolean (`true`/`false`) — whether more results are available.",
                "schema": {
                  "type": "string"
                }
              },
              "X-Pagination-Next-Cursor": {
                "description": "Resource id to pass as `starting_after` for the next page (cursor mode only).",
                "schema": {
                  "type": "string"
                }
              },
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              },
              "traceparent": {
                "$ref": "#/components/headers/Traceparent"
              },
              "Content-Language": {
                "$ref": "#/components/headers/Content-Language"
              }
            }
          },
          "400": {
            "description": "Bad request",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              },
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                },
                "examples": {
                  "error": {
                    "$ref": "#/components/examples/ErrorBadRequest"
                  }
                }
              }
            },
            "headers": {
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/XRateLimitLimit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/XRateLimitRemaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/XRateLimitReset"
              },
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "403": {
            "$ref": "#/components/responses/Forbidden",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "404": {
            "$ref": "#/components/responses/NotFound",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "409": {
            "$ref": "#/components/responses/Conflict",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "429": {
            "$ref": "#/components/responses/TooManyRequests",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "500": {
            "$ref": "#/components/responses/InternalServerError",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          }
        },
        "x-pagination-style": "cursor",
        "x-codeSamples": [
          {
            "lang": "cURL",
            "label": "cURL",
            "source": "curl -X GET \"https://api.kangopenbanking.com/v1/aisp/accounts/{accountId}/transactions\" \\\n  -H \"Authorization: Bearer $KOB_ACCESS_TOKEN\" \\\n  -H \"Content-Type: application/json\""
          },
          {
            "lang": "JavaScript",
            "label": "Node.js",
            "source": "import { KangOpenBanking } from \"@kangopenbanking/sdk\";\n\nconst kob = new KangOpenBanking({ apiKey: process.env.KOB_API_KEY });\nconst res = await kob.request(\"GET\", \"/v1/aisp/accounts/{accountId}/transactions\");\nconsole.log(res);"
          },
          {
            "lang": "Python",
            "label": "Python",
            "source": "from kangopenbanking import KangOpenBanking\n\nkob = KangOpenBanking(api_key=os.environ[\"KOB_API_KEY\"])\nres = kob.request(\"GET\", \"/v1/aisp/accounts/{accountId}/transactions\")\nprint(res)"
          },
          {
            "lang": "PHP",
            "label": "PHP",
            "source": "<?php\n$kob = new KangOpenBanking\\KangOpenBanking(getenv('KOB_API_KEY'));\n$res = $kob->request('GET', '/v1/aisp/accounts/{accountId}/transactions');\nprint_r($res);"
          }
        ]
      }
    },
    "/v1/aisp/accounts/{accountId}/beneficiaries": {
      "get": {
        "tags": [
          "AISP"
        ],
        "summary": "List beneficiaries",
        "operationId": "aispBeneficiaries",
        "security": [
          {
            "bearerAuth": []
          }
        ],
        "parameters": [
          {
            "name": "accountId",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "x-consent-id",
            "in": "header",
            "required": true,
            "schema": {
              "type": "string"
            },
            "description": "Authorised AISP consent ID. Required for all account information endpoints."
          },
          {
            "$ref": "#/components/parameters/RequestId"
          },
          {
            "$ref": "#/components/parameters/Traceparent"
          },
          {
            "$ref": "#/components/parameters/Tracestate"
          },
          {
            "$ref": "#/components/parameters/AcceptLanguage"
          }
        ],
        "responses": {
          "200": {
            "description": "Beneficiaries list",
            "content": {
              "application/json": {
                "schema": {
                  "allOf": [
                    {
                      "$ref": "#/components/schemas/PaginatedResponse"
                    },
                    {
                      "type": "object",
                      "properties": {
                        "data": {
                          "type": "array",
                          "items": {
                            "$ref": "#/components/schemas/GatewayBeneficiary"
                          }
                        }
                      }
                    }
                  ]
                },
                "example": {
                  "data": [
                    {
                      "id": "f1d6f4a0-1d4e-4a3a-9e0a-1a2b3c4d5e6f",
                      "merchant_id": "f1d6f4a0-1d4e-4a3a-9e0a-1a2b3c4d5e6f",
                      "name": "XAF",
                      "channel": "mobile_money",
                      "phone": "XAF",
                      "bank_account": "XAF",
                      "bank_code": "XAF",
                      "created_at": "2026-01-31T12:00:00Z"
                    }
                  ],
                  "pagination": {
                    "page": 1,
                    "limit": 20,
                    "total": 150,
                    "has_next": true,
                    "next_cursor": "eyJpZCI6IjEyMyJ9"
                  },
                  "meta": {
                    "request_id": "550e8400-e29b-41d4-a716-446655440000",
                    "timestamp": "2025-03-27T12:00:00Z",
                    "api_version": "4.3.0"
                  }
                }
              }
            },
            "headers": {
              "x-fapi-interaction-id": {
                "$ref": "#/components/headers/XFapiInteractionIdResponse"
              },
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/XRateLimitLimit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/XRateLimitRemaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/XRateLimitReset"
              },
              "Cache-Control": {
                "$ref": "#/components/headers/CacheControl"
              },
              "ETag": {
                "$ref": "#/components/headers/ETag"
              },
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              },
              "traceparent": {
                "$ref": "#/components/headers/Traceparent"
              },
              "Content-Language": {
                "$ref": "#/components/headers/Content-Language"
              }
            }
          },
          "400": {
            "description": "Bad request",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              },
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                },
                "examples": {
                  "error": {
                    "$ref": "#/components/examples/ErrorBadRequest"
                  }
                }
              }
            },
            "headers": {
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/XRateLimitLimit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/XRateLimitRemaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/XRateLimitReset"
              },
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "403": {
            "$ref": "#/components/responses/Forbidden",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "404": {
            "$ref": "#/components/responses/NotFound",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "409": {
            "$ref": "#/components/responses/Conflict",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "429": {
            "$ref": "#/components/responses/TooManyRequests",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "500": {
            "$ref": "#/components/responses/InternalServerError",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          }
        },
        "x-pagination-style": "cursor",
        "x-codeSamples": [
          {
            "lang": "cURL",
            "label": "cURL",
            "source": "curl -X GET \"https://api.kangopenbanking.com/v1/aisp/accounts/{accountId}/beneficiaries\" \\\n  -H \"Authorization: Bearer $KOB_ACCESS_TOKEN\" \\\n  -H \"Content-Type: application/json\""
          },
          {
            "lang": "JavaScript",
            "label": "Node.js",
            "source": "import { KangOpenBanking } from \"@kangopenbanking/sdk\";\n\nconst kob = new KangOpenBanking({ apiKey: process.env.KOB_API_KEY });\nconst res = await kob.request(\"GET\", \"/v1/aisp/accounts/{accountId}/beneficiaries\");\nconsole.log(res);"
          },
          {
            "lang": "Python",
            "label": "Python",
            "source": "from kangopenbanking import KangOpenBanking\n\nkob = KangOpenBanking(api_key=os.environ[\"KOB_API_KEY\"])\nres = kob.request(\"GET\", \"/v1/aisp/accounts/{accountId}/beneficiaries\")\nprint(res)"
          },
          {
            "lang": "PHP",
            "label": "PHP",
            "source": "<?php\n$kob = new KangOpenBanking\\KangOpenBanking(getenv('KOB_API_KEY'));\n$res = $kob->request('GET', '/v1/aisp/accounts/{accountId}/beneficiaries');\nprint_r($res);"
          }
        ]
      }
    },
    "/v1/aisp/accounts/{accountId}/standing-orders": {
      "get": {
        "tags": [
          "AISP"
        ],
        "summary": "List standing orders",
        "operationId": "aispStandingOrders",
        "security": [
          {
            "bearerAuth": []
          }
        ],
        "parameters": [
          {
            "name": "accountId",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "x-consent-id",
            "in": "header",
            "required": true,
            "schema": {
              "type": "string"
            },
            "description": "Authorised AISP consent ID. Required for all account information endpoints."
          },
          {
            "$ref": "#/components/parameters/RequestId"
          },
          {
            "$ref": "#/components/parameters/Traceparent"
          },
          {
            "$ref": "#/components/parameters/Tracestate"
          },
          {
            "$ref": "#/components/parameters/AcceptLanguage"
          }
        ],
        "responses": {
          "200": {
            "description": "Standing orders list",
            "content": {
              "application/json": {
                "schema": {
                  "allOf": [
                    {
                      "$ref": "#/components/schemas/PaginatedResponse"
                    },
                    {
                      "type": "object",
                      "properties": {
                        "data": {
                          "type": "array",
                          "items": {}
                        }
                      }
                    }
                  ]
                },
                "example": {
                  "data": [
                    {}
                  ],
                  "pagination": {
                    "page": 1,
                    "limit": 20,
                    "total": 150,
                    "has_next": true,
                    "next_cursor": "eyJpZCI6IjEyMyJ9"
                  },
                  "meta": {
                    "request_id": "550e8400-e29b-41d4-a716-446655440000",
                    "timestamp": "2025-03-27T12:00:00Z",
                    "api_version": "4.3.0"
                  }
                }
              }
            },
            "headers": {
              "x-fapi-interaction-id": {
                "$ref": "#/components/headers/XFapiInteractionIdResponse"
              },
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/XRateLimitLimit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/XRateLimitRemaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/XRateLimitReset"
              },
              "Cache-Control": {
                "$ref": "#/components/headers/CacheControl"
              },
              "ETag": {
                "$ref": "#/components/headers/ETag"
              },
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              },
              "traceparent": {
                "$ref": "#/components/headers/Traceparent"
              },
              "Content-Language": {
                "$ref": "#/components/headers/Content-Language"
              }
            }
          },
          "400": {
            "description": "Bad request",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              },
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                },
                "examples": {
                  "error": {
                    "$ref": "#/components/examples/ErrorBadRequest"
                  }
                }
              }
            },
            "headers": {
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/XRateLimitLimit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/XRateLimitRemaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/XRateLimitReset"
              },
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "403": {
            "$ref": "#/components/responses/Forbidden",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "404": {
            "$ref": "#/components/responses/NotFound",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "409": {
            "$ref": "#/components/responses/Conflict",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "429": {
            "$ref": "#/components/responses/TooManyRequests",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "500": {
            "$ref": "#/components/responses/InternalServerError",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          }
        },
        "x-pagination-style": "cursor",
        "x-codeSamples": [
          {
            "lang": "cURL",
            "label": "cURL",
            "source": "curl -X GET \"https://api.kangopenbanking.com/v1/aisp/accounts/{accountId}/standing-orders\" \\\n  -H \"Authorization: Bearer $KOB_ACCESS_TOKEN\" \\\n  -H \"Content-Type: application/json\""
          },
          {
            "lang": "JavaScript",
            "label": "Node.js",
            "source": "import { KangOpenBanking } from \"@kangopenbanking/sdk\";\n\nconst kob = new KangOpenBanking({ apiKey: process.env.KOB_API_KEY });\nconst res = await kob.request(\"GET\", \"/v1/aisp/accounts/{accountId}/standing-orders\");\nconsole.log(res);"
          },
          {
            "lang": "Python",
            "label": "Python",
            "source": "from kangopenbanking import KangOpenBanking\n\nkob = KangOpenBanking(api_key=os.environ[\"KOB_API_KEY\"])\nres = kob.request(\"GET\", \"/v1/aisp/accounts/{accountId}/standing-orders\")\nprint(res)"
          },
          {
            "lang": "PHP",
            "label": "PHP",
            "source": "<?php\n$kob = new KangOpenBanking\\KangOpenBanking(getenv('KOB_API_KEY'));\n$res = $kob->request('GET', '/v1/aisp/accounts/{accountId}/standing-orders');\nprint_r($res);"
          }
        ]
      }
    },
    "/v1/aisp/accounts/{accountId}/direct-debits": {
      "get": {
        "tags": [
          "AISP"
        ],
        "summary": "List direct debits",
        "operationId": "aispDirectDebits",
        "security": [
          {
            "bearerAuth": []
          }
        ],
        "parameters": [
          {
            "name": "accountId",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "x-consent-id",
            "in": "header",
            "required": true,
            "schema": {
              "type": "string"
            },
            "description": "Authorised AISP consent ID. Required for all account information endpoints."
          },
          {
            "$ref": "#/components/parameters/RequestId"
          },
          {
            "$ref": "#/components/parameters/Traceparent"
          },
          {
            "$ref": "#/components/parameters/Tracestate"
          },
          {
            "$ref": "#/components/parameters/AcceptLanguage"
          }
        ],
        "responses": {
          "200": {
            "description": "Direct debits list",
            "content": {
              "application/json": {
                "schema": {
                  "allOf": [
                    {
                      "$ref": "#/components/schemas/PaginatedResponse"
                    },
                    {
                      "type": "object",
                      "properties": {
                        "data": {
                          "type": "array",
                          "items": {}
                        }
                      }
                    }
                  ]
                },
                "example": {
                  "data": [
                    {}
                  ],
                  "pagination": {
                    "page": 1,
                    "limit": 20,
                    "total": 150,
                    "has_next": true,
                    "next_cursor": "eyJpZCI6IjEyMyJ9"
                  },
                  "meta": {
                    "request_id": "550e8400-e29b-41d4-a716-446655440000",
                    "timestamp": "2025-03-27T12:00:00Z",
                    "api_version": "4.3.0"
                  }
                }
              }
            },
            "headers": {
              "x-fapi-interaction-id": {
                "$ref": "#/components/headers/XFapiInteractionIdResponse"
              },
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/XRateLimitLimit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/XRateLimitRemaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/XRateLimitReset"
              },
              "Cache-Control": {
                "$ref": "#/components/headers/CacheControl"
              },
              "ETag": {
                "$ref": "#/components/headers/ETag"
              },
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              },
              "traceparent": {
                "$ref": "#/components/headers/Traceparent"
              },
              "Content-Language": {
                "$ref": "#/components/headers/Content-Language"
              }
            }
          },
          "400": {
            "description": "Bad request",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              },
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                },
                "examples": {
                  "error": {
                    "$ref": "#/components/examples/ErrorBadRequest"
                  }
                }
              }
            },
            "headers": {
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/XRateLimitLimit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/XRateLimitRemaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/XRateLimitReset"
              },
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "403": {
            "$ref": "#/components/responses/Forbidden",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "404": {
            "$ref": "#/components/responses/NotFound",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "409": {
            "$ref": "#/components/responses/Conflict",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "429": {
            "$ref": "#/components/responses/TooManyRequests",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "500": {
            "$ref": "#/components/responses/InternalServerError",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          }
        },
        "x-pagination-style": "cursor",
        "x-codeSamples": [
          {
            "lang": "cURL",
            "label": "cURL",
            "source": "curl -X GET \"https://api.kangopenbanking.com/v1/aisp/accounts/{accountId}/direct-debits\" \\\n  -H \"Authorization: Bearer $KOB_ACCESS_TOKEN\" \\\n  -H \"Content-Type: application/json\""
          },
          {
            "lang": "JavaScript",
            "label": "Node.js",
            "source": "import { KangOpenBanking } from \"@kangopenbanking/sdk\";\n\nconst kob = new KangOpenBanking({ apiKey: process.env.KOB_API_KEY });\nconst res = await kob.request(\"GET\", \"/v1/aisp/accounts/{accountId}/direct-debits\");\nconsole.log(res);"
          },
          {
            "lang": "Python",
            "label": "Python",
            "source": "from kangopenbanking import KangOpenBanking\n\nkob = KangOpenBanking(api_key=os.environ[\"KOB_API_KEY\"])\nres = kob.request(\"GET\", \"/v1/aisp/accounts/{accountId}/direct-debits\")\nprint(res)"
          },
          {
            "lang": "PHP",
            "label": "PHP",
            "source": "<?php\n$kob = new KangOpenBanking\\KangOpenBanking(getenv('KOB_API_KEY'));\n$res = $kob->request('GET', '/v1/aisp/accounts/{accountId}/direct-debits');\nprint_r($res);"
          }
        ]
      }
    },
    "/v1/pisp/consents": {
      "post": {
        "tags": [
          "PISP"
        ],
        "summary": "Create payment consent",
        "operationId": "pispCreateConsent",
        "security": [
          {
            "bearerAuth": []
          }
        ],
        "parameters": [
          {
            "name": "Idempotency-Key",
            "in": "header",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid"
            },
            "description": "Required on all POST/PUT endpoints. Unique key for idempotent request processing (UUID v4 recommended). Keys expire after 24 hours."
          },
          {
            "$ref": "#/components/parameters/XFapiInteractionId"
          },
          {
            "$ref": "#/components/parameters/XFapiCustomerIpAddress"
          },
          {
            "$ref": "#/components/parameters/XFapiAuthDate"
          },
          {
            "$ref": "#/components/parameters/RequestId"
          },
          {
            "$ref": "#/components/parameters/Traceparent"
          },
          {
            "$ref": "#/components/parameters/Tracestate"
          },
          {
            "$ref": "#/components/parameters/AcceptLanguage"
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "required": [
                  "amount",
                  "currency",
                  "creditor_account"
                ],
                "properties": {
                  "amount": {
                    "type": "string",
                    "example": "50000",
                    "pattern": "^[0-9]{1,15}$",
                    "description": "Represented as a string integer in the currency's minor unit (XAF has no subunits). Must be consistent with the currency field."
                  },
                  "currency": {
                    "type": "string",
                    "example": "XAF",
                    "enum": [
                      "XAF",
                      "XOF",
                      "USD",
                      "EUR",
                      "GBP",
                      "CNY",
                      "NGN",
                      "GHS",
                      "KES",
                      "ZAR"
                    ],
                    "default": "XAF",
                    "description": "ISO 4217 currency code. Default is XAF (Central African CFA Franc)."
                  },
                  "debtor_account": {
                    "type": "string"
                  },
                  "creditor_account": {
                    "type": "string"
                  },
                  "reference": {
                    "type": "string",
                    "example": "Invoice-2026-001"
                  }
                }
              },
              "example": {
                "amount": 50000,
                "currency": "XAF",
                "creditor_account": "CM21 10003 00200 9876543210 045",
                "reference": "Invoice-2026-001"
              }
            }
          }
        },
        "responses": {
          "201": {
            "description": "Payment consent created",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Consent"
                },
                "example": {
                  "consent_id": "string",
                  "status": "AwaitingAuthorisation",
                  "permissions": [
                    "string"
                  ],
                  "expiration_date": "2026-01-01T00:00:00Z",
                  "created_at": "2026-01-01T00:00:00Z"
                }
              }
            },
            "headers": {
              "x-fapi-interaction-id": {
                "$ref": "#/components/headers/XFapiInteractionIdResponse"
              },
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/XRateLimitLimit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/XRateLimitRemaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/XRateLimitReset"
              },
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              },
              "X-Idempotent-Replay": {
                "$ref": "#/components/headers/X-Idempotent-Replay"
              },
              "X-Idempotency-Status": {
                "$ref": "#/components/headers/X-Idempotency-Status"
              },
              "traceparent": {
                "$ref": "#/components/headers/Traceparent"
              },
              "Content-Language": {
                "$ref": "#/components/headers/Content-Language"
              }
            }
          },
          "400": {
            "description": "Bad request",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              },
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                },
                "examples": {
                  "error": {
                    "$ref": "#/components/examples/ErrorBadRequest"
                  }
                }
              }
            },
            "headers": {
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/XRateLimitLimit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/XRateLimitRemaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/XRateLimitReset"
              },
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "403": {
            "$ref": "#/components/responses/Forbidden",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "404": {
            "$ref": "#/components/responses/NotFound",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "409": {
            "$ref": "#/components/responses/Conflict",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "429": {
            "$ref": "#/components/responses/TooManyRequests",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "500": {
            "$ref": "#/components/responses/InternalServerError",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          }
        },
        "x-codeSamples": [
          {
            "lang": "cURL",
            "label": "cURL",
            "source": "curl -X POST \"https://api.kangopenbanking.com/v1/pisp/consents\" \\\n  -H \"Authorization: Bearer $KOB_ACCESS_TOKEN\" \\\n  -H \"Content-Type: application/json\" \\\n  -d '{}'"
          },
          {
            "lang": "JavaScript",
            "label": "Node.js",
            "source": "import { KangOpenBanking } from \"@kangopenbanking/sdk\";\n\nconst kob = new KangOpenBanking({ apiKey: process.env.KOB_API_KEY });\nconst res = await kob.request(\"POST\", \"/v1/pisp/consents\", { /* payload */ });\nconsole.log(res);"
          },
          {
            "lang": "Python",
            "label": "Python",
            "source": "from kangopenbanking import KangOpenBanking\n\nkob = KangOpenBanking(api_key=os.environ[\"KOB_API_KEY\"])\nres = kob.request(\"POST\", \"/v1/pisp/consents\", json={})\nprint(res)"
          },
          {
            "lang": "PHP",
            "label": "PHP",
            "source": "<?php\n$kob = new KangOpenBanking\\KangOpenBanking(getenv('KOB_API_KEY'));\n$res = $kob->request('POST', '/v1/pisp/consents', []);\nprint_r($res);"
          }
        ]
      }
    },
    "/v1/pisp/domestic-payment": {
      "post": {
        "tags": [
          "PISP"
        ],
        "summary": "Submit domestic payment",
        "operationId": "pispDomesticPayment",
        "security": [
          {
            "bearerAuth": []
          }
        ],
        "parameters": [
          {
            "name": "Idempotency-Key",
            "in": "header",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid"
            },
            "description": "Required on all POST/PUT endpoints. Unique key for idempotent request processing (UUID v4 recommended). Keys expire after 24 hours."
          },
          {
            "$ref": "#/components/parameters/XFapiInteractionId"
          },
          {
            "$ref": "#/components/parameters/XFapiCustomerIpAddress"
          },
          {
            "$ref": "#/components/parameters/XFapiAuthDate"
          },
          {
            "$ref": "#/components/parameters/RequestId"
          },
          {
            "$ref": "#/components/parameters/Traceparent"
          },
          {
            "$ref": "#/components/parameters/Tracestate"
          },
          {
            "$ref": "#/components/parameters/AcceptLanguage"
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "required": [
                  "consent_id",
                  "amount",
                  "currency",
                  "debtor_account",
                  "creditor_account",
                  "reference"
                ],
                "properties": {
                  "consent_id": {
                    "type": "string"
                  },
                  "amount": {
                    "type": "string",
                    "example": "50000",
                    "pattern": "^[0-9]{1,15}$",
                    "description": "Represented as a string integer in the currency's minor unit (XAF has no subunits). Must be consistent with the currency field."
                  },
                  "currency": {
                    "type": "string",
                    "example": "XAF",
                    "enum": [
                      "XAF",
                      "XOF",
                      "USD",
                      "EUR",
                      "GBP",
                      "CNY",
                      "NGN",
                      "GHS",
                      "KES",
                      "ZAR"
                    ],
                    "default": "XAF",
                    "description": "ISO 4217 currency code. Default is XAF (Central African CFA Franc)."
                  },
                  "debtor_account": {
                    "type": "string"
                  },
                  "creditor_account": {
                    "type": "string"
                  },
                  "reference": {
                    "type": "string"
                  }
                }
              }
            }
          }
        },
        "responses": {
          "201": {
            "description": "Payment submitted",
            "content": {
              "application/json": {
                "schema": {
                  "allOf": [
                    {
                      "$ref": "#/components/schemas/StandardResponse"
                    },
                    {
                      "type": "object",
                      "properties": {
                        "data": {
                          "$ref": "#/components/schemas/Payment"
                        }
                      }
                    }
                  ]
                },
                "example": {
                  "data": {
                    "payment_id": "00000000-0000-4000-8000-000000000000",
                    "amount": "50000",
                    "currency": "XAF",
                    "status": "pending",
                    "debtor_account": "CM21 10003 00100 0123456789 023",
                    "creditor_account": "CM21 10003 00200 9876543210 045",
                    "reference": "Invoice-2026-001",
                    "created_at": "2026-01-01T00:00:00Z"
                  },
                  "meta": {
                    "request_id": "550e8400-e29b-41d4-a716-446655440000",
                    "timestamp": "2025-03-27T12:00:00Z",
                    "api_version": "4.3.0"
                  }
                }
              }
            },
            "headers": {
              "x-fapi-interaction-id": {
                "$ref": "#/components/headers/XFapiInteractionIdResponse"
              },
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/XRateLimitLimit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/XRateLimitRemaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/XRateLimitReset"
              },
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              },
              "X-Idempotent-Replay": {
                "$ref": "#/components/headers/X-Idempotent-Replay"
              },
              "X-Idempotency-Status": {
                "$ref": "#/components/headers/X-Idempotency-Status"
              },
              "traceparent": {
                "$ref": "#/components/headers/Traceparent"
              },
              "Content-Language": {
                "$ref": "#/components/headers/Content-Language"
              }
            }
          },
          "400": {
            "description": "Bad request",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              },
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                },
                "examples": {
                  "error": {
                    "$ref": "#/components/examples/ErrorBadRequest"
                  }
                }
              }
            },
            "headers": {
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/XRateLimitLimit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/XRateLimitRemaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/XRateLimitReset"
              },
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "403": {
            "$ref": "#/components/responses/Forbidden",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "404": {
            "$ref": "#/components/responses/NotFound",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "409": {
            "$ref": "#/components/responses/Conflict",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "429": {
            "$ref": "#/components/responses/TooManyRequests",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "500": {
            "$ref": "#/components/responses/InternalServerError",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          }
        },
        "description": " Responses will conform to the StandardResponse envelope in a future minor release.",
        "x-codeSamples": [
          {
            "lang": "cURL",
            "label": "cURL",
            "source": "curl -X POST \"https://api.kangopenbanking.com/v1/pisp/domestic-payment\" \\\n  -H \"Authorization: Bearer $KOB_ACCESS_TOKEN\" \\\n  -H \"Content-Type: application/json\" \\\n  -d '{}'"
          },
          {
            "lang": "JavaScript",
            "label": "Node.js",
            "source": "import { KangOpenBanking } from \"@kangopenbanking/sdk\";\n\nconst kob = new KangOpenBanking({ apiKey: process.env.KOB_API_KEY });\nconst res = await kob.request(\"POST\", \"/v1/pisp/domestic-payment\", { /* payload */ });\nconsole.log(res);"
          },
          {
            "lang": "Python",
            "label": "Python",
            "source": "from kangopenbanking import KangOpenBanking\n\nkob = KangOpenBanking(api_key=os.environ[\"KOB_API_KEY\"])\nres = kob.request(\"POST\", \"/v1/pisp/domestic-payment\", json={})\nprint(res)"
          },
          {
            "lang": "PHP",
            "label": "PHP",
            "source": "<?php\n$kob = new KangOpenBanking\\KangOpenBanking(getenv('KOB_API_KEY'));\n$res = $kob->request('POST', '/v1/pisp/domestic-payment', []);\nprint_r($res);"
          }
        ]
      }
    },
    "/v1/pisp/payment-submission": {
      "post": {
        "tags": [
          "PISP"
        ],
        "summary": "Confirm payment submission",
        "operationId": "pispPaymentSubmission",
        "security": [
          {
            "bearerAuth": []
          }
        ],
        "parameters": [
          {
            "name": "Idempotency-Key",
            "in": "header",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid"
            },
            "description": "Required on all POST/PUT endpoints. Unique key for idempotent request processing (UUID v4 recommended). Keys expire after 24 hours."
          },
          {
            "$ref": "#/components/parameters/XFapiInteractionId"
          },
          {
            "$ref": "#/components/parameters/XFapiCustomerIpAddress"
          },
          {
            "$ref": "#/components/parameters/XFapiAuthDate"
          },
          {
            "$ref": "#/components/parameters/RequestId"
          },
          {
            "$ref": "#/components/parameters/Traceparent"
          },
          {
            "$ref": "#/components/parameters/Tracestate"
          },
          {
            "$ref": "#/components/parameters/AcceptLanguage"
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "required": [
                  "payment_id",
                  "consent_id",
                  "amount",
                  "currency",
                  "debtor_account",
                  "creditor_account"
                ],
                "properties": {
                  "payment_id": {
                    "type": "string",
                    "minLength": 1,
                    "maxLength": 128
                  },
                  "consent_id": {
                    "type": "string",
                    "minLength": 1,
                    "maxLength": 128
                  },
                  "amount": {
                    "type": "string",
                    "pattern": "^[0-9]{1,15}$",
                    "example": "50000"
                  },
                  "currency": {
                    "type": "string",
                    "enum": [
                      "XAF",
                      "XOF",
                      "EUR",
                      "USD"
                    ],
                    "example": "XAF"
                  },
                  "debtor_account": {
                    "type": "string",
                    "minLength": 1,
                    "maxLength": 64,
                    "example": "10005-00001-09876543210-45"
                  },
                  "creditor_account": {
                    "type": "string",
                    "minLength": 1,
                    "maxLength": 64,
                    "example": "10005-00001-12345678901-23"
                  }
                }
              },
              "example": {
                "payment_id": "pmt_01HFG",
                "consent_id": "cns_01HFG",
                "amount": "50000",
                "currency": "XAF",
                "debtor_account": "10005-00001-09876543210-45",
                "creditor_account": "10005-00001-12345678901-23"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Payment submission confirmed",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Payment"
                },
                "example": {
                  "payment_id": "00000000-0000-4000-8000-000000000000",
                  "amount": "50000",
                  "currency": "XAF",
                  "status": "pending",
                  "debtor_account": "CM21 10003 00100 0123456789 023",
                  "creditor_account": "CM21 10003 00200 9876543210 045",
                  "reference": "Invoice-2026-001",
                  "created_at": "2026-01-01T00:00:00Z"
                }
              }
            },
            "headers": {
              "x-fapi-interaction-id": {
                "$ref": "#/components/headers/XFapiInteractionIdResponse"
              },
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/XRateLimitLimit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/XRateLimitRemaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/XRateLimitReset"
              },
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              },
              "X-Idempotent-Replay": {
                "$ref": "#/components/headers/X-Idempotent-Replay"
              },
              "X-Idempotency-Status": {
                "$ref": "#/components/headers/X-Idempotency-Status"
              },
              "traceparent": {
                "$ref": "#/components/headers/Traceparent"
              },
              "Content-Language": {
                "$ref": "#/components/headers/Content-Language"
              }
            }
          },
          "400": {
            "description": "Bad request",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              },
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                },
                "examples": {
                  "error": {
                    "$ref": "#/components/examples/ErrorBadRequest"
                  }
                }
              }
            },
            "headers": {
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/XRateLimitLimit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/XRateLimitRemaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/XRateLimitReset"
              },
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "403": {
            "$ref": "#/components/responses/Forbidden",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "404": {
            "$ref": "#/components/responses/NotFound",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "409": {
            "$ref": "#/components/responses/Conflict",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "429": {
            "$ref": "#/components/responses/TooManyRequests",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "500": {
            "$ref": "#/components/responses/InternalServerError",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          }
        },
        "x-codeSamples": [
          {
            "lang": "cURL",
            "label": "cURL",
            "source": "curl -X POST \"https://api.kangopenbanking.com/v1/pisp/payment-submission\" \\\n  -H \"Authorization: Bearer $KOB_ACCESS_TOKEN\" \\\n  -H \"Content-Type: application/json\" \\\n  -d '{}'"
          },
          {
            "lang": "JavaScript",
            "label": "Node.js",
            "source": "import { KangOpenBanking } from \"@kangopenbanking/sdk\";\n\nconst kob = new KangOpenBanking({ apiKey: process.env.KOB_API_KEY });\nconst res = await kob.request(\"POST\", \"/v1/pisp/payment-submission\", { /* payload */ });\nconsole.log(res);"
          },
          {
            "lang": "Python",
            "label": "Python",
            "source": "from kangopenbanking import KangOpenBanking\n\nkob = KangOpenBanking(api_key=os.environ[\"KOB_API_KEY\"])\nres = kob.request(\"POST\", \"/v1/pisp/payment-submission\", json={})\nprint(res)"
          },
          {
            "lang": "PHP",
            "label": "PHP",
            "source": "<?php\n$kob = new KangOpenBanking\\KangOpenBanking(getenv('KOB_API_KEY'));\n$res = $kob->request('POST', '/v1/pisp/payment-submission', []);\nprint_r($res);"
          }
        ]
      }
    },
    "/v1/pisp/payments/{paymentId}": {
      "get": {
        "tags": [
          "PISP"
        ],
        "summary": "Get payment details",
        "operationId": "pispPaymentDetails",
        "security": [
          {
            "bearerAuth": []
          }
        ],
        "parameters": [
          {
            "name": "paymentId",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "$ref": "#/components/parameters/RequestId"
          },
          {
            "$ref": "#/components/parameters/Traceparent"
          },
          {
            "$ref": "#/components/parameters/Tracestate"
          },
          {
            "$ref": "#/components/parameters/AcceptLanguage"
          }
        ],
        "responses": {
          "200": {
            "description": "Payment details",
            "content": {
              "application/json": {
                "schema": {
                  "allOf": [
                    {
                      "$ref": "#/components/schemas/StandardResponse"
                    },
                    {
                      "type": "object",
                      "properties": {
                        "data": {
                          "$ref": "#/components/schemas/Payment"
                        }
                      }
                    }
                  ]
                },
                "example": {
                  "data": {
                    "payment_id": "00000000-0000-4000-8000-000000000000",
                    "amount": "50000",
                    "currency": "XAF",
                    "status": "pending",
                    "debtor_account": "CM21 10003 00100 0123456789 023",
                    "creditor_account": "CM21 10003 00200 9876543210 045",
                    "reference": "Invoice-2026-001",
                    "created_at": "2026-01-01T00:00:00Z"
                  },
                  "meta": {
                    "request_id": "550e8400-e29b-41d4-a716-446655440000",
                    "timestamp": "2025-03-27T12:00:00Z",
                    "api_version": "4.3.0"
                  }
                }
              }
            },
            "headers": {
              "x-fapi-interaction-id": {
                "$ref": "#/components/headers/XFapiInteractionIdResponse"
              },
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/XRateLimitLimit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/XRateLimitRemaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/XRateLimitReset"
              },
              "Cache-Control": {
                "$ref": "#/components/headers/CacheControl"
              },
              "ETag": {
                "$ref": "#/components/headers/ETag"
              },
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              },
              "traceparent": {
                "$ref": "#/components/headers/Traceparent"
              },
              "Content-Language": {
                "$ref": "#/components/headers/Content-Language"
              }
            }
          },
          "400": {
            "description": "Bad request",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              },
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                },
                "examples": {
                  "error": {
                    "$ref": "#/components/examples/ErrorBadRequest"
                  }
                }
              }
            },
            "headers": {
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/XRateLimitLimit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/XRateLimitRemaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/XRateLimitReset"
              },
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "403": {
            "$ref": "#/components/responses/Forbidden",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "404": {
            "$ref": "#/components/responses/NotFound",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "409": {
            "$ref": "#/components/responses/Conflict",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "429": {
            "$ref": "#/components/responses/TooManyRequests",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "500": {
            "$ref": "#/components/responses/InternalServerError",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          }
        },
        "x-codeSamples": [
          {
            "lang": "cURL",
            "label": "cURL",
            "source": "curl -X GET \"https://api.kangopenbanking.com/v1/pisp/payments/{paymentId}\" \\\n  -H \"Authorization: Bearer $KOB_ACCESS_TOKEN\" \\\n  -H \"Content-Type: application/json\""
          },
          {
            "lang": "JavaScript",
            "label": "Node.js",
            "source": "import { KangOpenBanking } from \"@kangopenbanking/sdk\";\n\nconst kob = new KangOpenBanking({ apiKey: process.env.KOB_API_KEY });\nconst res = await kob.request(\"GET\", \"/v1/pisp/payments/{paymentId}\");\nconsole.log(res);"
          },
          {
            "lang": "Python",
            "label": "Python",
            "source": "from kangopenbanking import KangOpenBanking\n\nkob = KangOpenBanking(api_key=os.environ[\"KOB_API_KEY\"])\nres = kob.request(\"GET\", \"/v1/pisp/payments/{paymentId}\")\nprint(res)"
          },
          {
            "lang": "PHP",
            "label": "PHP",
            "source": "<?php\n$kob = new KangOpenBanking\\KangOpenBanking(getenv('KOB_API_KEY'));\n$res = $kob->request('GET', '/v1/pisp/payments/{paymentId}');\nprint_r($res);"
          }
        ]
      }
    },
    "/v1/consents/{consentId}/authorize": {
      "post": {
        "tags": [
          "Consent Management"
        ],
        "summary": "Authorize consent",
        "operationId": "consentAuthorize",
        "security": [
          {
            "bearerAuth": []
          }
        ],
        "parameters": [
          {
            "name": "consentId",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "Idempotency-Key",
            "in": "header",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid"
            },
            "description": "Required on all POST/PUT endpoints. Unique key for idempotent request processing (UUID v4 recommended). Keys expire after 24 hours."
          },
          {
            "$ref": "#/components/parameters/RequestId"
          },
          {
            "$ref": "#/components/parameters/Traceparent"
          },
          {
            "$ref": "#/components/parameters/Tracestate"
          },
          {
            "$ref": "#/components/parameters/AcceptLanguage"
          }
        ],
        "responses": {
          "200": {
            "description": "Consent authorized",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Consent"
                },
                "example": {
                  "consent_id": "string",
                  "status": "AwaitingAuthorisation",
                  "permissions": [
                    "string"
                  ],
                  "expiration_date": "2026-01-01T00:00:00Z",
                  "created_at": "2026-01-01T00:00:00Z"
                }
              }
            },
            "headers": {
              "x-fapi-interaction-id": {
                "$ref": "#/components/headers/XFapiInteractionIdResponse"
              },
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/XRateLimitLimit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/XRateLimitRemaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/XRateLimitReset"
              },
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              },
              "traceparent": {
                "$ref": "#/components/headers/Traceparent"
              },
              "Content-Language": {
                "$ref": "#/components/headers/Content-Language"
              }
            }
          },
          "400": {
            "description": "Bad request",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              },
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                },
                "examples": {
                  "error": {
                    "$ref": "#/components/examples/ErrorBadRequest"
                  }
                }
              }
            },
            "headers": {
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/XRateLimitLimit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/XRateLimitRemaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/XRateLimitReset"
              },
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "403": {
            "$ref": "#/components/responses/Forbidden",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "404": {
            "$ref": "#/components/responses/NotFound",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "409": {
            "$ref": "#/components/responses/Conflict",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "429": {
            "$ref": "#/components/responses/TooManyRequests",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "500": {
            "$ref": "#/components/responses/InternalServerError",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          }
        },
        "x-codeSamples": [
          {
            "lang": "cURL",
            "label": "cURL",
            "source": "curl -X POST \"https://api.kangopenbanking.com/v1/consents/{consentId}/authorize\" \\\n  -H \"Authorization: Bearer $KOB_ACCESS_TOKEN\" \\\n  -H \"Content-Type: application/json\""
          },
          {
            "lang": "JavaScript",
            "label": "Node.js",
            "source": "import { KangOpenBanking } from \"@kangopenbanking/sdk\";\n\nconst kob = new KangOpenBanking({ apiKey: process.env.KOB_API_KEY });\nconst res = await kob.request(\"POST\", \"/v1/consents/{consentId}/authorize\");\nconsole.log(res);"
          },
          {
            "lang": "Python",
            "label": "Python",
            "source": "from kangopenbanking import KangOpenBanking\n\nkob = KangOpenBanking(api_key=os.environ[\"KOB_API_KEY\"])\nres = kob.request(\"POST\", \"/v1/consents/{consentId}/authorize\")\nprint(res)"
          },
          {
            "lang": "PHP",
            "label": "PHP",
            "source": "<?php\n$kob = new KangOpenBanking\\KangOpenBanking(getenv('KOB_API_KEY'));\n$res = $kob->request('POST', '/v1/consents/{consentId}/authorize');\nprint_r($res);"
          }
        ]
      }
    },
    "/v1/consents/{consentId}/revoke": {
      "post": {
        "tags": [
          "Consent Management"
        ],
        "summary": "Revoke consent",
        "operationId": "consentRevoke",
        "security": [
          {
            "bearerAuth": []
          }
        ],
        "parameters": [
          {
            "name": "consentId",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "$ref": "#/components/parameters/RequestId"
          },
          {
            "$ref": "#/components/parameters/Traceparent"
          },
          {
            "$ref": "#/components/parameters/Tracestate"
          },
          {
            "$ref": "#/components/parameters/AcceptLanguage"
          }
        ],
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "reason": {
                    "type": "string"
                  }
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Consent revoked",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Consent"
                },
                "example": {
                  "consent_id": "string",
                  "status": "AwaitingAuthorisation",
                  "permissions": [
                    "string"
                  ],
                  "expiration_date": "2026-01-01T00:00:00Z",
                  "created_at": "2026-01-01T00:00:00Z"
                }
              }
            },
            "headers": {
              "x-fapi-interaction-id": {
                "$ref": "#/components/headers/XFapiInteractionIdResponse"
              },
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/XRateLimitLimit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/XRateLimitRemaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/XRateLimitReset"
              },
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              },
              "traceparent": {
                "$ref": "#/components/headers/Traceparent"
              },
              "Content-Language": {
                "$ref": "#/components/headers/Content-Language"
              }
            }
          },
          "400": {
            "description": "Bad request",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              },
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                },
                "examples": {
                  "error": {
                    "$ref": "#/components/examples/ErrorBadRequest"
                  }
                }
              }
            },
            "headers": {
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/XRateLimitLimit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/XRateLimitRemaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/XRateLimitReset"
              },
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "403": {
            "$ref": "#/components/responses/Forbidden",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "404": {
            "$ref": "#/components/responses/NotFound",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "409": {
            "$ref": "#/components/responses/Conflict",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "429": {
            "$ref": "#/components/responses/TooManyRequests",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "500": {
            "$ref": "#/components/responses/InternalServerError",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          }
        },
        "x-codeSamples": [
          {
            "lang": "cURL",
            "label": "cURL",
            "source": "curl -X POST \"https://api.kangopenbanking.com/v1/consents/{consentId}/revoke\" \\\n  -H \"Authorization: Bearer $KOB_ACCESS_TOKEN\" \\\n  -H \"Content-Type: application/json\" \\\n  -d '{}'"
          },
          {
            "lang": "JavaScript",
            "label": "Node.js",
            "source": "import { KangOpenBanking } from \"@kangopenbanking/sdk\";\n\nconst kob = new KangOpenBanking({ apiKey: process.env.KOB_API_KEY });\nconst res = await kob.request(\"POST\", \"/v1/consents/{consentId}/revoke\", { /* payload */ });\nconsole.log(res);"
          },
          {
            "lang": "Python",
            "label": "Python",
            "source": "from kangopenbanking import KangOpenBanking\n\nkob = KangOpenBanking(api_key=os.environ[\"KOB_API_KEY\"])\nres = kob.request(\"POST\", \"/v1/consents/{consentId}/revoke\", json={})\nprint(res)"
          },
          {
            "lang": "PHP",
            "label": "PHP",
            "source": "<?php\n$kob = new KangOpenBanking\\KangOpenBanking(getenv('KOB_API_KEY'));\n$res = $kob->request('POST', '/v1/consents/{consentId}/revoke', []);\nprint_r($res);"
          }
        ]
      }
    },
    "/v1/consents": {
      "get": {
        "tags": [
          "Consent Management"
        ],
        "summary": "List consents",
        "operationId": "consentsList",
        "security": [
          {
            "bearerAuth": []
          }
        ],
        "parameters": [
          {
            "name": "limit",
            "in": "query",
            "schema": {
              "type": "integer",
              "default": 25,
              "maximum": 100
            },
            "description": "Items per page"
          },
          {
            "name": "offset",
            "in": "query",
            "schema": {
              "type": "integer",
              "default": 0
            },
            "description": "Items to skip Legacy: kept for backwards compatibility — prefer starting_after/ending_before (see x-pagination)."
          },
          {
            "name": "sort_by",
            "in": "query",
            "schema": {
              "type": "string",
              "default": "created_at"
            },
            "description": "Sort field"
          },
          {
            "name": "sort_order",
            "in": "query",
            "schema": {
              "type": "string",
              "enum": [
                "asc",
                "desc"
              ],
              "default": "desc"
            },
            "description": "Sort direction"
          },
          {
            "name": "starting_after",
            "in": "query",
            "required": false,
            "description": "Cursor pagination — returns the page of results AFTER this resource id. Mutually exclusive with offset/ending_before. Preferred for new integrations (see x-pagination).",
            "schema": {
              "type": "string",
              "example": "acc_01HZQ..."
            }
          },
          {
            "name": "ending_before",
            "in": "query",
            "required": false,
            "description": "Cursor pagination — returns the page of results BEFORE this resource id. Mutually exclusive with offset/starting_after.",
            "schema": {
              "type": "string",
              "example": "acc_01HZQ..."
            }
          },
          {
            "$ref": "#/components/parameters/RequestId"
          },
          {
            "$ref": "#/components/parameters/Traceparent"
          },
          {
            "$ref": "#/components/parameters/Tracestate"
          },
          {
            "$ref": "#/components/parameters/AcceptLanguage"
          }
        ],
        "responses": {
          "200": {
            "description": "Consents list",
            "content": {
              "application/json": {
                "schema": {
                  "allOf": [
                    {
                      "$ref": "#/components/schemas/PaginatedResponse"
                    },
                    {
                      "type": "object",
                      "properties": {
                        "data": {
                          "type": "array",
                          "items": {
                            "$ref": "#/components/schemas/Consent"
                          }
                        }
                      }
                    }
                  ]
                },
                "example": {
                  "data": [
                    {
                      "consent_id": "XAF",
                      "status": "AwaitingAuthorisation",
                      "permissions": [
                        "XAF"
                      ],
                      "expiration_date": "2026-01-31T12:00:00Z",
                      "created_at": "2026-01-31T12:00:00Z"
                    }
                  ],
                  "pagination": {
                    "page": 1,
                    "limit": 20,
                    "total": 150,
                    "has_next": true,
                    "next_cursor": "eyJpZCI6IjEyMyJ9"
                  },
                  "meta": {
                    "request_id": "550e8400-e29b-41d4-a716-446655440000",
                    "timestamp": "2025-03-27T12:00:00Z",
                    "api_version": "4.3.0"
                  }
                }
              }
            },
            "headers": {
              "x-fapi-interaction-id": {
                "$ref": "#/components/headers/XFapiInteractionIdResponse"
              },
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/XRateLimitLimit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/XRateLimitRemaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/XRateLimitReset"
              },
              "Cache-Control": {
                "$ref": "#/components/headers/CacheControl"
              },
              "ETag": {
                "$ref": "#/components/headers/ETag"
              },
              "X-Pagination-Mode": {
                "description": "Either `cursor` or `offset` — echoes which mode the gateway interpreted.",
                "schema": {
                  "type": "string",
                  "enum": [
                    "cursor",
                    "offset"
                  ]
                }
              },
              "X-Pagination-Has-More": {
                "description": "Boolean (`true`/`false`) — whether more results are available.",
                "schema": {
                  "type": "string"
                }
              },
              "X-Pagination-Next-Cursor": {
                "description": "Resource id to pass as `starting_after` for the next page (cursor mode only).",
                "schema": {
                  "type": "string"
                }
              },
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              },
              "traceparent": {
                "$ref": "#/components/headers/Traceparent"
              },
              "Content-Language": {
                "$ref": "#/components/headers/Content-Language"
              }
            }
          },
          "400": {
            "description": "Bad request",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              },
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                },
                "examples": {
                  "error": {
                    "$ref": "#/components/examples/ErrorBadRequest"
                  }
                }
              }
            },
            "headers": {
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/XRateLimitLimit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/XRateLimitRemaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/XRateLimitReset"
              },
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "403": {
            "$ref": "#/components/responses/Forbidden",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "404": {
            "$ref": "#/components/responses/NotFound",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "409": {
            "$ref": "#/components/responses/Conflict",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "429": {
            "$ref": "#/components/responses/TooManyRequests",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "500": {
            "$ref": "#/components/responses/InternalServerError",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          }
        },
        "x-codeSamples": [
          {
            "lang": "cURL",
            "label": "cURL",
            "source": "curl -X GET \"https://api.kangopenbanking.com/v1/consents\" \\\n  -H \"Authorization: Bearer $KOB_ACCESS_TOKEN\" \\\n  -H \"Content-Type: application/json\""
          },
          {
            "lang": "JavaScript",
            "label": "Node.js",
            "source": "import { KangOpenBanking } from \"@kangopenbanking/sdk\";\n\nconst kob = new KangOpenBanking({ apiKey: process.env.KOB_API_KEY });\nconst res = await kob.request(\"GET\", \"/v1/consents\");\nconsole.log(res);"
          },
          {
            "lang": "Python",
            "label": "Python",
            "source": "from kangopenbanking import KangOpenBanking\n\nkob = KangOpenBanking(api_key=os.environ[\"KOB_API_KEY\"])\nres = kob.request(\"GET\", \"/v1/consents\")\nprint(res)"
          },
          {
            "lang": "PHP",
            "label": "PHP",
            "source": "<?php\n$kob = new KangOpenBanking\\KangOpenBanking(getenv('KOB_API_KEY'));\n$res = $kob->request('GET', '/v1/consents');\nprint_r($res);"
          }
        ]
      },
      "post": {
        "tags": [
          "Consents"
        ],
        "summary": "Create consent",
        "description": "Rail-agnostic consent factory. Routes to `aisp-create-consent`, `pisp-create-consent`, or the CBPII module based on `type`.",
        "operationId": "createConsent",
        "parameters": [
          {
            "$ref": "#/components/parameters/Traceparent"
          },
          {
            "$ref": "#/components/parameters/Tracestate"
          },
          {
            "$ref": "#/components/parameters/IdempotencyKey"
          },
          {
            "$ref": "#/components/parameters/AcceptLanguage"
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/ConsentCreate"
              }
            }
          }
        },
        "responses": {
          "201": {
            "description": "Consent created in AwaitingAuthorisation.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Consent"
                },
                "example": {
                  "consent_id": "string",
                  "status": "AwaitingAuthorisation",
                  "permissions": [
                    "string"
                  ],
                  "expiration_date": "2026-01-01T00:00:00Z",
                  "created_at": "2026-01-01T00:00:00Z"
                }
              }
            },
            "headers": {
              "traceparent": {
                "$ref": "#/components/headers/Traceparent"
              },
              "Content-Language": {
                "$ref": "#/components/headers/Content-Language"
              },
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/XRateLimitLimit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/XRateLimitRemaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/XRateLimitReset"
              },
              "x-fapi-interaction-id": {
                "$ref": "#/components/headers/XFapiInteractionId"
              }
            }
          },
          "429": {
            "description": "Rate limit exceeded. Retry after the interval in `Retry-After`.",
            "headers": {
              "Retry-After": {
                "schema": {
                  "type": "integer"
                },
                "description": "Seconds to wait before retrying."
              },
              "X-RateLimit-Limit": {
                "schema": {
                  "type": "integer"
                }
              },
              "X-RateLimit-Remaining": {
                "schema": {
                  "type": "integer"
                }
              },
              "X-RateLimit-Reset": {
                "schema": {
                  "type": "integer"
                }
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                },
                "examples": {
                  "rateLimited": {
                    "$ref": "#/components/examples/ErrorRateLimited"
                  }
                }
              }
            }
          }
        },
        "x-codeSamples": [
          {
            "lang": "cURL",
            "label": "cURL",
            "source": "curl -X POST \"https://api.kangopenbanking.com/v1/consents\" \\\n  -H \"Authorization: Bearer $KOB_ACCESS_TOKEN\" \\\n  -H \"Content-Type: application/json\" \\\n  -d '{}'"
          },
          {
            "lang": "JavaScript",
            "label": "Node.js",
            "source": "import { KangOpenBanking } from \"@kangopenbanking/sdk\";\n\nconst kob = new KangOpenBanking({ apiKey: process.env.KOB_API_KEY });\nconst res = await kob.request(\"POST\", \"/v1/consents\", { /* payload */ });\nconsole.log(res);"
          },
          {
            "lang": "Python",
            "label": "Python",
            "source": "from kangopenbanking import KangOpenBanking\n\nkob = KangOpenBanking(api_key=os.environ[\"KOB_API_KEY\"])\nres = kob.request(\"POST\", \"/v1/consents\", json={})\nprint(res)"
          },
          {
            "lang": "PHP",
            "label": "PHP",
            "source": "<?php\n$kob = new KangOpenBanking\\KangOpenBanking(getenv('KOB_API_KEY'));\n$res = $kob->request('POST', '/v1/consents', []);\nprint_r($res);"
          }
        ]
      }
    },
    "/v1/credit/score": {
      "get": {
        "tags": [
          "Credit Scoring"
        ],
        "summary": "Get credit score",
        "operationId": "creditScoreFetch",
        "security": [
          {
            "bearerAuth": []
          }
        ],
        "responses": {
          "200": {
            "description": "Credit score",
            "content": {
              "application/json": {
                "schema": {
                  "allOf": [
                    {
                      "$ref": "#/components/schemas/StandardResponse"
                    },
                    {
                      "type": "object",
                      "properties": {
                        "data": {
                          "$ref": "#/components/schemas/CreditScore"
                        }
                      }
                    }
                  ]
                },
                "example": {
                  "data": {
                    "score": 680,
                    "grade": "A",
                    "score_range": "Poor",
                    "calculated_at": "2026-01-01T00:00:00Z",
                    "data_sources": [
                      "mobile_money_history",
                      "njangi_participation",
                      "cobac_registry"
                    ],
                    "locale_band": "cemac_v1"
                  },
                  "meta": {
                    "request_id": "550e8400-e29b-41d4-a716-446655440000",
                    "timestamp": "2025-03-27T12:00:00Z",
                    "api_version": "4.3.0"
                  }
                }
              }
            },
            "headers": {
              "x-fapi-interaction-id": {
                "$ref": "#/components/headers/XFapiInteractionIdResponse"
              },
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/XRateLimitLimit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/XRateLimitRemaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/XRateLimitReset"
              },
              "Cache-Control": {
                "$ref": "#/components/headers/CacheControl"
              },
              "ETag": {
                "$ref": "#/components/headers/ETag"
              },
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              },
              "traceparent": {
                "$ref": "#/components/headers/Traceparent"
              },
              "Content-Language": {
                "$ref": "#/components/headers/Content-Language"
              }
            }
          },
          "400": {
            "description": "Bad request",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              },
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                },
                "examples": {
                  "error": {
                    "$ref": "#/components/examples/ErrorBadRequest"
                  }
                }
              }
            },
            "headers": {
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/XRateLimitLimit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/XRateLimitRemaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/XRateLimitReset"
              },
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "403": {
            "$ref": "#/components/responses/Forbidden",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "404": {
            "$ref": "#/components/responses/NotFound",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "409": {
            "$ref": "#/components/responses/Conflict",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "429": {
            "$ref": "#/components/responses/TooManyRequests",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "500": {
            "$ref": "#/components/responses/InternalServerError",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          }
        },
        "parameters": [
          {
            "$ref": "#/components/parameters/RequestId"
          },
          {
            "$ref": "#/components/parameters/Traceparent"
          },
          {
            "$ref": "#/components/parameters/Tracestate"
          },
          {
            "$ref": "#/components/parameters/AcceptLanguage"
          }
        ],
        "x-codeSamples": [
          {
            "lang": "cURL",
            "label": "cURL",
            "source": "curl -X GET \"https://api.kangopenbanking.com/v1/credit/score\" \\\n  -H \"Authorization: Bearer $KOB_ACCESS_TOKEN\" \\\n  -H \"Content-Type: application/json\""
          },
          {
            "lang": "JavaScript",
            "label": "Node.js",
            "source": "import { KangOpenBanking } from \"@kangopenbanking/sdk\";\n\nconst kob = new KangOpenBanking({ apiKey: process.env.KOB_API_KEY });\nconst res = await kob.request(\"GET\", \"/v1/credit/score\");\nconsole.log(res);"
          },
          {
            "lang": "Python",
            "label": "Python",
            "source": "from kangopenbanking import KangOpenBanking\n\nkob = KangOpenBanking(api_key=os.environ[\"KOB_API_KEY\"])\nres = kob.request(\"GET\", \"/v1/credit/score\")\nprint(res)"
          },
          {
            "lang": "PHP",
            "label": "PHP",
            "source": "<?php\n$kob = new KangOpenBanking\\KangOpenBanking(getenv('KOB_API_KEY'));\n$res = $kob->request('GET', '/v1/credit/score');\nprint_r($res);"
          }
        ]
      },
      "post": {
        "tags": [
          "Credit Scoring"
        ],
        "summary": "Calculate credit score",
        "operationId": "creditScoreCalculate",
        "security": [
          {
            "bearerAuth": []
          }
        ],
        "responses": {
          "200": {
            "description": "Score calculated",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/CreditScore"
                },
                "example": {
                  "score": 680,
                  "grade": "A",
                  "score_range": "Poor",
                  "calculated_at": "2026-01-01T00:00:00Z",
                  "data_sources": [
                    "mobile_money_history",
                    "njangi_participation",
                    "cobac_registry"
                  ],
                  "locale_band": "cemac_v1"
                }
              }
            },
            "headers": {
              "x-fapi-interaction-id": {
                "$ref": "#/components/headers/XFapiInteractionIdResponse"
              },
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/XRateLimitLimit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/XRateLimitRemaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/XRateLimitReset"
              },
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              },
              "traceparent": {
                "$ref": "#/components/headers/Traceparent"
              },
              "Content-Language": {
                "$ref": "#/components/headers/Content-Language"
              }
            }
          },
          "400": {
            "description": "Bad request",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              },
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                },
                "examples": {
                  "error": {
                    "$ref": "#/components/examples/ErrorBadRequest"
                  }
                }
              }
            },
            "headers": {
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/XRateLimitLimit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/XRateLimitRemaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/XRateLimitReset"
              },
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "403": {
            "$ref": "#/components/responses/Forbidden",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "404": {
            "$ref": "#/components/responses/NotFound",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "409": {
            "$ref": "#/components/responses/Conflict",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "429": {
            "$ref": "#/components/responses/TooManyRequests",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "500": {
            "$ref": "#/components/responses/InternalServerError",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          }
        },
        "parameters": [
          {
            "$ref": "#/components/parameters/IdempotencyKey"
          },
          {
            "$ref": "#/components/parameters/RequestId"
          },
          {
            "$ref": "#/components/parameters/Traceparent"
          },
          {
            "$ref": "#/components/parameters/Tracestate"
          },
          {
            "$ref": "#/components/parameters/AcceptLanguage"
          }
        ],
        "x-codeSamples": [
          {
            "lang": "cURL",
            "label": "cURL",
            "source": "curl -X POST \"https://api.kangopenbanking.com/v1/credit/score\" \\\n  -H \"Authorization: Bearer $KOB_ACCESS_TOKEN\" \\\n  -H \"Content-Type: application/json\""
          },
          {
            "lang": "JavaScript",
            "label": "Node.js",
            "source": "import { KangOpenBanking } from \"@kangopenbanking/sdk\";\n\nconst kob = new KangOpenBanking({ apiKey: process.env.KOB_API_KEY });\nconst res = await kob.request(\"POST\", \"/v1/credit/score\");\nconsole.log(res);"
          },
          {
            "lang": "Python",
            "label": "Python",
            "source": "from kangopenbanking import KangOpenBanking\n\nkob = KangOpenBanking(api_key=os.environ[\"KOB_API_KEY\"])\nres = kob.request(\"POST\", \"/v1/credit/score\")\nprint(res)"
          },
          {
            "lang": "PHP",
            "label": "PHP",
            "source": "<?php\n$kob = new KangOpenBanking\\KangOpenBanking(getenv('KOB_API_KEY'));\n$res = $kob->request('POST', '/v1/credit/score');\nprint_r($res);"
          }
        ]
      }
    },
    "/v1/credit/simulate": {
      "post": {
        "tags": [
          "Credit Scoring"
        ],
        "summary": "Simulate score impact",
        "operationId": "creditScoreSimulate",
        "security": [
          {
            "bearerAuth": []
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "action_type": {
                    "type": "string",
                    "enum": [
                      "pay_off_debt",
                      "new_credit",
                      "late_payment"
                    ]
                  },
                  "amount": {
                    "type": "string",
                    "example": "100000",
                    "pattern": "^[0-9]{1,15}$",
                    "description": "Represented as a string integer in the currency's minor unit (XAF has no subunits)."
                  }
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Simulation result",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "current_score": {
                      "type": "integer"
                    },
                    "simulated_score": {
                      "type": "integer"
                    },
                    "impact": {
                      "type": "integer"
                    },
                    "grade_change": {
                      "type": "string"
                    }
                  }
                },
                "example": {
                  "current_score": 0,
                  "simulated_score": 0,
                  "impact": 0,
                  "grade_change": "string"
                }
              }
            },
            "headers": {
              "x-fapi-interaction-id": {
                "$ref": "#/components/headers/XFapiInteractionIdResponse"
              },
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/XRateLimitLimit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/XRateLimitRemaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/XRateLimitReset"
              },
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              },
              "traceparent": {
                "$ref": "#/components/headers/Traceparent"
              },
              "Content-Language": {
                "$ref": "#/components/headers/Content-Language"
              }
            }
          },
          "400": {
            "description": "Bad request",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              },
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                },
                "examples": {
                  "error": {
                    "$ref": "#/components/examples/ErrorBadRequest"
                  }
                }
              }
            },
            "headers": {
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/XRateLimitLimit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/XRateLimitRemaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/XRateLimitReset"
              },
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "403": {
            "$ref": "#/components/responses/Forbidden",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "404": {
            "$ref": "#/components/responses/NotFound",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "409": {
            "$ref": "#/components/responses/Conflict",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "429": {
            "$ref": "#/components/responses/TooManyRequests",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "500": {
            "$ref": "#/components/responses/InternalServerError",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          }
        },
        "parameters": [
          {
            "$ref": "#/components/parameters/IdempotencyKey"
          },
          {
            "$ref": "#/components/parameters/RequestId"
          },
          {
            "$ref": "#/components/parameters/Traceparent"
          },
          {
            "$ref": "#/components/parameters/Tracestate"
          },
          {
            "$ref": "#/components/parameters/AcceptLanguage"
          }
        ],
        "x-codeSamples": [
          {
            "lang": "cURL",
            "label": "cURL",
            "source": "curl -X POST \"https://api.kangopenbanking.com/v1/credit/simulate\" \\\n  -H \"Authorization: Bearer $KOB_ACCESS_TOKEN\" \\\n  -H \"Content-Type: application/json\" \\\n  -d '{}'"
          },
          {
            "lang": "JavaScript",
            "label": "Node.js",
            "source": "import { KangOpenBanking } from \"@kangopenbanking/sdk\";\n\nconst kob = new KangOpenBanking({ apiKey: process.env.KOB_API_KEY });\nconst res = await kob.request(\"POST\", \"/v1/credit/simulate\", { /* payload */ });\nconsole.log(res);"
          },
          {
            "lang": "Python",
            "label": "Python",
            "source": "from kangopenbanking import KangOpenBanking\n\nkob = KangOpenBanking(api_key=os.environ[\"KOB_API_KEY\"])\nres = kob.request(\"POST\", \"/v1/credit/simulate\", json={})\nprint(res)"
          },
          {
            "lang": "PHP",
            "label": "PHP",
            "source": "<?php\n$kob = new KangOpenBanking\\KangOpenBanking(getenv('KOB_API_KEY'));\n$res = $kob->request('POST', '/v1/credit/simulate', []);\nprint_r($res);"
          }
        ]
      }
    },
    "/v1/credit/tips": {
      "get": {
        "tags": [
          "Credit Scoring"
        ],
        "summary": "Get improvement tips",
        "operationId": "creditScoreTips",
        "security": [
          {
            "bearerAuth": []
          }
        ],
        "responses": {
          "200": {
            "description": "Tips list",
            "content": {
              "application/json": {
                "schema": {
                  "allOf": [
                    {
                      "$ref": "#/components/schemas/PaginatedResponse"
                    },
                    {
                      "type": "object",
                      "properties": {
                        "data": {
                          "type": "array",
                          "items": {}
                        }
                      }
                    }
                  ]
                },
                "example": {
                  "data": [
                    {}
                  ],
                  "pagination": {
                    "page": 1,
                    "limit": 20,
                    "total": 150,
                    "has_next": true,
                    "next_cursor": "eyJpZCI6IjEyMyJ9"
                  },
                  "meta": {
                    "request_id": "550e8400-e29b-41d4-a716-446655440000",
                    "timestamp": "2025-03-27T12:00:00Z",
                    "api_version": "4.3.0"
                  }
                }
              }
            },
            "headers": {
              "x-fapi-interaction-id": {
                "$ref": "#/components/headers/XFapiInteractionIdResponse"
              },
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/XRateLimitLimit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/XRateLimitRemaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/XRateLimitReset"
              },
              "Cache-Control": {
                "$ref": "#/components/headers/CacheControl"
              },
              "ETag": {
                "$ref": "#/components/headers/ETag"
              },
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              },
              "traceparent": {
                "$ref": "#/components/headers/Traceparent"
              },
              "Content-Language": {
                "$ref": "#/components/headers/Content-Language"
              }
            }
          },
          "400": {
            "description": "Bad request",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              },
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                },
                "examples": {
                  "error": {
                    "$ref": "#/components/examples/ErrorBadRequest"
                  }
                }
              }
            },
            "headers": {
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/XRateLimitLimit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/XRateLimitRemaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/XRateLimitReset"
              },
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "403": {
            "$ref": "#/components/responses/Forbidden",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "404": {
            "$ref": "#/components/responses/NotFound",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "409": {
            "$ref": "#/components/responses/Conflict",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "429": {
            "$ref": "#/components/responses/TooManyRequests",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "500": {
            "$ref": "#/components/responses/InternalServerError",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          }
        },
        "parameters": [
          {
            "$ref": "#/components/parameters/RequestId"
          },
          {
            "$ref": "#/components/parameters/Traceparent"
          },
          {
            "$ref": "#/components/parameters/Tracestate"
          },
          {
            "$ref": "#/components/parameters/AcceptLanguage"
          }
        ],
        "x-codeSamples": [
          {
            "lang": "cURL",
            "label": "cURL",
            "source": "curl -X GET \"https://api.kangopenbanking.com/v1/credit/tips\" \\\n  -H \"Authorization: Bearer $KOB_ACCESS_TOKEN\" \\\n  -H \"Content-Type: application/json\""
          },
          {
            "lang": "JavaScript",
            "label": "Node.js",
            "source": "import { KangOpenBanking } from \"@kangopenbanking/sdk\";\n\nconst kob = new KangOpenBanking({ apiKey: process.env.KOB_API_KEY });\nconst res = await kob.request(\"GET\", \"/v1/credit/tips\");\nconsole.log(res);"
          },
          {
            "lang": "Python",
            "label": "Python",
            "source": "from kangopenbanking import KangOpenBanking\n\nkob = KangOpenBanking(api_key=os.environ[\"KOB_API_KEY\"])\nres = kob.request(\"GET\", \"/v1/credit/tips\")\nprint(res)"
          },
          {
            "lang": "PHP",
            "label": "PHP",
            "source": "<?php\n$kob = new KangOpenBanking\\KangOpenBanking(getenv('KOB_API_KEY'));\n$res = $kob->request('GET', '/v1/credit/tips');\nprint_r($res);"
          }
        ]
      }
    },
    "/v1/credit/report": {
      "post": {
        "tags": [
          "Credit Scoring"
        ],
        "summary": "Generate credit report",
        "operationId": "creditReportGenerate",
        "security": [
          {
            "bearerAuth": []
          }
        ],
        "responses": {
          "200": {
            "description": "Report generated",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "report_id": {
                      "type": "string",
                      "format": "uuid"
                    },
                    "score": {
                      "$ref": "#/components/schemas/CreditScore"
                    },
                    "generated_at": {
                      "type": "string",
                      "format": "date-time"
                    }
                  }
                },
                "example": {
                  "report_id": "00000000-0000-4000-8000-000000000000",
                  "score": {
                    "score": 680,
                    "grade": "A",
                    "score_range": "Poor",
                    "calculated_at": "2026-01-01T00:00:00Z",
                    "data_sources": [
                      "mobile_money_history",
                      "njangi_participation",
                      "cobac_registry"
                    ],
                    "locale_band": "cemac_v1"
                  },
                  "generated_at": "2026-01-01T00:00:00Z"
                }
              }
            },
            "headers": {
              "x-fapi-interaction-id": {
                "$ref": "#/components/headers/XFapiInteractionIdResponse"
              },
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/XRateLimitLimit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/XRateLimitRemaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/XRateLimitReset"
              },
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              },
              "traceparent": {
                "$ref": "#/components/headers/Traceparent"
              },
              "Content-Language": {
                "$ref": "#/components/headers/Content-Language"
              }
            }
          },
          "400": {
            "description": "Bad request",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              },
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                },
                "examples": {
                  "error": {
                    "$ref": "#/components/examples/ErrorBadRequest"
                  }
                }
              }
            },
            "headers": {
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/XRateLimitLimit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/XRateLimitRemaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/XRateLimitReset"
              },
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "403": {
            "$ref": "#/components/responses/Forbidden",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "404": {
            "$ref": "#/components/responses/NotFound",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "409": {
            "$ref": "#/components/responses/Conflict",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "429": {
            "$ref": "#/components/responses/TooManyRequests",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "500": {
            "$ref": "#/components/responses/InternalServerError",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          }
        },
        "parameters": [
          {
            "$ref": "#/components/parameters/IdempotencyKey"
          },
          {
            "$ref": "#/components/parameters/RequestId"
          },
          {
            "$ref": "#/components/parameters/Traceparent"
          },
          {
            "$ref": "#/components/parameters/Tracestate"
          },
          {
            "$ref": "#/components/parameters/AcceptLanguage"
          }
        ],
        "x-codeSamples": [
          {
            "lang": "cURL",
            "label": "cURL",
            "source": "curl -X POST \"https://api.kangopenbanking.com/v1/credit/report\" \\\n  -H \"Authorization: Bearer $KOB_ACCESS_TOKEN\" \\\n  -H \"Content-Type: application/json\""
          },
          {
            "lang": "JavaScript",
            "label": "Node.js",
            "source": "import { KangOpenBanking } from \"@kangopenbanking/sdk\";\n\nconst kob = new KangOpenBanking({ apiKey: process.env.KOB_API_KEY });\nconst res = await kob.request(\"POST\", \"/v1/credit/report\");\nconsole.log(res);"
          },
          {
            "lang": "Python",
            "label": "Python",
            "source": "from kangopenbanking import KangOpenBanking\n\nkob = KangOpenBanking(api_key=os.environ[\"KOB_API_KEY\"])\nres = kob.request(\"POST\", \"/v1/credit/report\")\nprint(res)"
          },
          {
            "lang": "PHP",
            "label": "PHP",
            "source": "<?php\n$kob = new KangOpenBanking\\KangOpenBanking(getenv('KOB_API_KEY'));\n$res = $kob->request('POST', '/v1/credit/report');\nprint_r($res);"
          }
        ]
      }
    },
    "/v1/loans/products": {
      "get": {
        "tags": [
          "Loans"
        ],
        "summary": "List loan products",
        "operationId": "loanProducts",
        "security": [
          {
            "bearerAuth": []
          }
        ],
        "responses": {
          "200": {
            "description": "Loan products",
            "content": {
              "application/json": {
                "schema": {
                  "allOf": [
                    {
                      "$ref": "#/components/schemas/PaginatedResponse"
                    },
                    {
                      "type": "object",
                      "properties": {
                        "data": {
                          "type": "array",
                          "items": {}
                        }
                      }
                    }
                  ]
                },
                "example": {
                  "data": [
                    {}
                  ],
                  "pagination": {
                    "page": 1,
                    "limit": 20,
                    "total": 150,
                    "has_next": true,
                    "next_cursor": "eyJpZCI6IjEyMyJ9"
                  },
                  "meta": {
                    "request_id": "550e8400-e29b-41d4-a716-446655440000",
                    "timestamp": "2025-03-27T12:00:00Z",
                    "api_version": "4.3.0"
                  }
                }
              }
            },
            "headers": {
              "x-fapi-interaction-id": {
                "$ref": "#/components/headers/XFapiInteractionIdResponse"
              },
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/XRateLimitLimit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/XRateLimitRemaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/XRateLimitReset"
              },
              "Cache-Control": {
                "$ref": "#/components/headers/CacheControl"
              },
              "ETag": {
                "$ref": "#/components/headers/ETag"
              },
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              },
              "traceparent": {
                "$ref": "#/components/headers/Traceparent"
              },
              "Content-Language": {
                "$ref": "#/components/headers/Content-Language"
              }
            }
          },
          "400": {
            "description": "Bad request",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              },
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                },
                "examples": {
                  "error": {
                    "$ref": "#/components/examples/ErrorBadRequest"
                  }
                }
              }
            },
            "headers": {
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/XRateLimitLimit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/XRateLimitRemaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/XRateLimitReset"
              },
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "403": {
            "$ref": "#/components/responses/Forbidden",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "404": {
            "$ref": "#/components/responses/NotFound",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "409": {
            "$ref": "#/components/responses/Conflict",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "429": {
            "$ref": "#/components/responses/TooManyRequests",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "500": {
            "$ref": "#/components/responses/InternalServerError",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          }
        },
        "parameters": [
          {
            "$ref": "#/components/parameters/PageParam"
          },
          {
            "$ref": "#/components/parameters/LimitParam"
          },
          {
            "$ref": "#/components/parameters/CursorParam"
          },
          {
            "$ref": "#/components/parameters/RequestId"
          },
          {
            "$ref": "#/components/parameters/Traceparent"
          },
          {
            "$ref": "#/components/parameters/Tracestate"
          },
          {
            "$ref": "#/components/parameters/AcceptLanguage"
          }
        ],
        "x-codeSamples": [
          {
            "lang": "cURL",
            "label": "cURL",
            "source": "curl -X GET \"https://api.kangopenbanking.com/v1/loans/products\" \\\n  -H \"Authorization: Bearer $KOB_ACCESS_TOKEN\" \\\n  -H \"Content-Type: application/json\""
          },
          {
            "lang": "JavaScript",
            "label": "Node.js",
            "source": "import { KangOpenBanking } from \"@kangopenbanking/sdk\";\n\nconst kob = new KangOpenBanking({ apiKey: process.env.KOB_API_KEY });\nconst res = await kob.request(\"GET\", \"/v1/loans/products\");\nconsole.log(res);"
          },
          {
            "lang": "Python",
            "label": "Python",
            "source": "from kangopenbanking import KangOpenBanking\n\nkob = KangOpenBanking(api_key=os.environ[\"KOB_API_KEY\"])\nres = kob.request(\"GET\", \"/v1/loans/products\")\nprint(res)"
          },
          {
            "lang": "PHP",
            "label": "PHP",
            "source": "<?php\n$kob = new KangOpenBanking\\KangOpenBanking(getenv('KOB_API_KEY'));\n$res = $kob->request('GET', '/v1/loans/products');\nprint_r($res);"
          }
        ]
      }
    },
    "/v1/loans/apply": {
      "post": {
        "tags": [
          "Loans"
        ],
        "summary": "Apply for loan",
        "operationId": "loanApply",
        "security": [
          {
            "bearerAuth": []
          }
        ],
        "parameters": [
          {
            "name": "Idempotency-Key",
            "in": "header",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid"
            },
            "description": "Required on all POST/PUT endpoints. Unique key for idempotent request processing (UUID v4 recommended). Keys expire after 24 hours."
          },
          {
            "$ref": "#/components/parameters/RequestId"
          },
          {
            "$ref": "#/components/parameters/Traceparent"
          },
          {
            "$ref": "#/components/parameters/Tracestate"
          },
          {
            "$ref": "#/components/parameters/AcceptLanguage"
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "required": [
                  "product_id",
                  "amount",
                  "term_months"
                ],
                "properties": {
                  "product_id": {
                    "type": "string"
                  },
                  "amount": {
                    "type": "string",
                    "example": "1000000",
                    "pattern": "^[0-9]{1,15}$",
                    "description": "Represented as a string integer in the currency's minor unit (XAF has no subunits)."
                  },
                  "term_months": {
                    "type": "integer",
                    "example": 12
                  },
                  "purpose": {
                    "type": "string",
                    "example": "Business expansion"
                  }
                }
              },
              "example": {
                "product_id": "prod_abc123",
                "amount": 1000000,
                "term_months": 12,
                "purpose": "Business expansion"
              }
            }
          }
        },
        "responses": {
          "201": {
            "description": "Loan application submitted",
            "content": {
              "application/json": {
                "schema": {
                  "allOf": [
                    {
                      "$ref": "#/components/schemas/StandardResponse"
                    },
                    {
                      "type": "object",
                      "properties": {
                        "data": {
                          "$ref": "#/components/schemas/LoanApplication"
                        }
                      }
                    }
                  ]
                },
                "example": {
                  "data": {
                    "id": "00000000-0000-4000-8000-000000000000",
                    "product_id": "00000000-0000-4000-8000-000000000000",
                    "amount": "1000000",
                    "currency": "XAF",
                    "term_months": 12,
                    "interest_rate": 15,
                    "status": "applied",
                    "purpose": "Business expansion",
                    "created_at": "2026-01-01T00:00:00Z"
                  },
                  "meta": {
                    "request_id": "550e8400-e29b-41d4-a716-446655440000",
                    "timestamp": "2025-03-27T12:00:00Z",
                    "api_version": "4.3.0"
                  }
                }
              }
            },
            "headers": {
              "x-fapi-interaction-id": {
                "$ref": "#/components/headers/XFapiInteractionIdResponse"
              },
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/XRateLimitLimit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/XRateLimitRemaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/XRateLimitReset"
              },
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              },
              "X-Idempotent-Replay": {
                "$ref": "#/components/headers/X-Idempotent-Replay"
              },
              "X-Idempotency-Status": {
                "$ref": "#/components/headers/X-Idempotency-Status"
              },
              "traceparent": {
                "$ref": "#/components/headers/Traceparent"
              },
              "Content-Language": {
                "$ref": "#/components/headers/Content-Language"
              }
            }
          },
          "400": {
            "description": "Bad request",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              },
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                },
                "examples": {
                  "error": {
                    "$ref": "#/components/examples/ErrorBadRequest"
                  }
                }
              }
            },
            "headers": {
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/XRateLimitLimit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/XRateLimitRemaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/XRateLimitReset"
              },
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "403": {
            "$ref": "#/components/responses/Forbidden",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "404": {
            "$ref": "#/components/responses/NotFound",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "409": {
            "$ref": "#/components/responses/Conflict",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "429": {
            "$ref": "#/components/responses/TooManyRequests",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "500": {
            "$ref": "#/components/responses/InternalServerError",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          }
        },
        "description": " Responses will conform to the StandardResponse envelope in a future minor release.",
        "x-codeSamples": [
          {
            "lang": "cURL",
            "label": "cURL",
            "source": "curl -X POST \"https://api.kangopenbanking.com/v1/loans/apply\" \\\n  -H \"Authorization: Bearer $KOB_ACCESS_TOKEN\" \\\n  -H \"Content-Type: application/json\" \\\n  -d '{}'"
          },
          {
            "lang": "JavaScript",
            "label": "Node.js",
            "source": "import { KangOpenBanking } from \"@kangopenbanking/sdk\";\n\nconst kob = new KangOpenBanking({ apiKey: process.env.KOB_API_KEY });\nconst res = await kob.request(\"POST\", \"/v1/loans/apply\", { /* payload */ });\nconsole.log(res);"
          },
          {
            "lang": "Python",
            "label": "Python",
            "source": "from kangopenbanking import KangOpenBanking\n\nkob = KangOpenBanking(api_key=os.environ[\"KOB_API_KEY\"])\nres = kob.request(\"POST\", \"/v1/loans/apply\", json={})\nprint(res)"
          },
          {
            "lang": "PHP",
            "label": "PHP",
            "source": "<?php\n$kob = new KangOpenBanking\\KangOpenBanking(getenv('KOB_API_KEY'));\n$res = $kob->request('POST', '/v1/loans/apply', []);\nprint_r($res);"
          }
        ]
      }
    },
    "/v1/loans/calculate": {
      "post": {
        "tags": [
          "Loans"
        ],
        "summary": "Calculate loan terms",
        "operationId": "loanCalculate",
        "security": [],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "required": [
                  "amount",
                  "term_months",
                  "interest_rate"
                ],
                "properties": {
                  "amount": {
                    "type": "string",
                    "example": "1000000",
                    "pattern": "^[0-9]{1,15}$",
                    "description": "Represented as a string integer in the currency's minor unit (XAF has no subunits)."
                  },
                  "term_months": {
                    "type": "integer",
                    "example": 12
                  },
                  "interest_rate": {
                    "type": "number",
                    "example": 15
                  }
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Loan calculation",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "monthly_payment": {
                      "type": "number",
                      "example": 92500
                    },
                    "total_interest": {
                      "type": "number",
                      "example": 110000
                    },
                    "total_repayment": {
                      "type": "number",
                      "example": 1110000
                    }
                  }
                },
                "example": {
                  "monthly_payment": 92500,
                  "total_interest": 110000,
                  "total_repayment": 1110000
                }
              }
            },
            "headers": {
              "x-fapi-interaction-id": {
                "$ref": "#/components/headers/XFapiInteractionIdResponse"
              },
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/XRateLimitLimit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/XRateLimitRemaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/XRateLimitReset"
              },
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              },
              "X-Idempotent-Replay": {
                "$ref": "#/components/headers/X-Idempotent-Replay"
              },
              "X-Idempotency-Status": {
                "$ref": "#/components/headers/X-Idempotency-Status"
              },
              "traceparent": {
                "$ref": "#/components/headers/Traceparent"
              },
              "Content-Language": {
                "$ref": "#/components/headers/Content-Language"
              }
            }
          },
          "400": {
            "description": "Bad request",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              },
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                },
                "examples": {
                  "error": {
                    "$ref": "#/components/examples/ErrorBadRequest"
                  }
                }
              }
            },
            "headers": {
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/XRateLimitLimit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/XRateLimitRemaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/XRateLimitReset"
              },
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "403": {
            "$ref": "#/components/responses/Forbidden",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "404": {
            "$ref": "#/components/responses/NotFound",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "409": {
            "$ref": "#/components/responses/Conflict",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "429": {
            "$ref": "#/components/responses/TooManyRequests",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "500": {
            "$ref": "#/components/responses/InternalServerError",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          }
        },
        "parameters": [
          {
            "$ref": "#/components/parameters/IdempotencyKey"
          },
          {
            "$ref": "#/components/parameters/RequestId"
          },
          {
            "$ref": "#/components/parameters/Traceparent"
          },
          {
            "$ref": "#/components/parameters/Tracestate"
          },
          {
            "$ref": "#/components/parameters/AcceptLanguage"
          }
        ],
        "x-codeSamples": [
          {
            "lang": "cURL",
            "label": "cURL",
            "source": "curl -X POST \"https://api.kangopenbanking.com/v1/loans/calculate\" \\\n  -H \"Authorization: Bearer $KOB_ACCESS_TOKEN\" \\\n  -H \"Content-Type: application/json\" \\\n  -d '{}'"
          },
          {
            "lang": "JavaScript",
            "label": "Node.js",
            "source": "import { KangOpenBanking } from \"@kangopenbanking/sdk\";\n\nconst kob = new KangOpenBanking({ apiKey: process.env.KOB_API_KEY });\nconst res = await kob.request(\"POST\", \"/v1/loans/calculate\", { /* payload */ });\nconsole.log(res);"
          },
          {
            "lang": "Python",
            "label": "Python",
            "source": "from kangopenbanking import KangOpenBanking\n\nkob = KangOpenBanking(api_key=os.environ[\"KOB_API_KEY\"])\nres = kob.request(\"POST\", \"/v1/loans/calculate\", json={})\nprint(res)"
          },
          {
            "lang": "PHP",
            "label": "PHP",
            "source": "<?php\n$kob = new KangOpenBanking\\KangOpenBanking(getenv('KOB_API_KEY'));\n$res = $kob->request('POST', '/v1/loans/calculate', []);\nprint_r($res);"
          }
        ]
      }
    },
    "/v1/loans/{loanId}/approve": {
      "post": {
        "tags": [
          "Loans"
        ],
        "summary": "Approve loan application",
        "operationId": "loanApprove",
        "security": [
          {
            "bearerAuth": []
          }
        ],
        "parameters": [
          {
            "name": "loanId",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "Idempotency-Key",
            "in": "header",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid"
            },
            "description": "Required on all POST/PUT endpoints. Unique key for idempotent request processing (UUID v4 recommended). Keys expire after 24 hours."
          },
          {
            "$ref": "#/components/parameters/RequestId"
          },
          {
            "$ref": "#/components/parameters/Traceparent"
          },
          {
            "$ref": "#/components/parameters/Tracestate"
          },
          {
            "$ref": "#/components/parameters/AcceptLanguage"
          }
        ],
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "approved_amount": {
                    "type": "number"
                  },
                  "approved_rate": {
                    "type": "number"
                  },
                  "conditions": {
                    "type": "string"
                  }
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Loan approved",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/LoanApplication"
                },
                "example": {
                  "id": "00000000-0000-4000-8000-000000000000",
                  "product_id": "00000000-0000-4000-8000-000000000000",
                  "amount": "1000000",
                  "currency": "XAF",
                  "term_months": 12,
                  "interest_rate": 15,
                  "status": "applied",
                  "purpose": "Business expansion",
                  "created_at": "2026-01-01T00:00:00Z"
                }
              }
            },
            "headers": {
              "x-fapi-interaction-id": {
                "$ref": "#/components/headers/XFapiInteractionIdResponse"
              },
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/XRateLimitLimit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/XRateLimitRemaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/XRateLimitReset"
              },
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              },
              "X-Idempotent-Replay": {
                "$ref": "#/components/headers/X-Idempotent-Replay"
              },
              "X-Idempotency-Status": {
                "$ref": "#/components/headers/X-Idempotency-Status"
              },
              "traceparent": {
                "$ref": "#/components/headers/Traceparent"
              },
              "Content-Language": {
                "$ref": "#/components/headers/Content-Language"
              }
            }
          },
          "400": {
            "description": "Bad request",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              },
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                },
                "examples": {
                  "error": {
                    "$ref": "#/components/examples/ErrorBadRequest"
                  }
                }
              }
            },
            "headers": {
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/XRateLimitLimit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/XRateLimitRemaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/XRateLimitReset"
              },
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "403": {
            "$ref": "#/components/responses/Forbidden",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "404": {
            "$ref": "#/components/responses/NotFound",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "409": {
            "$ref": "#/components/responses/Conflict",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "429": {
            "$ref": "#/components/responses/TooManyRequests",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "500": {
            "$ref": "#/components/responses/InternalServerError",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          }
        },
        "x-codeSamples": [
          {
            "lang": "cURL",
            "label": "cURL",
            "source": "curl -X POST \"https://api.kangopenbanking.com/v1/loans/{loanId}/approve\" \\\n  -H \"Authorization: Bearer $KOB_ACCESS_TOKEN\" \\\n  -H \"Content-Type: application/json\" \\\n  -d '{}'"
          },
          {
            "lang": "JavaScript",
            "label": "Node.js",
            "source": "import { KangOpenBanking } from \"@kangopenbanking/sdk\";\n\nconst kob = new KangOpenBanking({ apiKey: process.env.KOB_API_KEY });\nconst res = await kob.request(\"POST\", \"/v1/loans/{loanId}/approve\", { /* payload */ });\nconsole.log(res);"
          },
          {
            "lang": "Python",
            "label": "Python",
            "source": "from kangopenbanking import KangOpenBanking\n\nkob = KangOpenBanking(api_key=os.environ[\"KOB_API_KEY\"])\nres = kob.request(\"POST\", \"/v1/loans/{loanId}/approve\", json={})\nprint(res)"
          },
          {
            "lang": "PHP",
            "label": "PHP",
            "source": "<?php\n$kob = new KangOpenBanking\\KangOpenBanking(getenv('KOB_API_KEY'));\n$res = $kob->request('POST', '/v1/loans/{loanId}/approve', []);\nprint_r($res);"
          }
        ]
      }
    },
    "/v1/loans/{loanId}/disburse": {
      "post": {
        "tags": [
          "Loans"
        ],
        "summary": "Disburse loan",
        "operationId": "loanDisburse",
        "security": [
          {
            "bearerAuth": []
          }
        ],
        "parameters": [
          {
            "name": "loanId",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "Idempotency-Key",
            "in": "header",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid"
            },
            "description": "Required on all POST/PUT endpoints. Unique key for idempotent request processing (UUID v4 recommended). Keys expire after 24 hours."
          },
          {
            "$ref": "#/components/parameters/RequestId"
          },
          {
            "$ref": "#/components/parameters/Traceparent"
          },
          {
            "$ref": "#/components/parameters/Tracestate"
          },
          {
            "$ref": "#/components/parameters/AcceptLanguage"
          }
        ],
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "disbursement_account": {
                    "type": "string"
                  },
                  "disbursement_method": {
                    "type": "string",
                    "enum": [
                      "bank_transfer",
                      "mobile_money"
                    ]
                  }
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Loan disbursed with ledger posting",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/LoanApplication"
                },
                "example": {
                  "id": "00000000-0000-4000-8000-000000000000",
                  "product_id": "00000000-0000-4000-8000-000000000000",
                  "amount": "1000000",
                  "currency": "XAF",
                  "term_months": 12,
                  "interest_rate": 15,
                  "status": "applied",
                  "purpose": "Business expansion",
                  "created_at": "2026-01-01T00:00:00Z"
                }
              }
            },
            "headers": {
              "x-fapi-interaction-id": {
                "$ref": "#/components/headers/XFapiInteractionIdResponse"
              },
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/XRateLimitLimit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/XRateLimitRemaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/XRateLimitReset"
              },
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              },
              "X-Idempotent-Replay": {
                "$ref": "#/components/headers/X-Idempotent-Replay"
              },
              "X-Idempotency-Status": {
                "$ref": "#/components/headers/X-Idempotency-Status"
              },
              "traceparent": {
                "$ref": "#/components/headers/Traceparent"
              },
              "Content-Language": {
                "$ref": "#/components/headers/Content-Language"
              }
            }
          },
          "400": {
            "description": "Bad request",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              },
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                },
                "examples": {
                  "error": {
                    "$ref": "#/components/examples/ErrorBadRequest"
                  }
                }
              }
            },
            "headers": {
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/XRateLimitLimit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/XRateLimitRemaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/XRateLimitReset"
              },
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "403": {
            "$ref": "#/components/responses/Forbidden",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "404": {
            "$ref": "#/components/responses/NotFound",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "409": {
            "$ref": "#/components/responses/Conflict",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "429": {
            "$ref": "#/components/responses/TooManyRequests",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "500": {
            "$ref": "#/components/responses/InternalServerError",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          }
        },
        "x-codeSamples": [
          {
            "lang": "cURL",
            "label": "cURL",
            "source": "curl -X POST \"https://api.kangopenbanking.com/v1/loans/{loanId}/disburse\" \\\n  -H \"Authorization: Bearer $KOB_ACCESS_TOKEN\" \\\n  -H \"Content-Type: application/json\" \\\n  -d '{}'"
          },
          {
            "lang": "JavaScript",
            "label": "Node.js",
            "source": "import { KangOpenBanking } from \"@kangopenbanking/sdk\";\n\nconst kob = new KangOpenBanking({ apiKey: process.env.KOB_API_KEY });\nconst res = await kob.request(\"POST\", \"/v1/loans/{loanId}/disburse\", { /* payload */ });\nconsole.log(res);"
          },
          {
            "lang": "Python",
            "label": "Python",
            "source": "from kangopenbanking import KangOpenBanking\n\nkob = KangOpenBanking(api_key=os.environ[\"KOB_API_KEY\"])\nres = kob.request(\"POST\", \"/v1/loans/{loanId}/disburse\", json={})\nprint(res)"
          },
          {
            "lang": "PHP",
            "label": "PHP",
            "source": "<?php\n$kob = new KangOpenBanking\\KangOpenBanking(getenv('KOB_API_KEY'));\n$res = $kob->request('POST', '/v1/loans/{loanId}/disburse', []);\nprint_r($res);"
          }
        ]
      }
    },
    "/v1/loans/{loanId}/schedule": {
      "get": {
        "tags": [
          "Loans"
        ],
        "summary": "Get repayment schedule",
        "operationId": "loanSchedule",
        "security": [
          {
            "bearerAuth": []
          }
        ],
        "parameters": [
          {
            "name": "loanId",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "$ref": "#/components/parameters/RequestId"
          },
          {
            "$ref": "#/components/parameters/Traceparent"
          },
          {
            "$ref": "#/components/parameters/Tracestate"
          },
          {
            "$ref": "#/components/parameters/AcceptLanguage"
          }
        ],
        "responses": {
          "200": {
            "description": "Repayment schedule",
            "content": {
              "application/json": {
                "schema": {
                  "allOf": [
                    {
                      "$ref": "#/components/schemas/PaginatedResponse"
                    },
                    {
                      "type": "object",
                      "properties": {
                        "data": {
                          "type": "array",
                          "items": {
                            "$ref": "#/components/schemas/LoanScheduleItem"
                          }
                        }
                      }
                    }
                  ]
                },
                "example": {
                  "data": [
                    {
                      "installment_number": 1,
                      "due_date": "2026-03-16",
                      "principal": "80000",
                      "interest": "12500",
                      "fees": "0",
                      "total_due": 92500,
                      "outstanding_balance": "920000",
                      "status": "pending"
                    }
                  ],
                  "pagination": {
                    "page": 1,
                    "limit": 20,
                    "total": 150,
                    "has_next": true,
                    "next_cursor": "eyJpZCI6IjEyMyJ9"
                  },
                  "meta": {
                    "request_id": "550e8400-e29b-41d4-a716-446655440000",
                    "timestamp": "2025-03-27T12:00:00Z",
                    "api_version": "4.3.0"
                  }
                }
              }
            },
            "headers": {
              "x-fapi-interaction-id": {
                "$ref": "#/components/headers/XFapiInteractionIdResponse"
              },
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/XRateLimitLimit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/XRateLimitRemaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/XRateLimitReset"
              },
              "Cache-Control": {
                "$ref": "#/components/headers/CacheControl"
              },
              "ETag": {
                "$ref": "#/components/headers/ETag"
              },
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              },
              "traceparent": {
                "$ref": "#/components/headers/Traceparent"
              },
              "Content-Language": {
                "$ref": "#/components/headers/Content-Language"
              }
            }
          },
          "400": {
            "description": "Bad request",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              },
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                },
                "examples": {
                  "error": {
                    "$ref": "#/components/examples/ErrorBadRequest"
                  }
                }
              }
            },
            "headers": {
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/XRateLimitLimit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/XRateLimitRemaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/XRateLimitReset"
              },
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "403": {
            "$ref": "#/components/responses/Forbidden",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "404": {
            "$ref": "#/components/responses/NotFound",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "409": {
            "$ref": "#/components/responses/Conflict",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "429": {
            "$ref": "#/components/responses/TooManyRequests",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "500": {
            "$ref": "#/components/responses/InternalServerError",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          }
        },
        "x-codeSamples": [
          {
            "lang": "cURL",
            "label": "cURL",
            "source": "curl -X GET \"https://api.kangopenbanking.com/v1/loans/{loanId}/schedule\" \\\n  -H \"Authorization: Bearer $KOB_ACCESS_TOKEN\" \\\n  -H \"Content-Type: application/json\""
          },
          {
            "lang": "JavaScript",
            "label": "Node.js",
            "source": "import { KangOpenBanking } from \"@kangopenbanking/sdk\";\n\nconst kob = new KangOpenBanking({ apiKey: process.env.KOB_API_KEY });\nconst res = await kob.request(\"GET\", \"/v1/loans/{loanId}/schedule\");\nconsole.log(res);"
          },
          {
            "lang": "Python",
            "label": "Python",
            "source": "from kangopenbanking import KangOpenBanking\n\nkob = KangOpenBanking(api_key=os.environ[\"KOB_API_KEY\"])\nres = kob.request(\"GET\", \"/v1/loans/{loanId}/schedule\")\nprint(res)"
          },
          {
            "lang": "PHP",
            "label": "PHP",
            "source": "<?php\n$kob = new KangOpenBanking\\KangOpenBanking(getenv('KOB_API_KEY'));\n$res = $kob->request('GET', '/v1/loans/{loanId}/schedule');\nprint_r($res);"
          }
        ]
      },
      "post": {
        "tags": [
          "Loans"
        ],
        "summary": "Generate repayment schedule",
        "operationId": "loanGenerateSchedule",
        "security": [
          {
            "bearerAuth": []
          }
        ],
        "parameters": [
          {
            "name": "loanId",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "Idempotency-Key",
            "in": "header",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid"
            },
            "description": "Required on all POST/PUT endpoints. Unique key for idempotent request processing (UUID v4 recommended). Keys expire after 24 hours."
          },
          {
            "$ref": "#/components/parameters/RequestId"
          },
          {
            "$ref": "#/components/parameters/Traceparent"
          },
          {
            "$ref": "#/components/parameters/Tracestate"
          },
          {
            "$ref": "#/components/parameters/AcceptLanguage"
          }
        ],
        "responses": {
          "201": {
            "description": "Schedule generated",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "success": {
                      "type": "boolean",
                      "example": true
                    },
                    "message": {
                      "type": "string"
                    }
                  }
                },
                "example": {
                  "success": true,
                  "message": "string"
                }
              }
            },
            "headers": {
              "x-fapi-interaction-id": {
                "$ref": "#/components/headers/XFapiInteractionIdResponse"
              },
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/XRateLimitLimit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/XRateLimitRemaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/XRateLimitReset"
              },
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              },
              "X-Idempotent-Replay": {
                "$ref": "#/components/headers/X-Idempotent-Replay"
              },
              "X-Idempotency-Status": {
                "$ref": "#/components/headers/X-Idempotency-Status"
              },
              "traceparent": {
                "$ref": "#/components/headers/Traceparent"
              },
              "Content-Language": {
                "$ref": "#/components/headers/Content-Language"
              }
            }
          },
          "400": {
            "description": "Bad request",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              },
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                },
                "examples": {
                  "error": {
                    "$ref": "#/components/examples/ErrorBadRequest"
                  }
                }
              }
            },
            "headers": {
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/XRateLimitLimit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/XRateLimitRemaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/XRateLimitReset"
              },
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "403": {
            "$ref": "#/components/responses/Forbidden",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "404": {
            "$ref": "#/components/responses/NotFound",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "409": {
            "$ref": "#/components/responses/Conflict",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "429": {
            "$ref": "#/components/responses/TooManyRequests",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "500": {
            "$ref": "#/components/responses/InternalServerError",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          }
        },
        "x-codeSamples": [
          {
            "lang": "cURL",
            "label": "cURL",
            "source": "curl -X POST \"https://api.kangopenbanking.com/v1/loans/{loanId}/schedule\" \\\n  -H \"Authorization: Bearer $KOB_ACCESS_TOKEN\" \\\n  -H \"Content-Type: application/json\""
          },
          {
            "lang": "JavaScript",
            "label": "Node.js",
            "source": "import { KangOpenBanking } from \"@kangopenbanking/sdk\";\n\nconst kob = new KangOpenBanking({ apiKey: process.env.KOB_API_KEY });\nconst res = await kob.request(\"POST\", \"/v1/loans/{loanId}/schedule\");\nconsole.log(res);"
          },
          {
            "lang": "Python",
            "label": "Python",
            "source": "from kangopenbanking import KangOpenBanking\n\nkob = KangOpenBanking(api_key=os.environ[\"KOB_API_KEY\"])\nres = kob.request(\"POST\", \"/v1/loans/{loanId}/schedule\")\nprint(res)"
          },
          {
            "lang": "PHP",
            "label": "PHP",
            "source": "<?php\n$kob = new KangOpenBanking\\KangOpenBanking(getenv('KOB_API_KEY'));\n$res = $kob->request('POST', '/v1/loans/{loanId}/schedule');\nprint_r($res);"
          }
        ]
      }
    },
    "/v1/loans/{loanId}/repay": {
      "post": {
        "tags": [
          "Loans"
        ],
        "summary": "Make loan repayment",
        "operationId": "loanRepay",
        "security": [
          {
            "bearerAuth": []
          }
        ],
        "parameters": [
          {
            "name": "loanId",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "Idempotency-Key",
            "in": "header",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid"
            },
            "description": "Required on all POST/PUT endpoints. Unique key for idempotent request processing (UUID v4 recommended). Keys expire after 24 hours."
          },
          {
            "$ref": "#/components/parameters/RequestId"
          },
          {
            "$ref": "#/components/parameters/Traceparent"
          },
          {
            "$ref": "#/components/parameters/Tracestate"
          },
          {
            "$ref": "#/components/parameters/AcceptLanguage"
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "required": [
                  "amount"
                ],
                "properties": {
                  "amount": {
                    "type": "string",
                    "example": "92500",
                    "pattern": "^[0-9]{1,15}$",
                    "description": "Represented as a string integer in the currency's minor unit (XAF has no subunits)."
                  },
                  "payment_method": {
                    "type": "string",
                    "enum": [
                      "bank_transfer",
                      "mobile_money",
                      "savings_debit"
                    ]
                  }
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Repayment recorded with schedule/ledger update",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "repayment_id": {
                      "type": "string",
                      "format": "uuid"
                    },
                    "amount_applied": {
                      "type": "number"
                    },
                    "remaining_balance": {
                      "type": "number"
                    },
                    "next_installment": {
                      "$ref": "#/components/schemas/LoanScheduleItem"
                    }
                  }
                },
                "example": {
                  "repayment_id": "00000000-0000-4000-8000-000000000000",
                  "amount_applied": 0,
                  "remaining_balance": 0,
                  "next_installment": {
                    "installment_number": 1,
                    "due_date": "2026-03-16",
                    "principal": "80000",
                    "interest": "12500",
                    "fees": "0",
                    "total_due": 92500,
                    "outstanding_balance": "920000",
                    "status": "pending"
                  }
                }
              }
            },
            "headers": {
              "x-fapi-interaction-id": {
                "$ref": "#/components/headers/XFapiInteractionIdResponse"
              },
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/XRateLimitLimit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/XRateLimitRemaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/XRateLimitReset"
              },
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              },
              "X-Idempotent-Replay": {
                "$ref": "#/components/headers/X-Idempotent-Replay"
              },
              "X-Idempotency-Status": {
                "$ref": "#/components/headers/X-Idempotency-Status"
              },
              "traceparent": {
                "$ref": "#/components/headers/Traceparent"
              },
              "Content-Language": {
                "$ref": "#/components/headers/Content-Language"
              }
            }
          },
          "400": {
            "description": "Bad request",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              },
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                },
                "examples": {
                  "error": {
                    "$ref": "#/components/examples/ErrorBadRequest"
                  }
                }
              }
            },
            "headers": {
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/XRateLimitLimit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/XRateLimitRemaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/XRateLimitReset"
              },
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "403": {
            "$ref": "#/components/responses/Forbidden",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "404": {
            "$ref": "#/components/responses/NotFound",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "409": {
            "$ref": "#/components/responses/Conflict",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "429": {
            "$ref": "#/components/responses/TooManyRequests",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "500": {
            "$ref": "#/components/responses/InternalServerError",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          }
        },
        "x-codeSamples": [
          {
            "lang": "cURL",
            "label": "cURL",
            "source": "curl -X POST \"https://api.kangopenbanking.com/v1/loans/{loanId}/repay\" \\\n  -H \"Authorization: Bearer $KOB_ACCESS_TOKEN\" \\\n  -H \"Content-Type: application/json\" \\\n  -d '{}'"
          },
          {
            "lang": "JavaScript",
            "label": "Node.js",
            "source": "import { KangOpenBanking } from \"@kangopenbanking/sdk\";\n\nconst kob = new KangOpenBanking({ apiKey: process.env.KOB_API_KEY });\nconst res = await kob.request(\"POST\", \"/v1/loans/{loanId}/repay\", { /* payload */ });\nconsole.log(res);"
          },
          {
            "lang": "Python",
            "label": "Python",
            "source": "from kangopenbanking import KangOpenBanking\n\nkob = KangOpenBanking(api_key=os.environ[\"KOB_API_KEY\"])\nres = kob.request(\"POST\", \"/v1/loans/{loanId}/repay\", json={})\nprint(res)"
          },
          {
            "lang": "PHP",
            "label": "PHP",
            "source": "<?php\n$kob = new KangOpenBanking\\KangOpenBanking(getenv('KOB_API_KEY'));\n$res = $kob->request('POST', '/v1/loans/{loanId}/repay', []);\nprint_r($res);"
          }
        ]
      }
    },
    "/v1/savings/products": {
      "get": {
        "tags": [
          "Savings"
        ],
        "summary": "List savings products",
        "operationId": "savingsProducts",
        "security": [
          {
            "bearerAuth": []
          }
        ],
        "responses": {
          "200": {
            "description": "Savings products",
            "content": {
              "application/json": {
                "schema": {
                  "allOf": [
                    {
                      "$ref": "#/components/schemas/PaginatedResponse"
                    },
                    {
                      "type": "object",
                      "properties": {
                        "data": {
                          "type": "array",
                          "items": {}
                        }
                      }
                    }
                  ]
                },
                "example": {
                  "data": [
                    {}
                  ],
                  "pagination": {
                    "page": 1,
                    "limit": 20,
                    "total": 150,
                    "has_next": true,
                    "next_cursor": "eyJpZCI6IjEyMyJ9"
                  },
                  "meta": {
                    "request_id": "550e8400-e29b-41d4-a716-446655440000",
                    "timestamp": "2025-03-27T12:00:00Z",
                    "api_version": "4.3.0"
                  }
                }
              }
            },
            "headers": {
              "x-fapi-interaction-id": {
                "$ref": "#/components/headers/XFapiInteractionIdResponse"
              },
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/XRateLimitLimit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/XRateLimitRemaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/XRateLimitReset"
              },
              "Cache-Control": {
                "$ref": "#/components/headers/CacheControl"
              },
              "ETag": {
                "$ref": "#/components/headers/ETag"
              },
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              },
              "traceparent": {
                "$ref": "#/components/headers/Traceparent"
              },
              "Content-Language": {
                "$ref": "#/components/headers/Content-Language"
              }
            }
          },
          "400": {
            "description": "Bad request",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              },
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                },
                "examples": {
                  "error": {
                    "$ref": "#/components/examples/ErrorBadRequest"
                  }
                }
              }
            },
            "headers": {
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/XRateLimitLimit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/XRateLimitRemaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/XRateLimitReset"
              },
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "403": {
            "$ref": "#/components/responses/Forbidden",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "404": {
            "$ref": "#/components/responses/NotFound",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "409": {
            "$ref": "#/components/responses/Conflict",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "429": {
            "$ref": "#/components/responses/TooManyRequests",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "500": {
            "$ref": "#/components/responses/InternalServerError",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          }
        },
        "parameters": [
          {
            "$ref": "#/components/parameters/PageParam"
          },
          {
            "$ref": "#/components/parameters/LimitParam"
          },
          {
            "$ref": "#/components/parameters/CursorParam"
          },
          {
            "$ref": "#/components/parameters/RequestId"
          },
          {
            "$ref": "#/components/parameters/Traceparent"
          },
          {
            "$ref": "#/components/parameters/Tracestate"
          },
          {
            "$ref": "#/components/parameters/AcceptLanguage"
          }
        ],
        "x-codeSamples": [
          {
            "lang": "cURL",
            "label": "cURL",
            "source": "curl -X GET \"https://api.kangopenbanking.com/v1/savings/products\" \\\n  -H \"Authorization: Bearer $KOB_ACCESS_TOKEN\" \\\n  -H \"Content-Type: application/json\""
          },
          {
            "lang": "JavaScript",
            "label": "Node.js",
            "source": "import { KangOpenBanking } from \"@kangopenbanking/sdk\";\n\nconst kob = new KangOpenBanking({ apiKey: process.env.KOB_API_KEY });\nconst res = await kob.request(\"GET\", \"/v1/savings/products\");\nconsole.log(res);"
          },
          {
            "lang": "Python",
            "label": "Python",
            "source": "from kangopenbanking import KangOpenBanking\n\nkob = KangOpenBanking(api_key=os.environ[\"KOB_API_KEY\"])\nres = kob.request(\"GET\", \"/v1/savings/products\")\nprint(res)"
          },
          {
            "lang": "PHP",
            "label": "PHP",
            "source": "<?php\n$kob = new KangOpenBanking\\KangOpenBanking(getenv('KOB_API_KEY'));\n$res = $kob->request('GET', '/v1/savings/products');\nprint_r($res);"
          }
        ]
      }
    },
    "/v1/savings/accounts": {
      "post": {
        "tags": [
          "Savings"
        ],
        "summary": "Create savings account",
        "operationId": "savingsCreate",
        "security": [
          {
            "bearerAuth": []
          }
        ],
        "parameters": [
          {
            "name": "Idempotency-Key",
            "in": "header",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid"
            },
            "description": "Required on all POST/PUT endpoints. Unique key for idempotent request processing (UUID v4 recommended). Keys expire after 24 hours."
          },
          {
            "$ref": "#/components/parameters/RequestId"
          },
          {
            "$ref": "#/components/parameters/Traceparent"
          },
          {
            "$ref": "#/components/parameters/Tracestate"
          },
          {
            "$ref": "#/components/parameters/AcceptLanguage"
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "required": [
                  "product_id"
                ],
                "properties": {
                  "product_id": {
                    "type": "string"
                  },
                  "initial_deposit": {
                    "type": "number",
                    "example": 50000
                  },
                  "currency": {
                    "type": "string",
                    "example": "XAF",
                    "enum": [
                      "XAF",
                      "XOF",
                      "USD",
                      "EUR",
                      "GBP",
                      "CNY",
                      "NGN",
                      "GHS",
                      "KES",
                      "ZAR"
                    ],
                    "default": "XAF",
                    "description": "ISO 4217 currency code. Default is XAF (Central African CFA Franc)."
                  }
                }
              }
            }
          }
        },
        "responses": {
          "201": {
            "description": "Savings account created",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/SavingsAccount"
                },
                "example": {
                  "account_id": "00000000-0000-4000-8000-000000000000",
                  "product_id": "string",
                  "account_number": "string",
                  "account_holder_name": "string",
                  "balance": "1000",
                  "currency": "XAF",
                  "status": "active",
                  "interest_rate": 0,
                  "opened_date": "2026-01-01",
                  "maturity_date": "2026-01-01",
                  "created_at": "2026-01-01T00:00:00Z",
                  "updated_at": "2026-01-01T00:00:00Z"
                }
              }
            },
            "headers": {
              "x-fapi-interaction-id": {
                "$ref": "#/components/headers/XFapiInteractionIdResponse"
              },
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/XRateLimitLimit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/XRateLimitRemaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/XRateLimitReset"
              },
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              },
              "X-Idempotent-Replay": {
                "$ref": "#/components/headers/X-Idempotent-Replay"
              },
              "X-Idempotency-Status": {
                "$ref": "#/components/headers/X-Idempotency-Status"
              },
              "traceparent": {
                "$ref": "#/components/headers/Traceparent"
              },
              "Content-Language": {
                "$ref": "#/components/headers/Content-Language"
              }
            }
          },
          "400": {
            "description": "Bad request",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              },
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                },
                "examples": {
                  "error": {
                    "$ref": "#/components/examples/ErrorBadRequest"
                  }
                }
              }
            },
            "headers": {
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/XRateLimitLimit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/XRateLimitRemaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/XRateLimitReset"
              },
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "403": {
            "$ref": "#/components/responses/Forbidden",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "404": {
            "$ref": "#/components/responses/NotFound",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "409": {
            "$ref": "#/components/responses/Conflict",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "429": {
            "$ref": "#/components/responses/TooManyRequests",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "500": {
            "$ref": "#/components/responses/InternalServerError",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          }
        },
        "x-codeSamples": [
          {
            "lang": "cURL",
            "label": "cURL",
            "source": "curl -X POST \"https://api.kangopenbanking.com/v1/savings/accounts\" \\\n  -H \"Authorization: Bearer $KOB_ACCESS_TOKEN\" \\\n  -H \"Content-Type: application/json\" \\\n  -d '{}'"
          },
          {
            "lang": "JavaScript",
            "label": "Node.js",
            "source": "import { KangOpenBanking } from \"@kangopenbanking/sdk\";\n\nconst kob = new KangOpenBanking({ apiKey: process.env.KOB_API_KEY });\nconst res = await kob.request(\"POST\", \"/v1/savings/accounts\", { /* payload */ });\nconsole.log(res);"
          },
          {
            "lang": "Python",
            "label": "Python",
            "source": "from kangopenbanking import KangOpenBanking\n\nkob = KangOpenBanking(api_key=os.environ[\"KOB_API_KEY\"])\nres = kob.request(\"POST\", \"/v1/savings/accounts\", json={})\nprint(res)"
          },
          {
            "lang": "PHP",
            "label": "PHP",
            "source": "<?php\n$kob = new KangOpenBanking\\KangOpenBanking(getenv('KOB_API_KEY'));\n$res = $kob->request('POST', '/v1/savings/accounts', []);\nprint_r($res);"
          }
        ]
      },
      "get": {
        "operationId": "listSavingsAccounts",
        "summary": "List savings accounts",
        "description": "Retrieve a paginated list of savings accounts for the authenticated user. Requires a valid AISP consent.",
        "tags": [
          "Savings",
          "AISP"
        ],
        "security": [
          {
            "bearerAuth": []
          }
        ],
        "parameters": [
          {
            "name": "x-consent-id",
            "in": "header",
            "required": true,
            "description": "Active AISP consent ID",
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          },
          {
            "$ref": "#/components/parameters/PageParam"
          },
          {
            "$ref": "#/components/parameters/LimitParam"
          },
          {
            "$ref": "#/components/parameters/CursorParam"
          },
          {
            "$ref": "#/components/parameters/XFapiInteractionId"
          },
          {
            "$ref": "#/components/parameters/RequestId"
          },
          {
            "$ref": "#/components/parameters/Traceparent"
          },
          {
            "$ref": "#/components/parameters/Tracestate"
          },
          {
            "$ref": "#/components/parameters/AcceptLanguage"
          }
        ],
        "responses": {
          "200": {
            "description": "Paginated list of savings accounts",
            "headers": {
              "x-fapi-interaction-id": {
                "$ref": "#/components/headers/XFapiInteractionIdResponse"
              },
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/XRateLimitLimit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/XRateLimitRemaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/XRateLimitReset"
              },
              "Cache-Control": {
                "$ref": "#/components/headers/CacheControl"
              },
              "ETag": {
                "$ref": "#/components/headers/ETag"
              },
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              },
              "traceparent": {
                "$ref": "#/components/headers/Traceparent"
              },
              "Content-Language": {
                "$ref": "#/components/headers/Content-Language"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "allOf": [
                    {
                      "$ref": "#/components/schemas/PaginatedResponse"
                    },
                    {
                      "type": "object",
                      "properties": {
                        "data": {
                          "type": "array",
                          "items": {
                            "$ref": "#/components/schemas/SavingsAccount"
                          }
                        }
                      }
                    }
                  ]
                },
                "example": {
                  "data": [
                    {
                      "account_id": "f1d6f4a0-1d4e-4a3a-9e0a-1a2b3c4d5e6f",
                      "product_id": "XAF",
                      "account_number": "XAF",
                      "account_holder_name": "XAF",
                      "balance": "1000",
                      "currency": "XAF",
                      "status": "active",
                      "interest_rate": 1,
                      "opened_date": "2026-01-31",
                      "maturity_date": "2026-01-31",
                      "created_at": "2026-01-31T12:00:00Z",
                      "updated_at": "2026-01-31T12:00:00Z"
                    }
                  ],
                  "pagination": {
                    "page": 1,
                    "limit": 20,
                    "total": 150,
                    "has_next": true,
                    "next_cursor": "eyJpZCI6IjEyMyJ9"
                  },
                  "meta": {
                    "request_id": "550e8400-e29b-41d4-a716-446655440000",
                    "timestamp": "2025-03-27T12:00:00Z",
                    "api_version": "4.3.0"
                  }
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "403": {
            "$ref": "#/components/responses/Forbidden",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "429": {
            "$ref": "#/components/responses/TooManyRequests",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "default": {
            "description": "Server error — see ProblemDetails for trace ID.",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            },
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/XRateLimitLimit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/XRateLimitRemaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/XRateLimitReset"
              }
            }
          }
        },
        "x-codeSamples": [
          {
            "lang": "cURL",
            "label": "cURL",
            "source": "curl -X GET \"https://api.kangopenbanking.com/v1/savings/accounts\" \\\n  -H \"Authorization: Bearer $KOB_ACCESS_TOKEN\" \\\n  -H \"Content-Type: application/json\""
          },
          {
            "lang": "JavaScript",
            "label": "Node.js",
            "source": "import { KangOpenBanking } from \"@kangopenbanking/sdk\";\n\nconst kob = new KangOpenBanking({ apiKey: process.env.KOB_API_KEY });\nconst res = await kob.request(\"GET\", \"/v1/savings/accounts\");\nconsole.log(res);"
          },
          {
            "lang": "Python",
            "label": "Python",
            "source": "from kangopenbanking import KangOpenBanking\n\nkob = KangOpenBanking(api_key=os.environ[\"KOB_API_KEY\"])\nres = kob.request(\"GET\", \"/v1/savings/accounts\")\nprint(res)"
          },
          {
            "lang": "PHP",
            "label": "PHP",
            "source": "<?php\n$kob = new KangOpenBanking\\KangOpenBanking(getenv('KOB_API_KEY'));\n$res = $kob->request('GET', '/v1/savings/accounts');\nprint_r($res);"
          }
        ]
      }
    },
    "/v1/savings/accounts/{accountId}/deposit": {
      "post": {
        "tags": [
          "Savings"
        ],
        "summary": "Deposit to savings",
        "operationId": "savingsDeposit",
        "security": [
          {
            "bearerAuth": []
          }
        ],
        "parameters": [
          {
            "name": "accountId",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "Idempotency-Key",
            "in": "header",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid"
            },
            "description": "Required on all POST/PUT endpoints. Unique key for idempotent request processing (UUID v4 recommended). Keys expire after 24 hours."
          },
          {
            "$ref": "#/components/parameters/RequestId"
          },
          {
            "$ref": "#/components/parameters/Traceparent"
          },
          {
            "$ref": "#/components/parameters/Tracestate"
          },
          {
            "$ref": "#/components/parameters/AcceptLanguage"
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "required": [
                  "amount"
                ],
                "properties": {
                  "amount": {
                    "type": "string",
                    "example": "50000",
                    "pattern": "^[0-9]{1,15}$",
                    "description": "Represented as a string integer in the currency's minor unit (XAF has no subunits)."
                  },
                  "source": {
                    "type": "string",
                    "enum": [
                      "bank_transfer",
                      "mobile_money"
                    ]
                  }
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Deposit recorded",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "success": {
                      "type": "boolean",
                      "example": true
                    },
                    "message": {
                      "type": "string"
                    }
                  }
                },
                "example": {
                  "success": true,
                  "message": "string"
                }
              }
            },
            "headers": {
              "x-fapi-interaction-id": {
                "$ref": "#/components/headers/XFapiInteractionIdResponse"
              },
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/XRateLimitLimit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/XRateLimitRemaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/XRateLimitReset"
              },
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              },
              "X-Idempotent-Replay": {
                "$ref": "#/components/headers/X-Idempotent-Replay"
              },
              "X-Idempotency-Status": {
                "$ref": "#/components/headers/X-Idempotency-Status"
              },
              "traceparent": {
                "$ref": "#/components/headers/Traceparent"
              },
              "Content-Language": {
                "$ref": "#/components/headers/Content-Language"
              }
            }
          },
          "400": {
            "description": "Bad request",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              },
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                },
                "examples": {
                  "error": {
                    "$ref": "#/components/examples/ErrorBadRequest"
                  }
                }
              }
            },
            "headers": {
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/XRateLimitLimit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/XRateLimitRemaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/XRateLimitReset"
              },
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "403": {
            "$ref": "#/components/responses/Forbidden",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "404": {
            "$ref": "#/components/responses/NotFound",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "409": {
            "$ref": "#/components/responses/Conflict",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "429": {
            "$ref": "#/components/responses/TooManyRequests",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "500": {
            "$ref": "#/components/responses/InternalServerError",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          }
        },
        "x-codeSamples": [
          {
            "lang": "cURL",
            "label": "cURL",
            "source": "curl -X POST \"https://api.kangopenbanking.com/v1/savings/accounts/{accountId}/deposit\" \\\n  -H \"Authorization: Bearer $KOB_ACCESS_TOKEN\" \\\n  -H \"Content-Type: application/json\" \\\n  -d '{}'"
          },
          {
            "lang": "JavaScript",
            "label": "Node.js",
            "source": "import { KangOpenBanking } from \"@kangopenbanking/sdk\";\n\nconst kob = new KangOpenBanking({ apiKey: process.env.KOB_API_KEY });\nconst res = await kob.request(\"POST\", \"/v1/savings/accounts/{accountId}/deposit\", { /* payload */ });\nconsole.log(res);"
          },
          {
            "lang": "Python",
            "label": "Python",
            "source": "from kangopenbanking import KangOpenBanking\n\nkob = KangOpenBanking(api_key=os.environ[\"KOB_API_KEY\"])\nres = kob.request(\"POST\", \"/v1/savings/accounts/{accountId}/deposit\", json={})\nprint(res)"
          },
          {
            "lang": "PHP",
            "label": "PHP",
            "source": "<?php\n$kob = new KangOpenBanking\\KangOpenBanking(getenv('KOB_API_KEY'));\n$res = $kob->request('POST', '/v1/savings/accounts/{accountId}/deposit', []);\nprint_r($res);"
          }
        ]
      }
    },
    "/v1/savings/accounts/{accountId}/withdraw": {
      "post": {
        "tags": [
          "Savings"
        ],
        "summary": "Withdraw from savings",
        "operationId": "savingsWithdraw",
        "security": [
          {
            "bearerAuth": []
          }
        ],
        "parameters": [
          {
            "name": "accountId",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "Idempotency-Key",
            "in": "header",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid"
            },
            "description": "Required on all POST/PUT endpoints. Unique key for idempotent request processing (UUID v4 recommended). Keys expire after 24 hours."
          },
          {
            "$ref": "#/components/parameters/RequestId"
          },
          {
            "$ref": "#/components/parameters/Traceparent"
          },
          {
            "$ref": "#/components/parameters/Tracestate"
          },
          {
            "$ref": "#/components/parameters/AcceptLanguage"
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "required": [
                  "amount"
                ],
                "properties": {
                  "amount": {
                    "type": "string",
                    "example": "25000",
                    "pattern": "^[0-9]{1,15}$",
                    "description": "Represented as a string integer in the currency's minor unit (XAF has no subunits)."
                  },
                  "destination": {
                    "type": "string"
                  }
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Withdrawal recorded",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "success": {
                      "type": "boolean",
                      "example": true
                    },
                    "message": {
                      "type": "string"
                    }
                  }
                },
                "example": {
                  "success": true,
                  "message": "string"
                }
              }
            },
            "headers": {
              "x-fapi-interaction-id": {
                "$ref": "#/components/headers/XFapiInteractionIdResponse"
              },
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/XRateLimitLimit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/XRateLimitRemaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/XRateLimitReset"
              },
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              },
              "X-Idempotent-Replay": {
                "$ref": "#/components/headers/X-Idempotent-Replay"
              },
              "X-Idempotency-Status": {
                "$ref": "#/components/headers/X-Idempotency-Status"
              },
              "traceparent": {
                "$ref": "#/components/headers/Traceparent"
              },
              "Content-Language": {
                "$ref": "#/components/headers/Content-Language"
              }
            }
          },
          "400": {
            "description": "Bad request",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              },
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                },
                "examples": {
                  "error": {
                    "$ref": "#/components/examples/ErrorBadRequest"
                  }
                }
              }
            },
            "headers": {
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/XRateLimitLimit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/XRateLimitRemaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/XRateLimitReset"
              },
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "403": {
            "$ref": "#/components/responses/Forbidden",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "404": {
            "$ref": "#/components/responses/NotFound",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "409": {
            "$ref": "#/components/responses/Conflict",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "429": {
            "$ref": "#/components/responses/TooManyRequests",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "500": {
            "$ref": "#/components/responses/InternalServerError",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          }
        },
        "x-codeSamples": [
          {
            "lang": "cURL",
            "label": "cURL",
            "source": "curl -X POST \"https://api.kangopenbanking.com/v1/savings/accounts/{accountId}/withdraw\" \\\n  -H \"Authorization: Bearer $KOB_ACCESS_TOKEN\" \\\n  -H \"Content-Type: application/json\" \\\n  -d '{}'"
          },
          {
            "lang": "JavaScript",
            "label": "Node.js",
            "source": "import { KangOpenBanking } from \"@kangopenbanking/sdk\";\n\nconst kob = new KangOpenBanking({ apiKey: process.env.KOB_API_KEY });\nconst res = await kob.request(\"POST\", \"/v1/savings/accounts/{accountId}/withdraw\", { /* payload */ });\nconsole.log(res);"
          },
          {
            "lang": "Python",
            "label": "Python",
            "source": "from kangopenbanking import KangOpenBanking\n\nkob = KangOpenBanking(api_key=os.environ[\"KOB_API_KEY\"])\nres = kob.request(\"POST\", \"/v1/savings/accounts/{accountId}/withdraw\", json={})\nprint(res)"
          },
          {
            "lang": "PHP",
            "label": "PHP",
            "source": "<?php\n$kob = new KangOpenBanking\\KangOpenBanking(getenv('KOB_API_KEY'));\n$res = $kob->request('POST', '/v1/savings/accounts/{accountId}/withdraw', []);\nprint_r($res);"
          }
        ]
      }
    },
    "/v1/savings/accrue-interest": {
      "post": {
        "tags": [
          "Savings"
        ],
        "summary": "Accrue interest (cron)",
        "description": "Trigger interest accrual across all eligible savings accounts. Designed for scheduled (cron) invocation.",
        "operationId": "savingsAccrueInterest",
        "security": [
          {
            "bearerAuth": []
          }
        ],
        "parameters": [
          {
            "name": "Idempotency-Key",
            "in": "header",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid"
            },
            "description": "Required on all POST/PUT endpoints. Unique key for idempotent request processing (UUID v4 recommended). Keys expire after 24 hours."
          },
          {
            "$ref": "#/components/parameters/RequestId"
          },
          {
            "$ref": "#/components/parameters/Traceparent"
          },
          {
            "$ref": "#/components/parameters/Tracestate"
          },
          {
            "$ref": "#/components/parameters/AcceptLanguage"
          }
        ],
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "accrual_date": {
                    "type": "string",
                    "format": "date"
                  }
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Interest accrued",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "accounts_processed": {
                      "type": "integer"
                    },
                    "total_interest": {
                      "type": "number"
                    },
                    "accrual_date": {
                      "type": "string",
                      "format": "date"
                    }
                  }
                },
                "example": {
                  "accounts_processed": 0,
                  "total_interest": 0,
                  "accrual_date": "2026-01-01"
                }
              }
            },
            "headers": {
              "x-fapi-interaction-id": {
                "$ref": "#/components/headers/XFapiInteractionIdResponse"
              },
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/XRateLimitLimit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/XRateLimitRemaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/XRateLimitReset"
              },
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              },
              "X-Idempotent-Replay": {
                "$ref": "#/components/headers/X-Idempotent-Replay"
              },
              "X-Idempotency-Status": {
                "$ref": "#/components/headers/X-Idempotency-Status"
              },
              "traceparent": {
                "$ref": "#/components/headers/Traceparent"
              },
              "Content-Language": {
                "$ref": "#/components/headers/Content-Language"
              }
            }
          },
          "400": {
            "description": "Bad request",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              },
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                },
                "examples": {
                  "error": {
                    "$ref": "#/components/examples/ErrorBadRequest"
                  }
                }
              }
            },
            "headers": {
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/XRateLimitLimit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/XRateLimitRemaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/XRateLimitReset"
              },
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "403": {
            "$ref": "#/components/responses/Forbidden",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "404": {
            "$ref": "#/components/responses/NotFound",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "409": {
            "$ref": "#/components/responses/Conflict",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "429": {
            "$ref": "#/components/responses/TooManyRequests",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "500": {
            "$ref": "#/components/responses/InternalServerError",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          }
        },
        "x-codeSamples": [
          {
            "lang": "cURL",
            "label": "cURL",
            "source": "curl -X POST \"https://api.kangopenbanking.com/v1/savings/accrue-interest\" \\\n  -H \"Authorization: Bearer $KOB_ACCESS_TOKEN\" \\\n  -H \"Content-Type: application/json\" \\\n  -d '{}'"
          },
          {
            "lang": "JavaScript",
            "label": "Node.js",
            "source": "import { KangOpenBanking } from \"@kangopenbanking/sdk\";\n\nconst kob = new KangOpenBanking({ apiKey: process.env.KOB_API_KEY });\nconst res = await kob.request(\"POST\", \"/v1/savings/accrue-interest\", { /* payload */ });\nconsole.log(res);"
          },
          {
            "lang": "Python",
            "label": "Python",
            "source": "from kangopenbanking import KangOpenBanking\n\nkob = KangOpenBanking(api_key=os.environ[\"KOB_API_KEY\"])\nres = kob.request(\"POST\", \"/v1/savings/accrue-interest\", json={})\nprint(res)"
          },
          {
            "lang": "PHP",
            "label": "PHP",
            "source": "<?php\n$kob = new KangOpenBanking\\KangOpenBanking(getenv('KOB_API_KEY'));\n$res = $kob->request('POST', '/v1/savings/accrue-interest', []);\nprint_r($res);"
          }
        ]
      }
    },
    "/v1/ledger/accounts": {
      "get": {
        "tags": [
          "Ledger"
        ],
        "summary": "List ledger accounts",
        "operationId": "ledgerAccounts",
        "security": [
          {
            "bearerAuth": []
          }
        ],
        "parameters": [
          {
            "name": "limit",
            "in": "query",
            "schema": {
              "type": "integer",
              "default": 25,
              "maximum": 100
            },
            "description": "Items per page"
          },
          {
            "name": "offset",
            "in": "query",
            "schema": {
              "type": "integer",
              "default": 0
            },
            "description": "Items to skip"
          },
          {
            "name": "sort_by",
            "in": "query",
            "schema": {
              "type": "string",
              "default": "created_at"
            },
            "description": "Sort field"
          },
          {
            "name": "sort_order",
            "in": "query",
            "schema": {
              "type": "string",
              "enum": [
                "asc",
                "desc"
              ],
              "default": "desc"
            },
            "description": "Sort direction"
          },
          {
            "$ref": "#/components/parameters/StartingAfter"
          },
          {
            "$ref": "#/components/parameters/EndingBefore"
          },
          {
            "$ref": "#/components/parameters/RequestId"
          },
          {
            "$ref": "#/components/parameters/Traceparent"
          },
          {
            "$ref": "#/components/parameters/Tracestate"
          },
          {
            "$ref": "#/components/parameters/AcceptLanguage"
          }
        ],
        "responses": {
          "200": {
            "description": "Ledger accounts (chart of accounts)",
            "content": {
              "application/json": {
                "schema": {
                  "allOf": [
                    {
                      "$ref": "#/components/schemas/PaginatedResponse"
                    },
                    {
                      "type": "object",
                      "properties": {
                        "data": {
                          "type": "array",
                          "items": {
                            "$ref": "#/components/schemas/LedgerAccount"
                          }
                        }
                      }
                    }
                  ]
                },
                "example": {
                  "data": [
                    {
                      "id": "f1d6f4a0-1d4e-4a3a-9e0a-1a2b3c4d5e6f",
                      "code": "1000",
                      "name": "Cash and Cash Equivalents",
                      "account_type": "asset",
                      "currency": "XAF",
                      "balance": "25000000",
                      "is_active": false
                    }
                  ],
                  "pagination": {
                    "page": 1,
                    "limit": 20,
                    "total": 150,
                    "has_next": true,
                    "next_cursor": "eyJpZCI6IjEyMyJ9"
                  },
                  "meta": {
                    "request_id": "550e8400-e29b-41d4-a716-446655440000",
                    "timestamp": "2025-03-27T12:00:00Z",
                    "api_version": "4.3.0"
                  }
                }
              }
            },
            "headers": {
              "x-fapi-interaction-id": {
                "$ref": "#/components/headers/XFapiInteractionIdResponse"
              },
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/XRateLimitLimit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/XRateLimitRemaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/XRateLimitReset"
              },
              "Cache-Control": {
                "$ref": "#/components/headers/CacheControl"
              },
              "ETag": {
                "$ref": "#/components/headers/ETag"
              },
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              },
              "traceparent": {
                "$ref": "#/components/headers/Traceparent"
              },
              "Content-Language": {
                "$ref": "#/components/headers/Content-Language"
              }
            }
          },
          "400": {
            "description": "Bad request",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              },
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                },
                "examples": {
                  "error": {
                    "$ref": "#/components/examples/ErrorBadRequest"
                  }
                }
              }
            },
            "headers": {
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/XRateLimitLimit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/XRateLimitRemaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/XRateLimitReset"
              },
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "403": {
            "$ref": "#/components/responses/Forbidden",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "404": {
            "$ref": "#/components/responses/NotFound",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "409": {
            "$ref": "#/components/responses/Conflict",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "429": {
            "$ref": "#/components/responses/TooManyRequests",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "500": {
            "$ref": "#/components/responses/InternalServerError",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          }
        },
        "x-codeSamples": [
          {
            "lang": "cURL",
            "label": "cURL",
            "source": "curl -X GET \"https://api.kangopenbanking.com/v1/ledger/accounts\" \\\n  -H \"Authorization: Bearer $KOB_ACCESS_TOKEN\" \\\n  -H \"Content-Type: application/json\""
          },
          {
            "lang": "JavaScript",
            "label": "Node.js",
            "source": "import { KangOpenBanking } from \"@kangopenbanking/sdk\";\n\nconst kob = new KangOpenBanking({ apiKey: process.env.KOB_API_KEY });\nconst res = await kob.request(\"GET\", \"/v1/ledger/accounts\");\nconsole.log(res);"
          },
          {
            "lang": "Python",
            "label": "Python",
            "source": "from kangopenbanking import KangOpenBanking\n\nkob = KangOpenBanking(api_key=os.environ[\"KOB_API_KEY\"])\nres = kob.request(\"GET\", \"/v1/ledger/accounts\")\nprint(res)"
          },
          {
            "lang": "PHP",
            "label": "PHP",
            "source": "<?php\n$kob = new KangOpenBanking\\KangOpenBanking(getenv('KOB_API_KEY'));\n$res = $kob->request('GET', '/v1/ledger/accounts');\nprint_r($res);"
          }
        ]
      },
      "post": {
        "tags": [
          "Ledger"
        ],
        "summary": "Create ledger account",
        "operationId": "ledgerAccountCreate",
        "security": [
          {
            "bearerAuth": []
          }
        ],
        "parameters": [
          {
            "name": "Idempotency-Key",
            "in": "header",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid"
            },
            "description": "Required on all POST/PUT endpoints. Unique key for idempotent request processing (UUID v4 recommended). Keys expire after 24 hours."
          },
          {
            "$ref": "#/components/parameters/RequestId"
          },
          {
            "$ref": "#/components/parameters/Traceparent"
          },
          {
            "$ref": "#/components/parameters/Tracestate"
          },
          {
            "$ref": "#/components/parameters/AcceptLanguage"
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "required": [
                  "code",
                  "name",
                  "account_type"
                ],
                "properties": {
                  "code": {
                    "type": "string",
                    "example": "1000"
                  },
                  "name": {
                    "type": "string",
                    "example": "Cash and Cash Equivalents"
                  },
                  "account_type": {
                    "type": "string",
                    "enum": [
                      "asset",
                      "liability",
                      "equity",
                      "revenue",
                      "expense"
                    ]
                  },
                  "currency": {
                    "type": "string",
                    "example": "XAF",
                    "enum": [
                      "XAF",
                      "XOF",
                      "USD",
                      "EUR",
                      "GBP",
                      "CNY",
                      "NGN",
                      "GHS",
                      "KES",
                      "ZAR"
                    ],
                    "default": "XAF",
                    "description": "ISO 4217 currency code. Default is XAF (Central African CFA Franc)."
                  },
                  "parent_id": {
                    "type": "string",
                    "format": "uuid"
                  }
                }
              }
            }
          }
        },
        "responses": {
          "201": {
            "description": "Ledger account created",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/LedgerAccount"
                },
                "example": {
                  "id": "00000000-0000-4000-8000-000000000000",
                  "code": "1000",
                  "name": "Cash and Cash Equivalents",
                  "account_type": "asset",
                  "currency": "XAF",
                  "balance": "25000000",
                  "is_active": true
                }
              }
            },
            "headers": {
              "x-fapi-interaction-id": {
                "$ref": "#/components/headers/XFapiInteractionIdResponse"
              },
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/XRateLimitLimit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/XRateLimitRemaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/XRateLimitReset"
              },
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              },
              "X-Idempotent-Replay": {
                "$ref": "#/components/headers/X-Idempotent-Replay"
              },
              "X-Idempotency-Status": {
                "$ref": "#/components/headers/X-Idempotency-Status"
              },
              "traceparent": {
                "$ref": "#/components/headers/Traceparent"
              },
              "Content-Language": {
                "$ref": "#/components/headers/Content-Language"
              }
            }
          },
          "400": {
            "description": "Bad request",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              },
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                },
                "examples": {
                  "error": {
                    "$ref": "#/components/examples/ErrorBadRequest"
                  }
                }
              }
            },
            "headers": {
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/XRateLimitLimit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/XRateLimitRemaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/XRateLimitReset"
              },
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "403": {
            "$ref": "#/components/responses/Forbidden",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "404": {
            "$ref": "#/components/responses/NotFound",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "409": {
            "$ref": "#/components/responses/Conflict",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "429": {
            "$ref": "#/components/responses/TooManyRequests",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "500": {
            "$ref": "#/components/responses/InternalServerError",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          }
        },
        "x-codeSamples": [
          {
            "lang": "cURL",
            "label": "cURL",
            "source": "curl -X POST \"https://api.kangopenbanking.com/v1/ledger/accounts\" \\\n  -H \"Authorization: Bearer $KOB_ACCESS_TOKEN\" \\\n  -H \"Content-Type: application/json\" \\\n  -d '{}'"
          },
          {
            "lang": "JavaScript",
            "label": "Node.js",
            "source": "import { KangOpenBanking } from \"@kangopenbanking/sdk\";\n\nconst kob = new KangOpenBanking({ apiKey: process.env.KOB_API_KEY });\nconst res = await kob.request(\"POST\", \"/v1/ledger/accounts\", { /* payload */ });\nconsole.log(res);"
          },
          {
            "lang": "Python",
            "label": "Python",
            "source": "from kangopenbanking import KangOpenBanking\n\nkob = KangOpenBanking(api_key=os.environ[\"KOB_API_KEY\"])\nres = kob.request(\"POST\", \"/v1/ledger/accounts\", json={})\nprint(res)"
          },
          {
            "lang": "PHP",
            "label": "PHP",
            "source": "<?php\n$kob = new KangOpenBanking\\KangOpenBanking(getenv('KOB_API_KEY'));\n$res = $kob->request('POST', '/v1/ledger/accounts', []);\nprint_r($res);"
          }
        ]
      }
    },
    "/v1/ledger/accounts/{accountId}/balance": {
      "get": {
        "tags": [
          "Ledger"
        ],
        "summary": "Get ledger account balance",
        "operationId": "ledgerBalance",
        "security": [
          {
            "bearerAuth": []
          }
        ],
        "parameters": [
          {
            "name": "accountId",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "as_of",
            "in": "query",
            "schema": {
              "type": "string",
              "format": "date"
            }
          },
          {
            "$ref": "#/components/parameters/RequestId"
          },
          {
            "$ref": "#/components/parameters/Traceparent"
          },
          {
            "$ref": "#/components/parameters/Tracestate"
          },
          {
            "$ref": "#/components/parameters/AcceptLanguage"
          }
        ],
        "responses": {
          "200": {
            "description": "Ledger balance",
            "content": {
              "application/json": {
                "schema": {
                  "allOf": [
                    {
                      "$ref": "#/components/schemas/StandardResponse"
                    },
                    {
                      "type": "object",
                      "properties": {
                        "data": {
                          "$ref": "#/components/schemas/LedgerAccount"
                        }
                      }
                    }
                  ]
                },
                "example": {
                  "data": {
                    "id": "00000000-0000-4000-8000-000000000000",
                    "code": "1000",
                    "name": "Cash and Cash Equivalents",
                    "account_type": "asset",
                    "currency": "XAF",
                    "balance": "25000000",
                    "is_active": true
                  },
                  "meta": {
                    "request_id": "550e8400-e29b-41d4-a716-446655440000",
                    "timestamp": "2025-03-27T12:00:00Z",
                    "api_version": "4.3.0"
                  }
                }
              }
            },
            "headers": {
              "x-fapi-interaction-id": {
                "$ref": "#/components/headers/XFapiInteractionIdResponse"
              },
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/XRateLimitLimit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/XRateLimitRemaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/XRateLimitReset"
              },
              "Cache-Control": {
                "$ref": "#/components/headers/CacheControl"
              },
              "ETag": {
                "$ref": "#/components/headers/ETag"
              },
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              },
              "traceparent": {
                "$ref": "#/components/headers/Traceparent"
              },
              "Content-Language": {
                "$ref": "#/components/headers/Content-Language"
              }
            }
          },
          "400": {
            "description": "Bad request",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              },
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                },
                "examples": {
                  "error": {
                    "$ref": "#/components/examples/ErrorBadRequest"
                  }
                }
              }
            },
            "headers": {
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/XRateLimitLimit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/XRateLimitRemaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/XRateLimitReset"
              },
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "403": {
            "$ref": "#/components/responses/Forbidden",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "404": {
            "$ref": "#/components/responses/NotFound",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "409": {
            "$ref": "#/components/responses/Conflict",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "429": {
            "$ref": "#/components/responses/TooManyRequests",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "500": {
            "$ref": "#/components/responses/InternalServerError",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          }
        },
        "x-codeSamples": [
          {
            "lang": "cURL",
            "label": "cURL",
            "source": "curl -X GET \"https://api.kangopenbanking.com/v1/ledger/accounts/{accountId}/balance\" \\\n  -H \"Authorization: Bearer $KOB_ACCESS_TOKEN\" \\\n  -H \"Content-Type: application/json\""
          },
          {
            "lang": "JavaScript",
            "label": "Node.js",
            "source": "import { KangOpenBanking } from \"@kangopenbanking/sdk\";\n\nconst kob = new KangOpenBanking({ apiKey: process.env.KOB_API_KEY });\nconst res = await kob.request(\"GET\", \"/v1/ledger/accounts/{accountId}/balance\");\nconsole.log(res);"
          },
          {
            "lang": "Python",
            "label": "Python",
            "source": "from kangopenbanking import KangOpenBanking\n\nkob = KangOpenBanking(api_key=os.environ[\"KOB_API_KEY\"])\nres = kob.request(\"GET\", \"/v1/ledger/accounts/{accountId}/balance\")\nprint(res)"
          },
          {
            "lang": "PHP",
            "label": "PHP",
            "source": "<?php\n$kob = new KangOpenBanking\\KangOpenBanking(getenv('KOB_API_KEY'));\n$res = $kob->request('GET', '/v1/ledger/accounts/{accountId}/balance');\nprint_r($res);"
          }
        ]
      }
    },
    "/v1/ledger/journal": {
      "post": {
        "tags": [
          "Ledger"
        ],
        "summary": "Post journal entry",
        "description": "Post a balanced double-entry journal entry. Sum of debits must equal sum of credits.",
        "operationId": "journalPost",
        "security": [
          {
            "bearerAuth": []
          }
        ],
        "parameters": [
          {
            "name": "Idempotency-Key",
            "in": "header",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid"
            },
            "description": "Required on all POST/PUT endpoints. Unique key for idempotent request processing (UUID v4 recommended). Keys expire after 24 hours."
          },
          {
            "$ref": "#/components/parameters/RequestId"
          },
          {
            "$ref": "#/components/parameters/Traceparent"
          },
          {
            "$ref": "#/components/parameters/Tracestate"
          },
          {
            "$ref": "#/components/parameters/AcceptLanguage"
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/JournalEntry"
              },
              "example": {
                "entry_date": "2026-02-16",
                "description": "Loan disbursement - 1,000,000 XAF",
                "reference_type": "loan",
                "reference_id": "loan_abc123",
                "lines": [
                  {
                    "ledger_account_id": "acc_loans_receivable",
                    "debit": 1000000,
                    "credit": 0
                  },
                  {
                    "ledger_account_id": "acc_cash",
                    "debit": 0,
                    "credit": 1000000
                  }
                ],
                "id": "f1d6f4a0-1d4e-4a3a-9e0a-1a2b3c4d5e6f"
              }
            }
          }
        },
        "responses": {
          "201": {
            "description": "Journal entry posted",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/JournalEntry"
                },
                "example": {
                  "id": "00000000-0000-4000-8000-000000000000",
                  "entry_date": "2026-01-01",
                  "description": "Loan disbursement - APP-2026-001",
                  "reference_type": "payment",
                  "reference_id": "00000000-0000-4000-8000-000000000000",
                  "lines": [
                    {
                      "ledger_account_id": "00000000-0000-4000-8000-000000000000",
                      "debit": 1000000,
                      "credit": 0
                    }
                  ],
                  "created_at": "2026-01-01T00:00:00Z"
                }
              }
            },
            "headers": {
              "x-fapi-interaction-id": {
                "$ref": "#/components/headers/XFapiInteractionIdResponse"
              },
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/XRateLimitLimit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/XRateLimitRemaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/XRateLimitReset"
              },
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              },
              "X-Idempotent-Replay": {
                "$ref": "#/components/headers/X-Idempotent-Replay"
              },
              "X-Idempotency-Status": {
                "$ref": "#/components/headers/X-Idempotency-Status"
              },
              "traceparent": {
                "$ref": "#/components/headers/Traceparent"
              },
              "Content-Language": {
                "$ref": "#/components/headers/Content-Language"
              }
            }
          },
          "400": {
            "description": "Bad request",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              },
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                },
                "examples": {
                  "error": {
                    "$ref": "#/components/examples/ErrorBadRequest"
                  }
                }
              }
            },
            "headers": {
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/XRateLimitLimit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/XRateLimitRemaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/XRateLimitReset"
              },
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "403": {
            "$ref": "#/components/responses/Forbidden",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "404": {
            "$ref": "#/components/responses/NotFound",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "409": {
            "$ref": "#/components/responses/Conflict",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "429": {
            "$ref": "#/components/responses/TooManyRequests",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "500": {
            "$ref": "#/components/responses/InternalServerError",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          }
        },
        "x-codeSamples": [
          {
            "lang": "cURL",
            "label": "cURL",
            "source": "curl -X POST \"https://api.kangopenbanking.com/v1/ledger/journal\" \\\n  -H \"Authorization: Bearer $KOB_ACCESS_TOKEN\" \\\n  -H \"Content-Type: application/json\" \\\n  -d '{}'"
          },
          {
            "lang": "JavaScript",
            "label": "Node.js",
            "source": "import { KangOpenBanking } from \"@kangopenbanking/sdk\";\n\nconst kob = new KangOpenBanking({ apiKey: process.env.KOB_API_KEY });\nconst res = await kob.request(\"POST\", \"/v1/ledger/journal\", { /* payload */ });\nconsole.log(res);"
          },
          {
            "lang": "Python",
            "label": "Python",
            "source": "from kangopenbanking import KangOpenBanking\n\nkob = KangOpenBanking(api_key=os.environ[\"KOB_API_KEY\"])\nres = kob.request(\"POST\", \"/v1/ledger/journal\", json={})\nprint(res)"
          },
          {
            "lang": "PHP",
            "label": "PHP",
            "source": "<?php\n$kob = new KangOpenBanking\\KangOpenBanking(getenv('KOB_API_KEY'));\n$res = $kob->request('POST', '/v1/ledger/journal', []);\nprint_r($res);"
          }
        ]
      },
      "get": {
        "tags": [
          "Ledger"
        ],
        "summary": "List journal entries",
        "operationId": "journalList",
        "security": [
          {
            "bearerAuth": []
          }
        ],
        "parameters": [
          {
            "name": "limit",
            "in": "query",
            "schema": {
              "type": "integer",
              "default": 25,
              "maximum": 100
            },
            "description": "Items per page"
          },
          {
            "name": "offset",
            "in": "query",
            "schema": {
              "type": "integer",
              "default": 0
            },
            "description": "Items to skip"
          },
          {
            "name": "sort_by",
            "in": "query",
            "schema": {
              "type": "string",
              "default": "created_at"
            },
            "description": "Sort field"
          },
          {
            "name": "sort_order",
            "in": "query",
            "schema": {
              "type": "string",
              "enum": [
                "asc",
                "desc"
              ],
              "default": "desc"
            },
            "description": "Sort direction"
          },
          {
            "name": "reference_type",
            "in": "query",
            "schema": {
              "type": "string"
            }
          },
          {
            "$ref": "#/components/parameters/StartingAfter"
          },
          {
            "$ref": "#/components/parameters/EndingBefore"
          },
          {
            "$ref": "#/components/parameters/RequestId"
          },
          {
            "$ref": "#/components/parameters/Traceparent"
          },
          {
            "$ref": "#/components/parameters/Tracestate"
          },
          {
            "$ref": "#/components/parameters/AcceptLanguage"
          }
        ],
        "responses": {
          "200": {
            "description": "Journal entries",
            "content": {
              "application/json": {
                "schema": {
                  "allOf": [
                    {
                      "$ref": "#/components/schemas/PaginatedResponse"
                    },
                    {
                      "type": "object",
                      "properties": {
                        "data": {
                          "type": "array",
                          "items": {
                            "$ref": "#/components/schemas/JournalEntry"
                          }
                        }
                      }
                    }
                  ]
                },
                "example": {
                  "data": [
                    {
                      "id": "f1d6f4a0-1d4e-4a3a-9e0a-1a2b3c4d5e6f",
                      "entry_date": "2026-01-31",
                      "description": "Loan disbursement - APP-2026-001",
                      "reference_type": "payment",
                      "reference_id": "f1d6f4a0-1d4e-4a3a-9e0a-1a2b3c4d5e6f",
                      "lines": [
                        {
                          "ledger_account_id": "f1d6f4a0-1d4e-4a3a-9e0a-1a2b3c4d5e6f",
                          "debit": 1000000,
                          "credit": 0
                        }
                      ],
                      "created_at": "2026-01-31T12:00:00Z"
                    }
                  ],
                  "pagination": {
                    "page": 1,
                    "limit": 20,
                    "total": 150,
                    "has_next": true,
                    "next_cursor": "eyJpZCI6IjEyMyJ9"
                  },
                  "meta": {
                    "request_id": "550e8400-e29b-41d4-a716-446655440000",
                    "timestamp": "2025-03-27T12:00:00Z",
                    "api_version": "4.3.0"
                  }
                }
              }
            },
            "headers": {
              "x-fapi-interaction-id": {
                "$ref": "#/components/headers/XFapiInteractionIdResponse"
              },
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/XRateLimitLimit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/XRateLimitRemaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/XRateLimitReset"
              },
              "Cache-Control": {
                "$ref": "#/components/headers/CacheControl"
              },
              "ETag": {
                "$ref": "#/components/headers/ETag"
              },
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              },
              "traceparent": {
                "$ref": "#/components/headers/Traceparent"
              },
              "Content-Language": {
                "$ref": "#/components/headers/Content-Language"
              }
            }
          },
          "400": {
            "description": "Bad request",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              },
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                },
                "examples": {
                  "error": {
                    "$ref": "#/components/examples/ErrorBadRequest"
                  }
                }
              }
            },
            "headers": {
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/XRateLimitLimit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/XRateLimitRemaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/XRateLimitReset"
              },
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "403": {
            "$ref": "#/components/responses/Forbidden",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "404": {
            "$ref": "#/components/responses/NotFound",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "409": {
            "$ref": "#/components/responses/Conflict",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "429": {
            "$ref": "#/components/responses/TooManyRequests",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "500": {
            "$ref": "#/components/responses/InternalServerError",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          }
        },
        "x-codeSamples": [
          {
            "lang": "cURL",
            "label": "cURL",
            "source": "curl -X GET \"https://api.kangopenbanking.com/v1/ledger/journal\" \\\n  -H \"Authorization: Bearer $KOB_ACCESS_TOKEN\" \\\n  -H \"Content-Type: application/json\""
          },
          {
            "lang": "JavaScript",
            "label": "Node.js",
            "source": "import { KangOpenBanking } from \"@kangopenbanking/sdk\";\n\nconst kob = new KangOpenBanking({ apiKey: process.env.KOB_API_KEY });\nconst res = await kob.request(\"GET\", \"/v1/ledger/journal\");\nconsole.log(res);"
          },
          {
            "lang": "Python",
            "label": "Python",
            "source": "from kangopenbanking import KangOpenBanking\n\nkob = KangOpenBanking(api_key=os.environ[\"KOB_API_KEY\"])\nres = kob.request(\"GET\", \"/v1/ledger/journal\")\nprint(res)"
          },
          {
            "lang": "PHP",
            "label": "PHP",
            "source": "<?php\n$kob = new KangOpenBanking\\KangOpenBanking(getenv('KOB_API_KEY'));\n$res = $kob->request('GET', '/v1/ledger/journal');\nprint_r($res);"
          }
        ]
      }
    },
    "/v1/mobile-money/charge": {
      "post": {
        "tags": [
          "Mobile Money"
        ],
        "summary": "Charge mobile money",
        "operationId": "mobileMoneyCharge",
        "security": [
          {
            "bearerAuth": []
          }
        ],
        "deprecated": true,
        "parameters": [
          {
            "name": "Idempotency-Key",
            "in": "header",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid"
            },
            "description": "Required on all POST/PUT endpoints. Unique key for idempotent request processing (UUID v4 recommended). Keys expire after 24 hours."
          },
          {
            "$ref": "#/components/parameters/RequestId"
          },
          {
            "$ref": "#/components/parameters/Traceparent"
          },
          {
            "$ref": "#/components/parameters/Tracestate"
          },
          {
            "$ref": "#/components/parameters/AcceptLanguage"
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "required": [
                  "phone_number",
                  "amount"
                ],
                "properties": {
                  "phone_number": {
                    "type": "string",
                    "example": "237650000000"
                  },
                  "amount": {
                    "type": "string",
                    "example": "5000",
                    "pattern": "^[0-9]{1,15}$",
                    "description": "Represented as a string integer in the currency's minor unit (XAF has no subunits). Must be consistent with the currency field."
                  },
                  "currency": {
                    "type": "string",
                    "example": "XAF",
                    "enum": [
                      "XAF",
                      "XOF",
                      "USD",
                      "EUR",
                      "GBP",
                      "CNY",
                      "NGN",
                      "GHS",
                      "KES",
                      "ZAR"
                    ],
                    "default": "XAF",
                    "description": "ISO 4217 currency code. Default is XAF (Central African CFA Franc)."
                  },
                  "provider": {
                    "type": "string",
                    "enum": [
                      "MTN",
                      "Orange"
                    ]
                  }
                }
              },
              "example": {
                "phone_number": "237650000000",
                "amount": 5000,
                "currency": "XAF",
                "provider": "MTN"
              }
            }
          }
        },
        "responses": {
          "410": {
            "description": "Gone — use /v1/gateway/charges?channel=mobile_money",
            "headers": {
              "Sunset": {
                "schema": {
                  "type": "string"
                },
                "description": "RFC 8594 sunset date (2026-01-01)."
              },
              "Link": {
                "schema": {
                  "type": "string"
                },
                "description": "</v1/gateway/charges?channel=mobile_money>; rel=\"successor-version\""
              },
              "Deprecation": {
                "schema": {
                  "type": "string"
                },
                "description": "true"
              },
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/XRateLimitLimit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/XRateLimitRemaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/XRateLimitReset"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                },
                "example": {
                  "type": "https://api.kangopenbanking.com/v1/errors/endpoint-retired",
                  "title": "Endpoint Retired",
                  "status": 410,
                  "detail": "This endpoint was retired on 2026-01-01. Use /v1/gateway/charges?channel=mobile_money.",
                  "error_code": "DEPRECATED_ENDPOINT_RETIRED"
                }
              }
            }
          },
          "422": {
            "description": "Provider declined or upstream validation error (normalized).",
            "content": {
              "application/problem+json": {
                "schema": {
                  "allOf": [
                    {
                      "$ref": "#/components/schemas/ProblemDetails"
                    },
                    {
                      "type": "object",
                      "properties": {
                        "provider_error": {
                          "$ref": "#/components/schemas/MobileMoneyProviderError"
                        }
                      }
                    }
                  ]
                },
                "examples": {
                  "insufficient_funds": {
                    "$ref": "#/components/examples/MobileMoneyInsufficientFunds"
                  }
                }
              }
            },
            "headers": {
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/XRateLimitLimit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/XRateLimitRemaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/XRateLimitReset"
              }
            }
          },
          "429": {
            "description": "Rate limit exceeded. Retry after the interval in `Retry-After`.",
            "headers": {
              "Retry-After": {
                "schema": {
                  "type": "integer"
                },
                "description": "Seconds to wait before retrying."
              },
              "X-RateLimit-Limit": {
                "schema": {
                  "type": "integer"
                }
              },
              "X-RateLimit-Remaining": {
                "schema": {
                  "type": "integer"
                }
              },
              "X-RateLimit-Reset": {
                "schema": {
                  "type": "integer"
                }
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                },
                "examples": {
                  "rateLimited": {
                    "$ref": "#/components/examples/ErrorRateLimited"
                  }
                }
              }
            }
          }
        },
        "description": "**RETIRED on 2026-01-01.** This endpoint returns HTTP 410 Gone. Use `/v1/gateway/charges?channel=mobile_money` instead.\n\nDEPRECATED (sunset: 2026-01-01): Use the unified Payment Gateway at /v1/gateway/charges instead.  Responses will conform to the StandardResponse envelope in a future minor release.\n\n**Migration:** Replace with `gatewayCreateCharge`. Create a charge with `channel=mobile_money`.",
        "x-sunset": "2026-01-01",
        "x-replaced-by": "/v1/gateway/charges (channel: momo)",
        "x-retired": true,
        "x-sunset-date": "2026-01-01",
        "x-successor": "/v1/gateway/charges?channel=mobile_money",
        "x-replacement-endpoint": "/v1/gateway/charges?channel=mobile_money",
        "x-codeSamples": [
          {
            "lang": "cURL",
            "label": "cURL",
            "source": "curl -X POST \"https://api.kangopenbanking.com/v1/mobile-money/charge\" \\\n  -H \"Authorization: Bearer $KOB_ACCESS_TOKEN\" \\\n  -H \"Content-Type: application/json\" \\\n  -d '{}'"
          },
          {
            "lang": "JavaScript",
            "label": "Node.js",
            "source": "import { KangOpenBanking } from \"@kangopenbanking/sdk\";\n\nconst kob = new KangOpenBanking({ apiKey: process.env.KOB_API_KEY });\nconst res = await kob.request(\"POST\", \"/v1/mobile-money/charge\", { /* payload */ });\nconsole.log(res);"
          },
          {
            "lang": "Python",
            "label": "Python",
            "source": "from kangopenbanking import KangOpenBanking\n\nkob = KangOpenBanking(api_key=os.environ[\"KOB_API_KEY\"])\nres = kob.request(\"POST\", \"/v1/mobile-money/charge\", json={})\nprint(res)"
          },
          {
            "lang": "PHP",
            "label": "PHP",
            "source": "<?php\n$kob = new KangOpenBanking\\KangOpenBanking(getenv('KOB_API_KEY'));\n$res = $kob->request('POST', '/v1/mobile-money/charge', []);\nprint_r($res);"
          }
        ],
        "x-replacement-operation-ids": [
          "gatewayCreateCharge"
        ],
        "x-migration-guide": "Create a charge with `channel=mobile_money`."
      }
    },
    "/v1/mobile-money/transfer": {
      "post": {
        "tags": [
          "Mobile Money"
        ],
        "summary": "Transfer to mobile money",
        "operationId": "mobileMoneyTransfer",
        "security": [
          {
            "bearerAuth": []
          }
        ],
        "deprecated": true,
        "parameters": [
          {
            "name": "Idempotency-Key",
            "in": "header",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid"
            },
            "description": "Required on all POST/PUT endpoints. Unique key for idempotent request processing (UUID v4 recommended). Keys expire after 24 hours."
          },
          {
            "$ref": "#/components/parameters/RequestId"
          },
          {
            "$ref": "#/components/parameters/Traceparent"
          },
          {
            "$ref": "#/components/parameters/Tracestate"
          },
          {
            "$ref": "#/components/parameters/AcceptLanguage"
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "required": [
                  "phone_number",
                  "amount"
                ],
                "properties": {
                  "phone_number": {
                    "type": "string"
                  },
                  "amount": {
                    "type": "string",
                    "example": "10000",
                    "pattern": "^[0-9]{1,15}$",
                    "description": "Represented as a string integer in the currency's minor unit (XAF has no subunits). Must be consistent with the currency field."
                  },
                  "currency": {
                    "type": "string",
                    "example": "XAF",
                    "enum": [
                      "XAF",
                      "XOF",
                      "USD",
                      "EUR",
                      "GBP",
                      "CNY",
                      "NGN",
                      "GHS",
                      "KES",
                      "ZAR"
                    ],
                    "default": "XAF",
                    "description": "ISO 4217 currency code. Default is XAF (Central African CFA Franc)."
                  }
                }
              }
            }
          }
        },
        "responses": {
          "410": {
            "description": "Gone — use /v1/gateway/payouts?channel=mobile_money",
            "headers": {
              "Sunset": {
                "schema": {
                  "type": "string"
                },
                "description": "RFC 8594 sunset date (2026-01-01)."
              },
              "Link": {
                "schema": {
                  "type": "string"
                },
                "description": "</v1/gateway/payouts?channel=mobile_money>; rel=\"successor-version\""
              },
              "Deprecation": {
                "schema": {
                  "type": "string"
                },
                "description": "true"
              },
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/XRateLimitLimit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/XRateLimitRemaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/XRateLimitReset"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                },
                "example": {
                  "type": "https://api.kangopenbanking.com/v1/errors/endpoint-retired",
                  "title": "Endpoint Retired",
                  "status": 410,
                  "detail": "This endpoint was retired on 2026-01-01. Use /v1/gateway/payouts?channel=mobile_money.",
                  "error_code": "DEPRECATED_ENDPOINT_RETIRED"
                }
              }
            }
          },
          "422": {
            "description": "Provider declined or upstream validation error (normalized).",
            "content": {
              "application/problem+json": {
                "schema": {
                  "allOf": [
                    {
                      "$ref": "#/components/schemas/ProblemDetails"
                    },
                    {
                      "type": "object",
                      "properties": {
                        "provider_error": {
                          "$ref": "#/components/schemas/MobileMoneyProviderError"
                        }
                      }
                    }
                  ]
                },
                "examples": {
                  "insufficient_funds": {
                    "$ref": "#/components/examples/MobileMoneyInsufficientFunds"
                  }
                }
              }
            },
            "headers": {
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/XRateLimitLimit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/XRateLimitRemaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/XRateLimitReset"
              }
            }
          },
          "429": {
            "description": "Rate limit exceeded. Retry after the interval in `Retry-After`.",
            "headers": {
              "Retry-After": {
                "schema": {
                  "type": "integer"
                },
                "description": "Seconds to wait before retrying."
              },
              "X-RateLimit-Limit": {
                "schema": {
                  "type": "integer"
                }
              },
              "X-RateLimit-Remaining": {
                "schema": {
                  "type": "integer"
                }
              },
              "X-RateLimit-Reset": {
                "schema": {
                  "type": "integer"
                }
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                },
                "examples": {
                  "rateLimited": {
                    "$ref": "#/components/examples/ErrorRateLimited"
                  }
                }
              }
            }
          }
        },
        "x-sunset": "2026-01-01",
        "x-replaced-by": "/v1/gateway/charges (channel: momo)",
        "description": "**RETIRED on 2026-01-01.** This endpoint returns HTTP 410 Gone. Use `/v1/gateway/payouts?channel=mobile_money` instead.\n\nDEPRECATED (sunset: 2026-01-01): Use the unified Payment Gateway at /v1/gateway/charges instead. \n\n**Migration:** Replace with `gatewayCreatePayout`. Create a payout with `channel=mobile_money`.",
        "x-retired": true,
        "x-sunset-date": "2026-01-01",
        "x-successor": "/v1/gateway/payouts?channel=mobile_money",
        "x-replacement-endpoint": "/v1/gateway/payouts?channel=mobile_money",
        "x-codeSamples": [
          {
            "lang": "cURL",
            "label": "cURL",
            "source": "curl -X POST \"https://api.kangopenbanking.com/v1/mobile-money/transfer\" \\\n  -H \"Authorization: Bearer $KOB_ACCESS_TOKEN\" \\\n  -H \"Content-Type: application/json\" \\\n  -d '{}'"
          },
          {
            "lang": "JavaScript",
            "label": "Node.js",
            "source": "import { KangOpenBanking } from \"@kangopenbanking/sdk\";\n\nconst kob = new KangOpenBanking({ apiKey: process.env.KOB_API_KEY });\nconst res = await kob.request(\"POST\", \"/v1/mobile-money/transfer\", { /* payload */ });\nconsole.log(res);"
          },
          {
            "lang": "Python",
            "label": "Python",
            "source": "from kangopenbanking import KangOpenBanking\n\nkob = KangOpenBanking(api_key=os.environ[\"KOB_API_KEY\"])\nres = kob.request(\"POST\", \"/v1/mobile-money/transfer\", json={})\nprint(res)"
          },
          {
            "lang": "PHP",
            "label": "PHP",
            "source": "<?php\n$kob = new KangOpenBanking\\KangOpenBanking(getenv('KOB_API_KEY'));\n$res = $kob->request('POST', '/v1/mobile-money/transfer', []);\nprint_r($res);"
          }
        ],
        "x-replacement-operation-ids": [
          "gatewayCreatePayout"
        ],
        "x-migration-guide": "Create a payout with `channel=mobile_money`."
      }
    },
    "/v1/mobile-money/verify": {
      "post": {
        "tags": [
          "Mobile Money"
        ],
        "summary": "Verify mobile money transaction",
        "operationId": "mobileMoneyVerify",
        "security": [
          {
            "bearerAuth": []
          }
        ],
        "deprecated": true,
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "required": [
                  "transaction_ref"
                ],
                "properties": {
                  "transaction_ref": {
                    "type": "string"
                  }
                }
              }
            }
          }
        },
        "responses": {
          "410": {
            "description": "Gone — use /v1/gateway/charges/{chargeId}",
            "headers": {
              "Sunset": {
                "schema": {
                  "type": "string"
                },
                "description": "RFC 8594 sunset date (2026-01-01)."
              },
              "Link": {
                "schema": {
                  "type": "string"
                },
                "description": "</v1/gateway/charges/{chargeId}>; rel=\"successor-version\""
              },
              "Deprecation": {
                "schema": {
                  "type": "string"
                },
                "description": "true"
              },
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/XRateLimitLimit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/XRateLimitRemaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/XRateLimitReset"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                },
                "example": {
                  "type": "https://api.kangopenbanking.com/v1/errors/endpoint-retired",
                  "title": "Endpoint Retired",
                  "status": 410,
                  "detail": "This endpoint was retired on 2026-01-01. Use /v1/gateway/charges/{chargeId}.",
                  "error_code": "DEPRECATED_ENDPOINT_RETIRED"
                }
              }
            }
          },
          "422": {
            "description": "Provider declined or upstream validation error (normalized).",
            "content": {
              "application/problem+json": {
                "schema": {
                  "allOf": [
                    {
                      "$ref": "#/components/schemas/ProblemDetails"
                    },
                    {
                      "type": "object",
                      "properties": {
                        "provider_error": {
                          "$ref": "#/components/schemas/MobileMoneyProviderError"
                        }
                      }
                    }
                  ]
                },
                "examples": {
                  "insufficient_funds": {
                    "$ref": "#/components/examples/MobileMoneyInsufficientFunds"
                  }
                }
              }
            },
            "headers": {
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/XRateLimitLimit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/XRateLimitRemaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/XRateLimitReset"
              }
            }
          },
          "429": {
            "description": "Rate limit exceeded. Retry after the interval in `Retry-After`.",
            "headers": {
              "Retry-After": {
                "schema": {
                  "type": "integer"
                },
                "description": "Seconds to wait before retrying."
              },
              "X-RateLimit-Limit": {
                "schema": {
                  "type": "integer"
                }
              },
              "X-RateLimit-Remaining": {
                "schema": {
                  "type": "integer"
                }
              },
              "X-RateLimit-Reset": {
                "schema": {
                  "type": "integer"
                }
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                },
                "examples": {
                  "rateLimited": {
                    "$ref": "#/components/examples/ErrorRateLimited"
                  }
                }
              }
            }
          }
        },
        "parameters": [
          {
            "name": "Idempotency-Key",
            "in": "header",
            "required": false,
            "description": "Client-generated UUID for idempotent request deduplication. If the same key is submitted twice, the server returns the original response without re-processing.",
            "schema": {
              "type": "string",
              "format": "uuid",
              "example": "b4a2f391-9a41-4d8b-a123-3c6f0e8b9d12"
            }
          },
          {
            "$ref": "#/components/parameters/RequestId"
          },
          {
            "$ref": "#/components/parameters/Traceparent"
          },
          {
            "$ref": "#/components/parameters/Tracestate"
          },
          {
            "$ref": "#/components/parameters/AcceptLanguage"
          }
        ],
        "x-sunset": "2026-01-01",
        "x-replaced-by": "/v1/gateway/charges (channel: momo)",
        "description": "**RETIRED on 2026-01-01.** This endpoint returns HTTP 410 Gone. Use `/v1/gateway/charges/{chargeId}` instead.\n\nDEPRECATED (sunset: 2026-01-01): Use the unified Payment Gateway at /v1/gateway/charges instead. \n\n**Migration:** Replace with `gatewayGetCharge`. Retrieve the charge status by `chargeId`.",
        "x-retired": true,
        "x-sunset-date": "2026-01-01",
        "x-successor": "/v1/gateway/charges/{chargeId}",
        "x-replacement-endpoint": "/v1/gateway/charges/{chargeId}",
        "x-codeSamples": [
          {
            "lang": "cURL",
            "label": "cURL",
            "source": "curl -X POST \"https://api.kangopenbanking.com/v1/mobile-money/verify\" \\\n  -H \"Authorization: Bearer $KOB_ACCESS_TOKEN\" \\\n  -H \"Content-Type: application/json\" \\\n  -d '{}'"
          },
          {
            "lang": "JavaScript",
            "label": "Node.js",
            "source": "import { KangOpenBanking } from \"@kangopenbanking/sdk\";\n\nconst kob = new KangOpenBanking({ apiKey: process.env.KOB_API_KEY });\nconst res = await kob.request(\"POST\", \"/v1/mobile-money/verify\", { /* payload */ });\nconsole.log(res);"
          },
          {
            "lang": "Python",
            "label": "Python",
            "source": "from kangopenbanking import KangOpenBanking\n\nkob = KangOpenBanking(api_key=os.environ[\"KOB_API_KEY\"])\nres = kob.request(\"POST\", \"/v1/mobile-money/verify\", json={})\nprint(res)"
          },
          {
            "lang": "PHP",
            "label": "PHP",
            "source": "<?php\n$kob = new KangOpenBanking\\KangOpenBanking(getenv('KOB_API_KEY'));\n$res = $kob->request('POST', '/v1/mobile-money/verify', []);\nprint_r($res);"
          }
        ],
        "x-replacement-operation-ids": [
          "gatewayGetCharge"
        ],
        "x-migration-guide": "Retrieve the charge status by `chargeId`."
      }
    },
    "/v1/mobile-money/to-bank": {
      "post": {
        "tags": [
          "Mobile Money"
        ],
        "summary": "Mobile money to bank transfer",
        "operationId": "mobileMoneyToBank",
        "security": [
          {
            "bearerAuth": []
          }
        ],
        "deprecated": true,
        "parameters": [
          {
            "name": "Idempotency-Key",
            "in": "header",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid"
            },
            "description": "Required on all POST/PUT endpoints. Unique key for idempotent request processing (UUID v4 recommended). Keys expire after 24 hours."
          },
          {
            "$ref": "#/components/parameters/RequestId"
          },
          {
            "$ref": "#/components/parameters/Traceparent"
          },
          {
            "$ref": "#/components/parameters/Tracestate"
          },
          {
            "$ref": "#/components/parameters/AcceptLanguage"
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "required": [
                  "phone_number",
                  "amount",
                  "bank_account"
                ],
                "properties": {
                  "phone_number": {
                    "type": "string"
                  },
                  "amount": {
                    "type": "string",
                    "pattern": "^[0-9]{1,15}$",
                    "description": "Represented as a string integer in the currency's minor unit (XAF has no subunits)."
                  },
                  "bank_account": {
                    "type": "string"
                  },
                  "bank_code": {
                    "type": "string"
                  }
                }
              }
            }
          }
        },
        "responses": {
          "410": {
            "description": "Gone — use /v1/gateway/payouts?channel=bank_transfer",
            "headers": {
              "Sunset": {
                "schema": {
                  "type": "string"
                },
                "description": "RFC 8594 sunset date (2026-01-01)."
              },
              "Link": {
                "schema": {
                  "type": "string"
                },
                "description": "</v1/gateway/payouts?channel=bank_transfer>; rel=\"successor-version\""
              },
              "Deprecation": {
                "schema": {
                  "type": "string"
                },
                "description": "true"
              },
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/XRateLimitLimit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/XRateLimitRemaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/XRateLimitReset"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                },
                "example": {
                  "type": "https://api.kangopenbanking.com/v1/errors/endpoint-retired",
                  "title": "Endpoint Retired",
                  "status": 410,
                  "detail": "This endpoint was retired on 2026-01-01. Use /v1/gateway/payouts?channel=bank_transfer.",
                  "error_code": "DEPRECATED_ENDPOINT_RETIRED"
                }
              }
            }
          },
          "422": {
            "description": "Provider declined or upstream validation error (normalized).",
            "content": {
              "application/problem+json": {
                "schema": {
                  "allOf": [
                    {
                      "$ref": "#/components/schemas/ProblemDetails"
                    },
                    {
                      "type": "object",
                      "properties": {
                        "provider_error": {
                          "$ref": "#/components/schemas/MobileMoneyProviderError"
                        }
                      }
                    }
                  ]
                },
                "examples": {
                  "insufficient_funds": {
                    "$ref": "#/components/examples/MobileMoneyInsufficientFunds"
                  }
                }
              }
            },
            "headers": {
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/XRateLimitLimit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/XRateLimitRemaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/XRateLimitReset"
              }
            }
          },
          "429": {
            "description": "Rate limit exceeded. Retry after the interval in `Retry-After`.",
            "headers": {
              "Retry-After": {
                "schema": {
                  "type": "integer"
                },
                "description": "Seconds to wait before retrying."
              },
              "X-RateLimit-Limit": {
                "schema": {
                  "type": "integer"
                }
              },
              "X-RateLimit-Remaining": {
                "schema": {
                  "type": "integer"
                }
              },
              "X-RateLimit-Reset": {
                "schema": {
                  "type": "integer"
                }
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                },
                "examples": {
                  "rateLimited": {
                    "$ref": "#/components/examples/ErrorRateLimited"
                  }
                }
              }
            }
          }
        },
        "x-sunset": "2026-01-01",
        "x-replaced-by": "/v1/gateway/charges (channel: momo)",
        "description": "**RETIRED on 2026-01-01.** This endpoint returns HTTP 410 Gone. Use `/v1/gateway/payouts?channel=bank_transfer` instead.\n\nDEPRECATED (sunset: 2026-01-01): Use the unified Payment Gateway at /v1/gateway/charges instead. \n\n**Migration:** Replace with `gatewayCreatePayout`. Create a payout with `channel=bank_transfer`.",
        "x-retired": true,
        "x-sunset-date": "2026-01-01",
        "x-successor": "/v1/gateway/payouts?channel=bank_transfer",
        "x-replacement-endpoint": "/v1/gateway/payouts?channel=bank_transfer",
        "x-codeSamples": [
          {
            "lang": "cURL",
            "label": "cURL",
            "source": "curl -X POST \"https://api.kangopenbanking.com/v1/mobile-money/to-bank\" \\\n  -H \"Authorization: Bearer $KOB_ACCESS_TOKEN\" \\\n  -H \"Content-Type: application/json\" \\\n  -d '{}'"
          },
          {
            "lang": "JavaScript",
            "label": "Node.js",
            "source": "import { KangOpenBanking } from \"@kangopenbanking/sdk\";\n\nconst kob = new KangOpenBanking({ apiKey: process.env.KOB_API_KEY });\nconst res = await kob.request(\"POST\", \"/v1/mobile-money/to-bank\", { /* payload */ });\nconsole.log(res);"
          },
          {
            "lang": "Python",
            "label": "Python",
            "source": "from kangopenbanking import KangOpenBanking\n\nkob = KangOpenBanking(api_key=os.environ[\"KOB_API_KEY\"])\nres = kob.request(\"POST\", \"/v1/mobile-money/to-bank\", json={})\nprint(res)"
          },
          {
            "lang": "PHP",
            "label": "PHP",
            "source": "<?php\n$kob = new KangOpenBanking\\KangOpenBanking(getenv('KOB_API_KEY'));\n$res = $kob->request('POST', '/v1/mobile-money/to-bank', []);\nprint_r($res);"
          }
        ],
        "x-replacement-operation-ids": [
          "gatewayCreatePayout"
        ],
        "x-migration-guide": "Create a payout with `channel=bank_transfer`."
      }
    },
    "/v1/flutterwave/bank-transfer": {
      "post": {
        "tags": [
          "Payments"
        ],
        "summary": "Initiate bank transfer via Flutterwave",
        "operationId": "flutterwaveBankTransfer",
        "security": [
          {
            "bearerAuth": []
          }
        ],
        "deprecated": true,
        "parameters": [
          {
            "name": "Idempotency-Key",
            "in": "header",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid"
            },
            "description": "Required on all POST/PUT endpoints. Unique key for idempotent request processing (UUID v4 recommended). Keys expire after 24 hours."
          },
          {
            "$ref": "#/components/parameters/RequestId"
          },
          {
            "$ref": "#/components/parameters/Traceparent"
          },
          {
            "$ref": "#/components/parameters/Tracestate"
          },
          {
            "$ref": "#/components/parameters/AcceptLanguage"
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "required": [
                  "account_number",
                  "bank_code",
                  "amount"
                ],
                "properties": {
                  "account_number": {
                    "type": "string"
                  },
                  "bank_code": {
                    "type": "string"
                  },
                  "amount": {
                    "type": "string",
                    "example": "100000",
                    "pattern": "^[0-9]{1,15}$",
                    "description": "Represented as a string integer in the currency's minor unit (XAF has no subunits). Must be consistent with the currency field."
                  },
                  "currency": {
                    "type": "string",
                    "example": "XAF",
                    "enum": [
                      "XAF",
                      "XOF",
                      "USD",
                      "EUR",
                      "GBP",
                      "CNY",
                      "NGN",
                      "GHS",
                      "KES",
                      "ZAR"
                    ],
                    "default": "XAF",
                    "description": "ISO 4217 currency code. Default is XAF (Central African CFA Franc)."
                  },
                  "narration": {
                    "type": "string"
                  }
                }
              }
            }
          }
        },
        "responses": {
          "410": {
            "description": "Gone — use /v1/gateway/payouts?provider=flutterwave",
            "headers": {
              "Sunset": {
                "schema": {
                  "type": "string"
                },
                "description": "RFC 8594 sunset date (2026-01-01)."
              },
              "Link": {
                "schema": {
                  "type": "string"
                },
                "description": "</v1/gateway/payouts?provider=flutterwave>; rel=\"successor-version\""
              },
              "Deprecation": {
                "schema": {
                  "type": "string"
                },
                "description": "true"
              },
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/XRateLimitLimit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/XRateLimitRemaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/XRateLimitReset"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                },
                "example": {
                  "type": "https://api.kangopenbanking.com/v1/errors/endpoint-retired",
                  "title": "Endpoint Retired",
                  "status": 410,
                  "detail": "This endpoint was retired on 2026-01-01. Use /v1/gateway/payouts?provider=flutterwave.",
                  "error_code": "DEPRECATED_ENDPOINT_RETIRED"
                }
              }
            }
          },
          "429": {
            "description": "Rate limit exceeded. Retry after the interval in `Retry-After`.",
            "headers": {
              "Retry-After": {
                "schema": {
                  "type": "integer"
                },
                "description": "Seconds to wait before retrying."
              },
              "X-RateLimit-Limit": {
                "schema": {
                  "type": "integer"
                }
              },
              "X-RateLimit-Remaining": {
                "schema": {
                  "type": "integer"
                }
              },
              "X-RateLimit-Reset": {
                "schema": {
                  "type": "integer"
                }
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                },
                "examples": {
                  "rateLimited": {
                    "$ref": "#/components/examples/ErrorRateLimited"
                  }
                }
              }
            }
          }
        },
        "x-sunset": "2026-01-01",
        "x-replaced-by": "/v1/gateway/charges (channel: flutterwave)",
        "description": "**RETIRED on 2026-01-01.** This endpoint returns HTTP 410 Gone. Use `/v1/gateway/payouts?provider=flutterwave` instead.\n\nDEPRECATED (sunset: 2026-01-01): Use the unified Payment Gateway at /v1/gateway/charges instead. \n\n**Migration:** Replace with `gatewayCreatePayout`. Create a payout; provider routing is selected server-side.",
        "x-retired": true,
        "x-sunset-date": "2026-01-01",
        "x-successor": "/v1/gateway/payouts?provider=flutterwave",
        "x-replacement-endpoint": "/v1/gateway/payouts?provider=flutterwave",
        "x-codeSamples": [
          {
            "lang": "cURL",
            "label": "cURL",
            "source": "curl -X POST \"https://api.kangopenbanking.com/v1/flutterwave/bank-transfer\" \\\n  -H \"Authorization: Bearer $KOB_ACCESS_TOKEN\" \\\n  -H \"Content-Type: application/json\" \\\n  -d '{}'"
          },
          {
            "lang": "JavaScript",
            "label": "Node.js",
            "source": "import { KangOpenBanking } from \"@kangopenbanking/sdk\";\n\nconst kob = new KangOpenBanking({ apiKey: process.env.KOB_API_KEY });\nconst res = await kob.request(\"POST\", \"/v1/flutterwave/bank-transfer\", { /* payload */ });\nconsole.log(res);"
          },
          {
            "lang": "Python",
            "label": "Python",
            "source": "from kangopenbanking import KangOpenBanking\n\nkob = KangOpenBanking(api_key=os.environ[\"KOB_API_KEY\"])\nres = kob.request(\"POST\", \"/v1/flutterwave/bank-transfer\", json={})\nprint(res)"
          },
          {
            "lang": "PHP",
            "label": "PHP",
            "source": "<?php\n$kob = new KangOpenBanking\\KangOpenBanking(getenv('KOB_API_KEY'));\n$res = $kob->request('POST', '/v1/flutterwave/bank-transfer', []);\nprint_r($res);"
          }
        ],
        "x-replacement-operation-ids": [
          "gatewayCreatePayout"
        ],
        "x-migration-guide": "Create a payout; provider routing is selected server-side."
      }
    },
    "/v1/flutterwave/banks": {
      "get": {
        "tags": [
          "Payments"
        ],
        "summary": "List supported banks",
        "operationId": "flutterwaveListBanks",
        "security": [
          {
            "bearerAuth": []
          }
        ],
        "deprecated": true,
        "parameters": [
          {
            "name": "country",
            "in": "query",
            "schema": {
              "type": "string",
              "default": "CM"
            }
          },
          {
            "$ref": "#/components/parameters/PageParam"
          },
          {
            "$ref": "#/components/parameters/LimitParam"
          },
          {
            "$ref": "#/components/parameters/CursorParam"
          },
          {
            "$ref": "#/components/parameters/RequestId"
          },
          {
            "$ref": "#/components/parameters/Traceparent"
          },
          {
            "$ref": "#/components/parameters/Tracestate"
          },
          {
            "$ref": "#/components/parameters/AcceptLanguage"
          }
        ],
        "responses": {
          "410": {
            "description": "Gone — use /v1/banks/directory",
            "headers": {
              "Sunset": {
                "schema": {
                  "type": "string"
                },
                "description": "RFC 8594 sunset date (2026-01-01)."
              },
              "Link": {
                "schema": {
                  "type": "string"
                },
                "description": "</v1/banks/directory>; rel=\"successor-version\""
              },
              "Deprecation": {
                "schema": {
                  "type": "string"
                },
                "description": "true"
              },
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/XRateLimitLimit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/XRateLimitRemaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/XRateLimitReset"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                },
                "example": {
                  "type": "https://api.kangopenbanking.com/v1/errors/endpoint-retired",
                  "title": "Endpoint Retired",
                  "status": 410,
                  "detail": "This endpoint was retired on 2026-01-01. Use /v1/banks/directory.",
                  "error_code": "DEPRECATED_ENDPOINT_RETIRED"
                }
              }
            }
          },
          "429": {
            "description": "Rate limit exceeded. Retry after the interval in `Retry-After`.",
            "headers": {
              "Retry-After": {
                "schema": {
                  "type": "integer"
                },
                "description": "Seconds to wait before retrying."
              },
              "X-RateLimit-Limit": {
                "schema": {
                  "type": "integer"
                }
              },
              "X-RateLimit-Remaining": {
                "schema": {
                  "type": "integer"
                }
              },
              "X-RateLimit-Reset": {
                "schema": {
                  "type": "integer"
                }
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                },
                "examples": {
                  "rateLimited": {
                    "$ref": "#/components/examples/ErrorRateLimited"
                  }
                }
              }
            }
          }
        },
        "x-sunset": "2026-01-01",
        "x-replaced-by": "/v1/gateway/charges (channel: flutterwave)",
        "description": "**RETIRED on 2026-01-01.** This endpoint returns HTTP 410 Gone. Use `GET /v1/directory/banks` (`directoryBanksList`) instead.\n\nDEPRECATED (sunset: 2026-01-01): Use the unified Payment Gateway at /v1/gateway/charges instead. \n\n**Migration:** Replace with `directoryBanksList`. List banks from the KOB bank directory.",
        "x-retired": true,
        "x-sunset-date": "2026-01-01",
        "x-successor": "/v1/banks/directory",
        "x-replacement-endpoint": "/v1/banks/directory",
        "x-codeSamples": [
          {
            "lang": "cURL",
            "label": "cURL",
            "source": "curl -X GET \"https://api.kangopenbanking.com/v1/flutterwave/banks\" \\\n  -H \"Authorization: Bearer $KOB_ACCESS_TOKEN\" \\\n  -H \"Content-Type: application/json\""
          },
          {
            "lang": "JavaScript",
            "label": "Node.js",
            "source": "import { KangOpenBanking } from \"@kangopenbanking/sdk\";\n\nconst kob = new KangOpenBanking({ apiKey: process.env.KOB_API_KEY });\nconst res = await kob.request(\"GET\", \"/v1/flutterwave/banks\");\nconsole.log(res);"
          },
          {
            "lang": "Python",
            "label": "Python",
            "source": "from kangopenbanking import KangOpenBanking\n\nkob = KangOpenBanking(api_key=os.environ[\"KOB_API_KEY\"])\nres = kob.request(\"GET\", \"/v1/flutterwave/banks\")\nprint(res)"
          },
          {
            "lang": "PHP",
            "label": "PHP",
            "source": "<?php\n$kob = new KangOpenBanking\\KangOpenBanking(getenv('KOB_API_KEY'));\n$res = $kob->request('GET', '/v1/flutterwave/banks');\nprint_r($res);"
          }
        ],
        "x-replacement-operation-ids": [
          "directoryBanksList"
        ],
        "x-migration-guide": "List banks from the KOB bank directory."
      }
    },
    "/v1/flutterwave/verify-bank": {
      "post": {
        "tags": [
          "Payments"
        ],
        "summary": "Verify bank account",
        "operationId": "flutterwaveVerifyBank",
        "security": [
          {
            "bearerAuth": []
          }
        ],
        "deprecated": true,
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "required": [
                  "account_number",
                  "bank_code"
                ],
                "properties": {
                  "account_number": {
                    "type": "string"
                  },
                  "bank_code": {
                    "type": "string"
                  }
                }
              }
            }
          }
        },
        "responses": {
          "410": {
            "description": "Gone — use /v1/banks/verify-account",
            "headers": {
              "Sunset": {
                "schema": {
                  "type": "string"
                },
                "description": "RFC 8594 sunset date (2026-01-01)."
              },
              "Link": {
                "schema": {
                  "type": "string"
                },
                "description": "</v1/banks/verify-account>; rel=\"successor-version\""
              },
              "Deprecation": {
                "schema": {
                  "type": "string"
                },
                "description": "true"
              },
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/XRateLimitLimit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/XRateLimitRemaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/XRateLimitReset"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                },
                "example": {
                  "type": "https://api.kangopenbanking.com/v1/errors/endpoint-retired",
                  "title": "Endpoint Retired",
                  "status": 410,
                  "detail": "This endpoint was retired on 2026-01-01. Use /v1/banks/verify-account.",
                  "error_code": "DEPRECATED_ENDPOINT_RETIRED"
                }
              }
            }
          },
          "429": {
            "description": "Rate limit exceeded. Retry after the interval in `Retry-After`.",
            "headers": {
              "Retry-After": {
                "schema": {
                  "type": "integer"
                },
                "description": "Seconds to wait before retrying."
              },
              "X-RateLimit-Limit": {
                "schema": {
                  "type": "integer"
                }
              },
              "X-RateLimit-Remaining": {
                "schema": {
                  "type": "integer"
                }
              },
              "X-RateLimit-Reset": {
                "schema": {
                  "type": "integer"
                }
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                },
                "examples": {
                  "rateLimited": {
                    "$ref": "#/components/examples/ErrorRateLimited"
                  }
                }
              }
            }
          }
        },
        "x-sunset": "2026-01-01",
        "x-replaced-by": "/v1/gateway/charges (channel: flutterwave)",
        "description": "**RETIRED on 2026-01-01.** This endpoint returns HTTP 410 Gone. No direct replacement exists; see Migration below.\n\nDEPRECATED (sunset: 2026-01-01): Use the unified Payment Gateway at /v1/gateway/charges instead. \n\n**Migration:** No direct replacement. Validate destination details when creating a payout with `gatewayCreatePayout`; validation failures are returned as Problem Details.",
        "x-retired": true,
        "x-sunset-date": "2026-01-01",
        "x-successor": "/v1/banks/verify-account",
        "x-replacement-endpoint": "/v1/banks/verify-account",
        "parameters": [
          {
            "$ref": "#/components/parameters/RequestId"
          },
          {
            "$ref": "#/components/parameters/Traceparent"
          },
          {
            "$ref": "#/components/parameters/Tracestate"
          },
          {
            "$ref": "#/components/parameters/AcceptLanguage"
          }
        ],
        "x-codeSamples": [
          {
            "lang": "cURL",
            "label": "cURL",
            "source": "curl -X POST \"https://api.kangopenbanking.com/v1/flutterwave/verify-bank\" \\\n  -H \"Authorization: Bearer $KOB_ACCESS_TOKEN\" \\\n  -H \"Content-Type: application/json\" \\\n  -d '{}'"
          },
          {
            "lang": "JavaScript",
            "label": "Node.js",
            "source": "import { KangOpenBanking } from \"@kangopenbanking/sdk\";\n\nconst kob = new KangOpenBanking({ apiKey: process.env.KOB_API_KEY });\nconst res = await kob.request(\"POST\", \"/v1/flutterwave/verify-bank\", { /* payload */ });\nconsole.log(res);"
          },
          {
            "lang": "Python",
            "label": "Python",
            "source": "from kangopenbanking import KangOpenBanking\n\nkob = KangOpenBanking(api_key=os.environ[\"KOB_API_KEY\"])\nres = kob.request(\"POST\", \"/v1/flutterwave/verify-bank\", json={})\nprint(res)"
          },
          {
            "lang": "PHP",
            "label": "PHP",
            "source": "<?php\n$kob = new KangOpenBanking\\KangOpenBanking(getenv('KOB_API_KEY'));\n$res = $kob->request('POST', '/v1/flutterwave/verify-bank', []);\nprint_r($res);"
          }
        ],
        "x-replacement-operation-ids": [],
        "x-migration-guide": "No direct replacement. Validate destination details when creating a payout with `gatewayCreatePayout`; validation failures are returned as Problem Details."
      }
    },
    "/v1/stripe/payment-intent": {
      "post": {
        "tags": [
          "Payments"
        ],
        "summary": "Create Stripe payment intent",
        "operationId": "stripePaymentIntent",
        "security": [
          {
            "bearerAuth": []
          }
        ],
        "deprecated": true,
        "parameters": [
          {
            "name": "Idempotency-Key",
            "in": "header",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid"
            },
            "description": "Required on all POST/PUT endpoints. Unique key for idempotent request processing (UUID v4 recommended). Keys expire after 24 hours."
          },
          {
            "$ref": "#/components/parameters/RequestId"
          },
          {
            "$ref": "#/components/parameters/Traceparent"
          },
          {
            "$ref": "#/components/parameters/Tracestate"
          },
          {
            "$ref": "#/components/parameters/AcceptLanguage"
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "required": [
                  "amount",
                  "currency"
                ],
                "properties": {
                  "amount": {
                    "type": "string",
                    "pattern": "^[0-9]{1,15}$",
                    "description": "Represented as a string integer in the currency's minor unit (XAF has no subunits). Must be consistent with the currency field."
                  },
                  "currency": {
                    "type": "string",
                    "example": "XAF",
                    "enum": [
                      "XAF",
                      "XOF",
                      "USD",
                      "EUR",
                      "GBP",
                      "CNY",
                      "NGN",
                      "GHS",
                      "KES",
                      "ZAR"
                    ],
                    "default": "XAF",
                    "description": "ISO 4217 currency code. Default is XAF (Central African CFA Franc)."
                  }
                }
              }
            }
          }
        },
        "responses": {
          "410": {
            "description": "Gone — use /v1/gateway/charges?provider=stripe",
            "headers": {
              "Sunset": {
                "schema": {
                  "type": "string"
                },
                "description": "RFC 8594 sunset date (2026-01-01)."
              },
              "Link": {
                "schema": {
                  "type": "string"
                },
                "description": "</v1/gateway/charges?provider=stripe>; rel=\"successor-version\""
              },
              "Deprecation": {
                "schema": {
                  "type": "string"
                },
                "description": "true"
              },
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/XRateLimitLimit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/XRateLimitRemaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/XRateLimitReset"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                },
                "example": {
                  "type": "https://api.kangopenbanking.com/v1/errors/endpoint-retired",
                  "title": "Endpoint Retired",
                  "status": 410,
                  "detail": "This endpoint was retired on 2026-01-01. Use /v1/gateway/charges?provider=stripe.",
                  "error_code": "DEPRECATED_ENDPOINT_RETIRED"
                }
              }
            }
          },
          "429": {
            "description": "Rate limit exceeded. Retry after the interval in `Retry-After`.",
            "headers": {
              "Retry-After": {
                "schema": {
                  "type": "integer"
                },
                "description": "Seconds to wait before retrying."
              },
              "X-RateLimit-Limit": {
                "schema": {
                  "type": "integer"
                }
              },
              "X-RateLimit-Remaining": {
                "schema": {
                  "type": "integer"
                }
              },
              "X-RateLimit-Reset": {
                "schema": {
                  "type": "integer"
                }
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                },
                "examples": {
                  "rateLimited": {
                    "$ref": "#/components/examples/ErrorRateLimited"
                  }
                }
              }
            }
          }
        },
        "x-sunset": "2026-01-01",
        "x-replaced-by": "/v1/gateway/charges (channel: stripe)",
        "description": "**RETIRED on 2026-01-01.** This endpoint returns HTTP 410 Gone. Use `/v1/gateway/charges?provider=stripe` instead.\n\nDEPRECATED (sunset: 2026-01-01): Use the unified Payment Gateway at /v1/gateway/charges instead. \n\n**Migration:** Replace with `gatewayCreateCharge`. Create a card charge; card details are collected only through Stripe Elements.",
        "x-retired": true,
        "x-sunset-date": "2026-01-01",
        "x-successor": "/v1/gateway/charges?provider=stripe",
        "x-replacement-endpoint": "/v1/gateway/charges?provider=stripe",
        "x-codeSamples": [
          {
            "lang": "cURL",
            "label": "cURL",
            "source": "curl -X POST \"https://api.kangopenbanking.com/v1/stripe/payment-intent\" \\\n  -H \"Authorization: Bearer $KOB_ACCESS_TOKEN\" \\\n  -H \"Content-Type: application/json\" \\\n  -d '{}'"
          },
          {
            "lang": "JavaScript",
            "label": "Node.js",
            "source": "import { KangOpenBanking } from \"@kangopenbanking/sdk\";\n\nconst kob = new KangOpenBanking({ apiKey: process.env.KOB_API_KEY });\nconst res = await kob.request(\"POST\", \"/v1/stripe/payment-intent\", { /* payload */ });\nconsole.log(res);"
          },
          {
            "lang": "Python",
            "label": "Python",
            "source": "from kangopenbanking import KangOpenBanking\n\nkob = KangOpenBanking(api_key=os.environ[\"KOB_API_KEY\"])\nres = kob.request(\"POST\", \"/v1/stripe/payment-intent\", json={})\nprint(res)"
          },
          {
            "lang": "PHP",
            "label": "PHP",
            "source": "<?php\n$kob = new KangOpenBanking\\KangOpenBanking(getenv('KOB_API_KEY'));\n$res = $kob->request('POST', '/v1/stripe/payment-intent', []);\nprint_r($res);"
          }
        ],
        "x-replacement-operation-ids": [
          "gatewayCreateCharge"
        ],
        "x-migration-guide": "Create a card charge; card details are collected only through Stripe Elements."
      }
    },
    "/v1/stripe/confirm-payment": {
      "post": {
        "tags": [
          "Payments"
        ],
        "summary": "Confirm Stripe payment",
        "operationId": "stripeConfirmPayment",
        "security": [
          {
            "bearerAuth": []
          }
        ],
        "deprecated": true,
        "parameters": [
          {
            "name": "Idempotency-Key",
            "in": "header",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid"
            },
            "description": "Required on all POST/PUT endpoints. Unique key for idempotent request processing (UUID v4 recommended). Keys expire after 24 hours."
          },
          {
            "$ref": "#/components/parameters/RequestId"
          },
          {
            "$ref": "#/components/parameters/Traceparent"
          },
          {
            "$ref": "#/components/parameters/Tracestate"
          },
          {
            "$ref": "#/components/parameters/AcceptLanguage"
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "required": [
                  "payment_intent_id"
                ],
                "properties": {
                  "payment_intent_id": {
                    "type": "string"
                  }
                }
              }
            }
          }
        },
        "responses": {
          "410": {
            "description": "Gone — use /v1/gateway/charges/{chargeId}",
            "headers": {
              "Sunset": {
                "schema": {
                  "type": "string"
                },
                "description": "RFC 8594 sunset date (2026-01-01)."
              },
              "Link": {
                "schema": {
                  "type": "string"
                },
                "description": "</v1/gateway/charges/{chargeId}>; rel=\"successor-version\""
              },
              "Deprecation": {
                "schema": {
                  "type": "string"
                },
                "description": "true"
              },
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/XRateLimitLimit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/XRateLimitRemaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/XRateLimitReset"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                },
                "example": {
                  "type": "https://api.kangopenbanking.com/v1/errors/endpoint-retired",
                  "title": "Endpoint Retired",
                  "status": 410,
                  "detail": "This endpoint was retired on 2026-01-01. Use /v1/gateway/charges/{chargeId}.",
                  "error_code": "DEPRECATED_ENDPOINT_RETIRED"
                }
              }
            }
          },
          "429": {
            "description": "Rate limit exceeded. Retry after the interval in `Retry-After`.",
            "headers": {
              "Retry-After": {
                "schema": {
                  "type": "integer"
                },
                "description": "Seconds to wait before retrying."
              },
              "X-RateLimit-Limit": {
                "schema": {
                  "type": "integer"
                }
              },
              "X-RateLimit-Remaining": {
                "schema": {
                  "type": "integer"
                }
              },
              "X-RateLimit-Reset": {
                "schema": {
                  "type": "integer"
                }
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                },
                "examples": {
                  "rateLimited": {
                    "$ref": "#/components/examples/ErrorRateLimited"
                  }
                }
              }
            }
          }
        },
        "x-sunset": "2026-01-01",
        "x-replaced-by": "/v1/gateway/charges (channel: stripe)",
        "description": "**RETIRED on 2026-01-01.** This endpoint returns HTTP 410 Gone. Use `/v1/gateway/charges/{chargeId}` instead.\n\nDEPRECATED (sunset: 2026-01-01): Use the unified Payment Gateway at /v1/gateway/charges instead. \n\n**Migration:** Replace with `gatewayGetCharge`. Retrieve the charge status by `chargeId`.",
        "x-retired": true,
        "x-sunset-date": "2026-01-01",
        "x-successor": "/v1/gateway/charges/{chargeId}",
        "x-replacement-endpoint": "/v1/gateway/charges/{chargeId}",
        "x-codeSamples": [
          {
            "lang": "cURL",
            "label": "cURL",
            "source": "curl -X POST \"https://api.kangopenbanking.com/v1/stripe/confirm-payment\" \\\n  -H \"Authorization: Bearer $KOB_ACCESS_TOKEN\" \\\n  -H \"Content-Type: application/json\" \\\n  -d '{}'"
          },
          {
            "lang": "JavaScript",
            "label": "Node.js",
            "source": "import { KangOpenBanking } from \"@kangopenbanking/sdk\";\n\nconst kob = new KangOpenBanking({ apiKey: process.env.KOB_API_KEY });\nconst res = await kob.request(\"POST\", \"/v1/stripe/confirm-payment\", { /* payload */ });\nconsole.log(res);"
          },
          {
            "lang": "Python",
            "label": "Python",
            "source": "from kangopenbanking import KangOpenBanking\n\nkob = KangOpenBanking(api_key=os.environ[\"KOB_API_KEY\"])\nres = kob.request(\"POST\", \"/v1/stripe/confirm-payment\", json={})\nprint(res)"
          },
          {
            "lang": "PHP",
            "label": "PHP",
            "source": "<?php\n$kob = new KangOpenBanking\\KangOpenBanking(getenv('KOB_API_KEY'));\n$res = $kob->request('POST', '/v1/stripe/confirm-payment', []);\nprint_r($res);"
          }
        ],
        "x-replacement-operation-ids": [
          "gatewayGetCharge"
        ],
        "x-migration-guide": "Retrieve the charge status by `chargeId`."
      }
    },
    "/v1/banking/bulk-transfers": {
      "post": {
        "tags": [
          "Banking Operations"
        ],
        "summary": "Initiate bulk transfers",
        "operationId": "bulkTransfers",
        "security": [
          {
            "bearerAuth": []
          }
        ],
        "parameters": [
          {
            "name": "Idempotency-Key",
            "in": "header",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid"
            },
            "description": "Required on all POST/PUT endpoints. Unique key for idempotent request processing (UUID v4 recommended). Keys expire after 24 hours."
          },
          {
            "$ref": "#/components/parameters/RequestId"
          },
          {
            "$ref": "#/components/parameters/Traceparent"
          },
          {
            "$ref": "#/components/parameters/Tracestate"
          },
          {
            "$ref": "#/components/parameters/AcceptLanguage"
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "required": [
                  "transfers"
                ],
                "properties": {
                  "transfers": {
                    "type": "array",
                    "items": {
                      "type": "object",
                      "properties": {
                        "account_number": {
                          "type": "string"
                        },
                        "bank_code": {
                          "type": "string"
                        },
                        "amount": {
                          "type": "string",
                          "pattern": "^[0-9]{1,15}$",
                          "description": "Represented as a string integer in the currency's minor unit (XAF has no subunits)."
                        },
                        "narration": {
                          "type": "string"
                        }
                      }
                    }
                  }
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Bulk transfer initiated",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "success": {
                      "type": "boolean",
                      "example": true
                    },
                    "message": {
                      "type": "string"
                    }
                  }
                },
                "example": {
                  "success": true,
                  "message": "string"
                }
              }
            },
            "headers": {
              "x-fapi-interaction-id": {
                "$ref": "#/components/headers/XFapiInteractionIdResponse"
              },
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/XRateLimitLimit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/XRateLimitRemaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/XRateLimitReset"
              },
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              },
              "X-Idempotent-Replay": {
                "$ref": "#/components/headers/X-Idempotent-Replay"
              },
              "X-Idempotency-Status": {
                "$ref": "#/components/headers/X-Idempotency-Status"
              },
              "traceparent": {
                "$ref": "#/components/headers/Traceparent"
              },
              "Content-Language": {
                "$ref": "#/components/headers/Content-Language"
              }
            }
          },
          "400": {
            "description": "Bad request",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              },
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                },
                "examples": {
                  "error": {
                    "$ref": "#/components/examples/ErrorBadRequest"
                  }
                }
              }
            },
            "headers": {
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/XRateLimitLimit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/XRateLimitRemaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/XRateLimitReset"
              },
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "403": {
            "$ref": "#/components/responses/Forbidden",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "404": {
            "$ref": "#/components/responses/NotFound",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "409": {
            "$ref": "#/components/responses/Conflict",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "429": {
            "$ref": "#/components/responses/TooManyRequests",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "500": {
            "$ref": "#/components/responses/InternalServerError",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          }
        },
        "x-codeSamples": [
          {
            "lang": "cURL",
            "label": "cURL",
            "source": "curl -X POST \"https://api.kangopenbanking.com/v1/banking/bulk-transfers\" \\\n  -H \"Authorization: Bearer $KOB_ACCESS_TOKEN\" \\\n  -H \"Content-Type: application/json\" \\\n  -d '{}'"
          },
          {
            "lang": "JavaScript",
            "label": "Node.js",
            "source": "import { KangOpenBanking } from \"@kangopenbanking/sdk\";\n\nconst kob = new KangOpenBanking({ apiKey: process.env.KOB_API_KEY });\nconst res = await kob.request(\"POST\", \"/v1/banking/bulk-transfers\", { /* payload */ });\nconsole.log(res);"
          },
          {
            "lang": "Python",
            "label": "Python",
            "source": "from kangopenbanking import KangOpenBanking\n\nkob = KangOpenBanking(api_key=os.environ[\"KOB_API_KEY\"])\nres = kob.request(\"POST\", \"/v1/banking/bulk-transfers\", json={})\nprint(res)"
          },
          {
            "lang": "PHP",
            "label": "PHP",
            "source": "<?php\n$kob = new KangOpenBanking\\KangOpenBanking(getenv('KOB_API_KEY'));\n$res = $kob->request('POST', '/v1/banking/bulk-transfers', []);\nprint_r($res);"
          }
        ]
      }
    },
    "/v1/banking/exchange-rate": {
      "get": {
        "tags": [
          "Banking Operations"
        ],
        "summary": "Get exchange rate",
        "operationId": "exchangeRate",
        "security": [
          {
            "bearerAuth": []
          }
        ],
        "parameters": [
          {
            "name": "from",
            "in": "query",
            "required": true,
            "schema": {
              "type": "string",
              "example": "XAF"
            }
          },
          {
            "name": "to",
            "in": "query",
            "required": true,
            "schema": {
              "type": "string",
              "example": "USD"
            }
          },
          {
            "$ref": "#/components/parameters/RequestId"
          },
          {
            "$ref": "#/components/parameters/Traceparent"
          },
          {
            "$ref": "#/components/parameters/Tracestate"
          },
          {
            "$ref": "#/components/parameters/AcceptLanguage"
          }
        ],
        "responses": {
          "200": {
            "description": "Exchange rate",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "from": {
                      "type": "string"
                    },
                    "to": {
                      "type": "string"
                    },
                    "rate": {
                      "type": "number"
                    },
                    "timestamp": {
                      "type": "string",
                      "format": "date-time"
                    }
                  }
                },
                "example": {
                  "from": "string",
                  "to": "string",
                  "rate": 0,
                  "timestamp": "2026-01-01T00:00:00Z"
                }
              }
            },
            "headers": {
              "x-fapi-interaction-id": {
                "$ref": "#/components/headers/XFapiInteractionIdResponse"
              },
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/XRateLimitLimit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/XRateLimitRemaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/XRateLimitReset"
              },
              "Cache-Control": {
                "$ref": "#/components/headers/CacheControl"
              },
              "ETag": {
                "$ref": "#/components/headers/ETag"
              },
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              },
              "traceparent": {
                "$ref": "#/components/headers/Traceparent"
              },
              "Content-Language": {
                "$ref": "#/components/headers/Content-Language"
              }
            }
          },
          "400": {
            "description": "Bad request",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              },
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                },
                "examples": {
                  "error": {
                    "$ref": "#/components/examples/ErrorBadRequest"
                  }
                }
              }
            },
            "headers": {
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/XRateLimitLimit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/XRateLimitRemaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/XRateLimitReset"
              },
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "403": {
            "$ref": "#/components/responses/Forbidden",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "404": {
            "$ref": "#/components/responses/NotFound",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "409": {
            "$ref": "#/components/responses/Conflict",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "429": {
            "$ref": "#/components/responses/TooManyRequests",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "500": {
            "$ref": "#/components/responses/InternalServerError",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          }
        },
        "x-codeSamples": [
          {
            "lang": "cURL",
            "label": "cURL",
            "source": "curl -X GET \"https://api.kangopenbanking.com/v1/banking/exchange-rate\" \\\n  -H \"Authorization: Bearer $KOB_ACCESS_TOKEN\" \\\n  -H \"Content-Type: application/json\""
          },
          {
            "lang": "JavaScript",
            "label": "Node.js",
            "source": "import { KangOpenBanking } from \"@kangopenbanking/sdk\";\n\nconst kob = new KangOpenBanking({ apiKey: process.env.KOB_API_KEY });\nconst res = await kob.request(\"GET\", \"/v1/banking/exchange-rate\");\nconsole.log(res);"
          },
          {
            "lang": "Python",
            "label": "Python",
            "source": "from kangopenbanking import KangOpenBanking\n\nkob = KangOpenBanking(api_key=os.environ[\"KOB_API_KEY\"])\nres = kob.request(\"GET\", \"/v1/banking/exchange-rate\")\nprint(res)"
          },
          {
            "lang": "PHP",
            "label": "PHP",
            "source": "<?php\n$kob = new KangOpenBanking\\KangOpenBanking(getenv('KOB_API_KEY'));\n$res = $kob->request('GET', '/v1/banking/exchange-rate');\nprint_r($res);"
          }
        ]
      }
    },
    "/v1/cards": {
      "post": {
        "tags": [
          "Virtual Cards"
        ],
        "summary": "Create virtual card",
        "operationId": "virtualCardCreate",
        "security": [
          {
            "bearerAuth": []
          }
        ],
        "parameters": [
          {
            "name": "Idempotency-Key",
            "in": "header",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid"
            },
            "description": "Required on all POST/PUT endpoints. Unique key for idempotent request processing (UUID v4 recommended). Keys expire after 24 hours."
          },
          {
            "$ref": "#/components/parameters/RequestId"
          },
          {
            "$ref": "#/components/parameters/Traceparent"
          },
          {
            "$ref": "#/components/parameters/Tracestate"
          },
          {
            "$ref": "#/components/parameters/AcceptLanguage"
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "currency": {
                    "type": "string",
                    "example": "USD",
                    "enum": [
                      "XAF",
                      "XOF",
                      "USD",
                      "EUR",
                      "GBP",
                      "CNY",
                      "NGN",
                      "GHS",
                      "KES",
                      "ZAR"
                    ],
                    "default": "XAF",
                    "description": "ISO 4217 currency code. Default is XAF (Central African CFA Franc)."
                  },
                  "label": {
                    "type": "string"
                  }
                }
              }
            }
          }
        },
        "responses": {
          "201": {
            "description": "Card created",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/VirtualCard"
                },
                "example": {
                  "id": "00000000-0000-4000-8000-000000000000",
                  "card_number_masked": "**** **** **** 1234",
                  "balance_usd": 100,
                  "status": "active",
                  "expiry_month": 0,
                  "expiry_year": 0,
                  "created_at": "2026-01-01T00:00:00Z"
                }
              }
            },
            "headers": {
              "x-fapi-interaction-id": {
                "$ref": "#/components/headers/XFapiInteractionIdResponse"
              },
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/XRateLimitLimit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/XRateLimitRemaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/XRateLimitReset"
              },
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              },
              "X-Idempotent-Replay": {
                "$ref": "#/components/headers/X-Idempotent-Replay"
              },
              "X-Idempotency-Status": {
                "$ref": "#/components/headers/X-Idempotency-Status"
              },
              "traceparent": {
                "$ref": "#/components/headers/Traceparent"
              },
              "Content-Language": {
                "$ref": "#/components/headers/Content-Language"
              }
            }
          },
          "400": {
            "description": "Bad request",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              },
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                },
                "examples": {
                  "error": {
                    "$ref": "#/components/examples/ErrorBadRequest"
                  }
                }
              }
            },
            "headers": {
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/XRateLimitLimit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/XRateLimitRemaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/XRateLimitReset"
              },
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "403": {
            "$ref": "#/components/responses/Forbidden",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "404": {
            "$ref": "#/components/responses/NotFound",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "409": {
            "$ref": "#/components/responses/Conflict",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "429": {
            "$ref": "#/components/responses/TooManyRequests",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "500": {
            "$ref": "#/components/responses/InternalServerError",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          }
        },
        "x-codeSamples": [
          {
            "lang": "cURL",
            "label": "cURL",
            "source": "curl -X POST \"https://api.kangopenbanking.com/v1/cards\" \\\n  -H \"Authorization: Bearer $KOB_ACCESS_TOKEN\" \\\n  -H \"Content-Type: application/json\" \\\n  -d '{}'"
          },
          {
            "lang": "JavaScript",
            "label": "Node.js",
            "source": "import { KangOpenBanking } from \"@kangopenbanking/sdk\";\n\nconst kob = new KangOpenBanking({ apiKey: process.env.KOB_API_KEY });\nconst res = await kob.request(\"POST\", \"/v1/cards\", { /* payload */ });\nconsole.log(res);"
          },
          {
            "lang": "Python",
            "label": "Python",
            "source": "from kangopenbanking import KangOpenBanking\n\nkob = KangOpenBanking(api_key=os.environ[\"KOB_API_KEY\"])\nres = kob.request(\"POST\", \"/v1/cards\", json={})\nprint(res)"
          },
          {
            "lang": "PHP",
            "label": "PHP",
            "source": "<?php\n$kob = new KangOpenBanking\\KangOpenBanking(getenv('KOB_API_KEY'));\n$res = $kob->request('POST', '/v1/cards', []);\nprint_r($res);"
          }
        ]
      },
      "get": {
        "tags": [
          "Virtual Cards"
        ],
        "summary": "List virtual cards",
        "operationId": "virtualCardList",
        "security": [
          {
            "bearerAuth": []
          }
        ],
        "responses": {
          "200": {
            "description": "Cards list",
            "content": {
              "application/json": {
                "schema": {
                  "allOf": [
                    {
                      "$ref": "#/components/schemas/PaginatedResponse"
                    },
                    {
                      "type": "object",
                      "properties": {
                        "data": {
                          "type": "array",
                          "items": {
                            "$ref": "#/components/schemas/VirtualCard"
                          }
                        }
                      }
                    }
                  ]
                },
                "example": {
                  "data": [
                    {
                      "id": "f1d6f4a0-1d4e-4a3a-9e0a-1a2b3c4d5e6f",
                      "card_number_masked": "**** **** **** 1234",
                      "balance_usd": 100,
                      "status": "active",
                      "expiry_month": 1,
                      "expiry_year": 1,
                      "created_at": "2026-01-31T12:00:00Z"
                    }
                  ],
                  "pagination": {
                    "page": 1,
                    "limit": 20,
                    "total": 150,
                    "has_next": true,
                    "next_cursor": "eyJpZCI6IjEyMyJ9"
                  },
                  "meta": {
                    "request_id": "550e8400-e29b-41d4-a716-446655440000",
                    "timestamp": "2025-03-27T12:00:00Z",
                    "api_version": "4.3.0"
                  }
                }
              }
            },
            "headers": {
              "x-fapi-interaction-id": {
                "$ref": "#/components/headers/XFapiInteractionIdResponse"
              },
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/XRateLimitLimit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/XRateLimitRemaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/XRateLimitReset"
              },
              "Cache-Control": {
                "$ref": "#/components/headers/CacheControl"
              },
              "ETag": {
                "$ref": "#/components/headers/ETag"
              },
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              },
              "traceparent": {
                "$ref": "#/components/headers/Traceparent"
              },
              "Content-Language": {
                "$ref": "#/components/headers/Content-Language"
              }
            }
          },
          "400": {
            "description": "Bad request",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              },
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                },
                "examples": {
                  "error": {
                    "$ref": "#/components/examples/ErrorBadRequest"
                  }
                }
              }
            },
            "headers": {
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/XRateLimitLimit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/XRateLimitRemaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/XRateLimitReset"
              },
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "403": {
            "$ref": "#/components/responses/Forbidden",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "404": {
            "$ref": "#/components/responses/NotFound",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "409": {
            "$ref": "#/components/responses/Conflict",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "429": {
            "$ref": "#/components/responses/TooManyRequests",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "500": {
            "$ref": "#/components/responses/InternalServerError",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          }
        },
        "parameters": [
          {
            "$ref": "#/components/parameters/PageParam"
          },
          {
            "$ref": "#/components/parameters/LimitParam"
          },
          {
            "$ref": "#/components/parameters/CursorParam"
          },
          {
            "$ref": "#/components/parameters/RequestId"
          },
          {
            "$ref": "#/components/parameters/Traceparent"
          },
          {
            "$ref": "#/components/parameters/Tracestate"
          },
          {
            "$ref": "#/components/parameters/AcceptLanguage"
          }
        ],
        "x-codeSamples": [
          {
            "lang": "cURL",
            "label": "cURL",
            "source": "curl -X GET \"https://api.kangopenbanking.com/v1/cards\" \\\n  -H \"Authorization: Bearer $KOB_ACCESS_TOKEN\" \\\n  -H \"Content-Type: application/json\""
          },
          {
            "lang": "JavaScript",
            "label": "Node.js",
            "source": "import { KangOpenBanking } from \"@kangopenbanking/sdk\";\n\nconst kob = new KangOpenBanking({ apiKey: process.env.KOB_API_KEY });\nconst res = await kob.request(\"GET\", \"/v1/cards\");\nconsole.log(res);"
          },
          {
            "lang": "Python",
            "label": "Python",
            "source": "from kangopenbanking import KangOpenBanking\n\nkob = KangOpenBanking(api_key=os.environ[\"KOB_API_KEY\"])\nres = kob.request(\"GET\", \"/v1/cards\")\nprint(res)"
          },
          {
            "lang": "PHP",
            "label": "PHP",
            "source": "<?php\n$kob = new KangOpenBanking\\KangOpenBanking(getenv('KOB_API_KEY'));\n$res = $kob->request('GET', '/v1/cards');\nprint_r($res);"
          }
        ]
      }
    },
    "/v1/cards/{cardId}/topup": {
      "post": {
        "tags": [
          "Virtual Cards"
        ],
        "summary": "Top up virtual card",
        "operationId": "virtualCardTopup",
        "security": [
          {
            "bearerAuth": []
          }
        ],
        "parameters": [
          {
            "name": "cardId",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "Idempotency-Key",
            "in": "header",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid"
            },
            "description": "Required on all POST/PUT endpoints. Unique key for idempotent request processing (UUID v4 recommended). Keys expire after 24 hours."
          },
          {
            "$ref": "#/components/parameters/RequestId"
          },
          {
            "$ref": "#/components/parameters/Traceparent"
          },
          {
            "$ref": "#/components/parameters/Tracestate"
          },
          {
            "$ref": "#/components/parameters/AcceptLanguage"
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "required": [
                  "amount",
                  "source_currency"
                ],
                "properties": {
                  "amount": {
                    "type": "string",
                    "example": "50000",
                    "pattern": "^[0-9]{1,15}$",
                    "description": "Represented as a string integer in the currency's minor unit (XAF has no subunits)."
                  },
                  "source_currency": {
                    "type": "string",
                    "example": "XAF"
                  }
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Card topped up",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "success": {
                      "type": "boolean",
                      "example": true
                    },
                    "message": {
                      "type": "string"
                    }
                  }
                },
                "example": {
                  "success": true,
                  "message": "string"
                }
              }
            },
            "headers": {
              "x-fapi-interaction-id": {
                "$ref": "#/components/headers/XFapiInteractionIdResponse"
              },
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/XRateLimitLimit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/XRateLimitRemaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/XRateLimitReset"
              },
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              },
              "X-Idempotent-Replay": {
                "$ref": "#/components/headers/X-Idempotent-Replay"
              },
              "X-Idempotency-Status": {
                "$ref": "#/components/headers/X-Idempotency-Status"
              },
              "traceparent": {
                "$ref": "#/components/headers/Traceparent"
              },
              "Content-Language": {
                "$ref": "#/components/headers/Content-Language"
              }
            }
          },
          "400": {
            "description": "Bad request",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              },
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                },
                "examples": {
                  "error": {
                    "$ref": "#/components/examples/ErrorBadRequest"
                  }
                }
              }
            },
            "headers": {
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/XRateLimitLimit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/XRateLimitRemaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/XRateLimitReset"
              },
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "403": {
            "$ref": "#/components/responses/Forbidden",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "404": {
            "$ref": "#/components/responses/NotFound",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "409": {
            "$ref": "#/components/responses/Conflict",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "429": {
            "$ref": "#/components/responses/TooManyRequests",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "500": {
            "$ref": "#/components/responses/InternalServerError",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          }
        },
        "x-codeSamples": [
          {
            "lang": "cURL",
            "label": "cURL",
            "source": "curl -X POST \"https://api.kangopenbanking.com/v1/cards/{cardId}/topup\" \\\n  -H \"Authorization: Bearer $KOB_ACCESS_TOKEN\" \\\n  -H \"Content-Type: application/json\" \\\n  -d '{}'"
          },
          {
            "lang": "JavaScript",
            "label": "Node.js",
            "source": "import { KangOpenBanking } from \"@kangopenbanking/sdk\";\n\nconst kob = new KangOpenBanking({ apiKey: process.env.KOB_API_KEY });\nconst res = await kob.request(\"POST\", \"/v1/cards/{cardId}/topup\", { /* payload */ });\nconsole.log(res);"
          },
          {
            "lang": "Python",
            "label": "Python",
            "source": "from kangopenbanking import KangOpenBanking\n\nkob = KangOpenBanking(api_key=os.environ[\"KOB_API_KEY\"])\nres = kob.request(\"POST\", \"/v1/cards/{cardId}/topup\", json={})\nprint(res)"
          },
          {
            "lang": "PHP",
            "label": "PHP",
            "source": "<?php\n$kob = new KangOpenBanking\\KangOpenBanking(getenv('KOB_API_KEY'));\n$res = $kob->request('POST', '/v1/cards/{cardId}/topup', []);\nprint_r($res);"
          }
        ]
      }
    },
    "/v1/cards/{cardId}/transactions": {
      "get": {
        "tags": [
          "Virtual Cards"
        ],
        "summary": "Card transactions",
        "operationId": "virtualCardTransactions",
        "security": [
          {
            "bearerAuth": []
          }
        ],
        "parameters": [
          {
            "name": "cardId",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "limit",
            "in": "query",
            "schema": {
              "type": "integer",
              "default": 25,
              "maximum": 100
            },
            "description": "Items per page"
          },
          {
            "name": "offset",
            "in": "query",
            "schema": {
              "type": "integer",
              "default": 0
            },
            "description": "Items to skip"
          },
          {
            "name": "sort_by",
            "in": "query",
            "schema": {
              "type": "string",
              "default": "created_at"
            },
            "description": "Sort field"
          },
          {
            "name": "sort_order",
            "in": "query",
            "schema": {
              "type": "string",
              "enum": [
                "asc",
                "desc"
              ],
              "default": "desc"
            },
            "description": "Sort direction"
          },
          {
            "$ref": "#/components/parameters/StartingAfter"
          },
          {
            "$ref": "#/components/parameters/EndingBefore"
          },
          {
            "$ref": "#/components/parameters/RequestId"
          },
          {
            "$ref": "#/components/parameters/Traceparent"
          },
          {
            "$ref": "#/components/parameters/Tracestate"
          },
          {
            "$ref": "#/components/parameters/AcceptLanguage"
          }
        ],
        "responses": {
          "200": {
            "description": "Card transactions",
            "content": {
              "application/json": {
                "schema": {
                  "allOf": [
                    {
                      "$ref": "#/components/schemas/PaginatedResponse"
                    },
                    {
                      "type": "object",
                      "properties": {
                        "data": {
                          "type": "array",
                          "items": {
                            "$ref": "#/components/schemas/Transaction"
                          }
                        }
                      }
                    }
                  ]
                },
                "example": {
                  "data": [
                    {
                      "transaction_id": "f1d6f4a0-1d4e-4a3a-9e0a-1a2b3c4d5e6f",
                      "amount": "25000",
                      "currency": "XAF",
                      "type": "debit",
                      "description": "Mobile Money transfer from 237650000000",
                      "balance_after": "1475000",
                      "booking_date": "2026-01-31",
                      "value_date": "2026-01-31",
                      "timestamp": "2026-01-31T12:00:00Z",
                      "AccountId": "XAF",
                      "TransactionId": "XAF",
                      "Amount": "1000",
                      "Currency": "XAF",
                      "CreditDebitIndicator": "Credit",
                      "BookingDateTime": "2026-01-31T12:00:00Z",
                      "ValueDateTime": "2026-01-31T12:00:00Z",
                      "TransactionInformation": "Payment for Invoice INV-2025-001 — Professional Services",
                      "Status": "Booked"
                    }
                  ],
                  "pagination": {
                    "page": 1,
                    "limit": 20,
                    "total": 150,
                    "has_next": true,
                    "next_cursor": "eyJpZCI6IjEyMyJ9"
                  },
                  "meta": {
                    "request_id": "550e8400-e29b-41d4-a716-446655440000",
                    "timestamp": "2025-03-27T12:00:00Z",
                    "api_version": "4.3.0"
                  }
                }
              }
            },
            "headers": {
              "x-fapi-interaction-id": {
                "$ref": "#/components/headers/XFapiInteractionIdResponse"
              },
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/XRateLimitLimit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/XRateLimitRemaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/XRateLimitReset"
              },
              "Cache-Control": {
                "$ref": "#/components/headers/CacheControl"
              },
              "ETag": {
                "$ref": "#/components/headers/ETag"
              },
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              },
              "traceparent": {
                "$ref": "#/components/headers/Traceparent"
              },
              "Content-Language": {
                "$ref": "#/components/headers/Content-Language"
              }
            }
          },
          "400": {
            "description": "Bad request",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              },
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                },
                "examples": {
                  "error": {
                    "$ref": "#/components/examples/ErrorBadRequest"
                  }
                }
              }
            },
            "headers": {
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/XRateLimitLimit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/XRateLimitRemaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/XRateLimitReset"
              },
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "403": {
            "$ref": "#/components/responses/Forbidden",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "404": {
            "$ref": "#/components/responses/NotFound",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "409": {
            "$ref": "#/components/responses/Conflict",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "429": {
            "$ref": "#/components/responses/TooManyRequests",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "500": {
            "$ref": "#/components/responses/InternalServerError",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          }
        },
        "x-codeSamples": [
          {
            "lang": "cURL",
            "label": "cURL",
            "source": "curl -X GET \"https://api.kangopenbanking.com/v1/cards/{cardId}/transactions\" \\\n  -H \"Authorization: Bearer $KOB_ACCESS_TOKEN\" \\\n  -H \"Content-Type: application/json\""
          },
          {
            "lang": "JavaScript",
            "label": "Node.js",
            "source": "import { KangOpenBanking } from \"@kangopenbanking/sdk\";\n\nconst kob = new KangOpenBanking({ apiKey: process.env.KOB_API_KEY });\nconst res = await kob.request(\"GET\", \"/v1/cards/{cardId}/transactions\");\nconsole.log(res);"
          },
          {
            "lang": "Python",
            "label": "Python",
            "source": "from kangopenbanking import KangOpenBanking\n\nkob = KangOpenBanking(api_key=os.environ[\"KOB_API_KEY\"])\nres = kob.request(\"GET\", \"/v1/cards/{cardId}/transactions\")\nprint(res)"
          },
          {
            "lang": "PHP",
            "label": "PHP",
            "source": "<?php\n$kob = new KangOpenBanking\\KangOpenBanking(getenv('KOB_API_KEY'));\n$res = $kob->request('GET', '/v1/cards/{cardId}/transactions');\nprint_r($res);"
          }
        ]
      }
    },
    "/v1/cards/{cardId}/status": {
      "put": {
        "tags": [
          "Virtual Cards"
        ],
        "summary": "Update card status",
        "operationId": "virtualCardUpdateStatus",
        "security": [
          {
            "bearerAuth": []
          }
        ],
        "parameters": [
          {
            "name": "cardId",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "$ref": "#/components/parameters/IdempotencyKey"
          },
          {
            "$ref": "#/components/parameters/RequestId"
          },
          {
            "$ref": "#/components/parameters/Traceparent"
          },
          {
            "$ref": "#/components/parameters/Tracestate"
          },
          {
            "$ref": "#/components/parameters/AcceptLanguage"
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "required": [
                  "status"
                ],
                "properties": {
                  "status": {
                    "type": "string",
                    "enum": [
                      "active",
                      "frozen",
                      "cancelled"
                    ]
                  }
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Status updated",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "success": {
                      "type": "boolean",
                      "example": true
                    },
                    "message": {
                      "type": "string"
                    }
                  }
                },
                "example": {
                  "success": true,
                  "message": "string"
                }
              }
            },
            "headers": {
              "x-fapi-interaction-id": {
                "$ref": "#/components/headers/XFapiInteractionIdResponse"
              },
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/XRateLimitLimit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/XRateLimitRemaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/XRateLimitReset"
              },
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              },
              "X-Idempotent-Replay": {
                "$ref": "#/components/headers/X-Idempotent-Replay"
              },
              "X-Idempotency-Status": {
                "$ref": "#/components/headers/X-Idempotency-Status"
              },
              "traceparent": {
                "$ref": "#/components/headers/Traceparent"
              },
              "Content-Language": {
                "$ref": "#/components/headers/Content-Language"
              }
            }
          },
          "400": {
            "description": "Bad request",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              },
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                },
                "examples": {
                  "error": {
                    "$ref": "#/components/examples/ErrorBadRequest"
                  }
                }
              }
            },
            "headers": {
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/XRateLimitLimit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/XRateLimitRemaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/XRateLimitReset"
              },
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "403": {
            "$ref": "#/components/responses/Forbidden",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "404": {
            "$ref": "#/components/responses/NotFound",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "409": {
            "$ref": "#/components/responses/Conflict",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "429": {
            "$ref": "#/components/responses/TooManyRequests",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "500": {
            "$ref": "#/components/responses/InternalServerError",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          }
        },
        "x-codeSamples": [
          {
            "lang": "cURL",
            "label": "cURL",
            "source": "curl -X PUT \"https://api.kangopenbanking.com/v1/cards/{cardId}/status\" \\\n  -H \"Authorization: Bearer $KOB_ACCESS_TOKEN\" \\\n  -H \"Content-Type: application/json\" \\\n  -d '{}'"
          },
          {
            "lang": "JavaScript",
            "label": "Node.js",
            "source": "import { KangOpenBanking } from \"@kangopenbanking/sdk\";\n\nconst kob = new KangOpenBanking({ apiKey: process.env.KOB_API_KEY });\nconst res = await kob.request(\"PUT\", \"/v1/cards/{cardId}/status\", { /* payload */ });\nconsole.log(res);"
          },
          {
            "lang": "Python",
            "label": "Python",
            "source": "from kangopenbanking import KangOpenBanking\n\nkob = KangOpenBanking(api_key=os.environ[\"KOB_API_KEY\"])\nres = kob.request(\"PUT\", \"/v1/cards/{cardId}/status\", json={})\nprint(res)"
          },
          {
            "lang": "PHP",
            "label": "PHP",
            "source": "<?php\n$kob = new KangOpenBanking\\KangOpenBanking(getenv('KOB_API_KEY'));\n$res = $kob->request('PUT', '/v1/cards/{cardId}/status', []);\nprint_r($res);"
          }
        ]
      }
    },
    "/v1/standards/iso20022/pain001/parse": {
      "post": {
        "tags": [
          "Standards"
        ],
        "summary": "Parse pain.001",
        "operationId": "iso20022Pain001Parser",
        "security": [
          {
            "bearerAuth": []
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/xml": {
              "schema": {
                "type": "string"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Parsed payment initiation",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "message_id": {
                      "type": "string"
                    },
                    "creation_date": {
                      "type": "string"
                    },
                    "payments": {
                      "type": "array",
                      "items": {
                        "type": "object",
                        "properties": {
                          "end_to_end_id": {
                            "type": "string"
                          },
                          "amount": {
                            "type": "string",
                            "pattern": "^[0-9]{1,15}$",
                            "description": "Represented as a string integer in the currency's minor unit (XAF has no subunits). Must be consistent with the currency field."
                          },
                          "currency": {
                            "type": "string",
                            "enum": [
                              "XAF",
                              "XOF",
                              "USD",
                              "EUR",
                              "GBP",
                              "CNY",
                              "NGN",
                              "GHS",
                              "KES",
                              "ZAR"
                            ],
                            "default": "XAF",
                            "description": "ISO 4217 currency code. Default is XAF (Central African CFA Franc)."
                          },
                          "creditor_name": {
                            "type": "string"
                          },
                          "creditor_account": {
                            "type": "string"
                          }
                        }
                      }
                    }
                  }
                },
                "example": {
                  "message_id": "string",
                  "creation_date": "string",
                  "payments": [
                    {
                      "end_to_end_id": "string",
                      "amount": "1000",
                      "currency": "XAF",
                      "creditor_name": "string",
                      "creditor_account": "string"
                    }
                  ]
                }
              }
            },
            "headers": {
              "x-fapi-interaction-id": {
                "$ref": "#/components/headers/XFapiInteractionIdResponse"
              },
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/XRateLimitLimit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/XRateLimitRemaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/XRateLimitReset"
              },
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              },
              "traceparent": {
                "$ref": "#/components/headers/Traceparent"
              },
              "Content-Language": {
                "$ref": "#/components/headers/Content-Language"
              }
            }
          },
          "400": {
            "description": "Bad request",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              },
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                },
                "examples": {
                  "error": {
                    "$ref": "#/components/examples/ErrorBadRequest"
                  }
                }
              }
            },
            "headers": {
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/XRateLimitLimit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/XRateLimitRemaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/XRateLimitReset"
              },
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "403": {
            "$ref": "#/components/responses/Forbidden",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "404": {
            "$ref": "#/components/responses/NotFound",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "409": {
            "$ref": "#/components/responses/Conflict",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "429": {
            "$ref": "#/components/responses/TooManyRequests",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "500": {
            "$ref": "#/components/responses/InternalServerError",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          }
        },
        "x-iso20022-message": "pain.001.001.09",
        "parameters": [
          {
            "$ref": "#/components/parameters/RequestId"
          },
          {
            "$ref": "#/components/parameters/Traceparent"
          },
          {
            "$ref": "#/components/parameters/Tracestate"
          },
          {
            "$ref": "#/components/parameters/AcceptLanguage"
          }
        ],
        "x-codeSamples": [
          {
            "lang": "cURL",
            "label": "cURL",
            "source": "curl -X POST \"https://api.kangopenbanking.com/v1/standards/iso20022/pain001/parse\" \\\n  -H \"Authorization: Bearer $KOB_ACCESS_TOKEN\" \\\n  -H \"Content-Type: application/json\" \\\n  -d '{}'"
          },
          {
            "lang": "JavaScript",
            "label": "Node.js",
            "source": "import { KangOpenBanking } from \"@kangopenbanking/sdk\";\n\nconst kob = new KangOpenBanking({ apiKey: process.env.KOB_API_KEY });\nconst res = await kob.request(\"POST\", \"/v1/standards/iso20022/pain001/parse\", { /* payload */ });\nconsole.log(res);"
          },
          {
            "lang": "Python",
            "label": "Python",
            "source": "from kangopenbanking import KangOpenBanking\n\nkob = KangOpenBanking(api_key=os.environ[\"KOB_API_KEY\"])\nres = kob.request(\"POST\", \"/v1/standards/iso20022/pain001/parse\", json={})\nprint(res)"
          },
          {
            "lang": "PHP",
            "label": "PHP",
            "source": "<?php\n$kob = new KangOpenBanking\\KangOpenBanking(getenv('KOB_API_KEY'));\n$res = $kob->request('POST', '/v1/standards/iso20022/pain001/parse', []);\nprint_r($res);"
          }
        ]
      }
    },
    "/v1/standards/iso20022/camt053/parse": {
      "post": {
        "tags": [
          "Standards"
        ],
        "summary": "Parse camt.053",
        "operationId": "iso20022Camt053Parser",
        "security": [
          {
            "bearerAuth": []
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/xml": {
              "schema": {
                "type": "string"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Parsed bank statement",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "statement_id": {
                      "type": "string"
                    },
                    "account": {
                      "type": "string"
                    },
                    "opening_balance": {
                      "type": "number"
                    },
                    "closing_balance": {
                      "type": "number"
                    },
                    "entries": {
                      "type": "array",
                      "items": {
                        "type": "object",
                        "properties": {
                          "amount": {
                            "type": "string",
                            "pattern": "^[0-9]{1,15}$",
                            "description": "Represented as a string integer in the currency's minor unit (XAF has no subunits)."
                          },
                          "credit_debit": {
                            "type": "string"
                          },
                          "booking_date": {
                            "type": "string"
                          },
                          "reference": {
                            "type": "string"
                          }
                        }
                      }
                    }
                  }
                },
                "example": {
                  "statement_id": "string",
                  "account": "string",
                  "opening_balance": 0,
                  "closing_balance": 0,
                  "entries": [
                    {
                      "amount": "1000",
                      "credit_debit": "string",
                      "booking_date": "string",
                      "reference": "string"
                    }
                  ]
                }
              }
            },
            "headers": {
              "x-fapi-interaction-id": {
                "$ref": "#/components/headers/XFapiInteractionIdResponse"
              },
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/XRateLimitLimit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/XRateLimitRemaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/XRateLimitReset"
              },
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              },
              "traceparent": {
                "$ref": "#/components/headers/Traceparent"
              },
              "Content-Language": {
                "$ref": "#/components/headers/Content-Language"
              }
            }
          },
          "400": {
            "description": "Bad request",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              },
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                },
                "examples": {
                  "error": {
                    "$ref": "#/components/examples/ErrorBadRequest"
                  }
                }
              }
            },
            "headers": {
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/XRateLimitLimit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/XRateLimitRemaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/XRateLimitReset"
              },
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "403": {
            "$ref": "#/components/responses/Forbidden",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "404": {
            "$ref": "#/components/responses/NotFound",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "409": {
            "$ref": "#/components/responses/Conflict",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "429": {
            "$ref": "#/components/responses/TooManyRequests",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "500": {
            "$ref": "#/components/responses/InternalServerError",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          }
        },
        "x-iso20022-message": "camt.053.001.08",
        "parameters": [
          {
            "$ref": "#/components/parameters/RequestId"
          },
          {
            "$ref": "#/components/parameters/Traceparent"
          },
          {
            "$ref": "#/components/parameters/Tracestate"
          },
          {
            "$ref": "#/components/parameters/AcceptLanguage"
          }
        ],
        "x-codeSamples": [
          {
            "lang": "cURL",
            "label": "cURL",
            "source": "curl -X POST \"https://api.kangopenbanking.com/v1/standards/iso20022/camt053/parse\" \\\n  -H \"Authorization: Bearer $KOB_ACCESS_TOKEN\" \\\n  -H \"Content-Type: application/json\" \\\n  -d '{}'"
          },
          {
            "lang": "JavaScript",
            "label": "Node.js",
            "source": "import { KangOpenBanking } from \"@kangopenbanking/sdk\";\n\nconst kob = new KangOpenBanking({ apiKey: process.env.KOB_API_KEY });\nconst res = await kob.request(\"POST\", \"/v1/standards/iso20022/camt053/parse\", { /* payload */ });\nconsole.log(res);"
          },
          {
            "lang": "Python",
            "label": "Python",
            "source": "from kangopenbanking import KangOpenBanking\n\nkob = KangOpenBanking(api_key=os.environ[\"KOB_API_KEY\"])\nres = kob.request(\"POST\", \"/v1/standards/iso20022/camt053/parse\", json={})\nprint(res)"
          },
          {
            "lang": "PHP",
            "label": "PHP",
            "source": "<?php\n$kob = new KangOpenBanking\\KangOpenBanking(getenv('KOB_API_KEY'));\n$res = $kob->request('POST', '/v1/standards/iso20022/camt053/parse', []);\nprint_r($res);"
          }
        ]
      }
    },
    "/v1/standards/iso20022/pacs008/generate": {
      "post": {
        "tags": [
          "Standards"
        ],
        "summary": "Generate pacs.008",
        "operationId": "iso20022Pacs008Generator",
        "security": [
          {
            "bearerAuth": []
          }
        ],
        "parameters": [
          {
            "name": "Idempotency-Key",
            "in": "header",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid"
            },
            "description": "Required on all POST/PUT endpoints. Unique key for idempotent request processing (UUID v4 recommended). Keys expire after 24 hours."
          },
          {
            "$ref": "#/components/parameters/RequestId"
          },
          {
            "$ref": "#/components/parameters/Traceparent"
          },
          {
            "$ref": "#/components/parameters/Tracestate"
          },
          {
            "$ref": "#/components/parameters/AcceptLanguage"
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Generated FI-to-FI payment",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "xml": {
                      "type": "string"
                    },
                    "message_id": {
                      "type": "string"
                    },
                    "transaction_id": {
                      "type": "string"
                    }
                  }
                },
                "example": {
                  "xml": "string",
                  "message_id": "string",
                  "transaction_id": "string"
                }
              }
            },
            "headers": {
              "x-fapi-interaction-id": {
                "$ref": "#/components/headers/XFapiInteractionIdResponse"
              },
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/XRateLimitLimit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/XRateLimitRemaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/XRateLimitReset"
              },
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              },
              "traceparent": {
                "$ref": "#/components/headers/Traceparent"
              },
              "Content-Language": {
                "$ref": "#/components/headers/Content-Language"
              }
            }
          },
          "400": {
            "description": "Bad request",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              },
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                },
                "examples": {
                  "error": {
                    "$ref": "#/components/examples/ErrorBadRequest"
                  }
                }
              }
            },
            "headers": {
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/XRateLimitLimit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/XRateLimitRemaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/XRateLimitReset"
              },
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "403": {
            "$ref": "#/components/responses/Forbidden",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "404": {
            "$ref": "#/components/responses/NotFound",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "409": {
            "$ref": "#/components/responses/Conflict",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "429": {
            "$ref": "#/components/responses/TooManyRequests",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "500": {
            "$ref": "#/components/responses/InternalServerError",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          }
        },
        "x-iso20022-message": "pacs.008.001.08",
        "x-codeSamples": [
          {
            "lang": "cURL",
            "label": "cURL",
            "source": "curl -X POST \"https://api.kangopenbanking.com/v1/standards/iso20022/pacs008/generate\" \\\n  -H \"Authorization: Bearer $KOB_ACCESS_TOKEN\" \\\n  -H \"Content-Type: application/json\" \\\n  -d '{}'"
          },
          {
            "lang": "JavaScript",
            "label": "Node.js",
            "source": "import { KangOpenBanking } from \"@kangopenbanking/sdk\";\n\nconst kob = new KangOpenBanking({ apiKey: process.env.KOB_API_KEY });\nconst res = await kob.request(\"POST\", \"/v1/standards/iso20022/pacs008/generate\", { /* payload */ });\nconsole.log(res);"
          },
          {
            "lang": "Python",
            "label": "Python",
            "source": "from kangopenbanking import KangOpenBanking\n\nkob = KangOpenBanking(api_key=os.environ[\"KOB_API_KEY\"])\nres = kob.request(\"POST\", \"/v1/standards/iso20022/pacs008/generate\", json={})\nprint(res)"
          },
          {
            "lang": "PHP",
            "label": "PHP",
            "source": "<?php\n$kob = new KangOpenBanking\\KangOpenBanking(getenv('KOB_API_KEY'));\n$res = $kob->request('POST', '/v1/standards/iso20022/pacs008/generate', []);\nprint_r($res);"
          }
        ]
      }
    },
    "/v1/standards/iso20022/pacs002/generate": {
      "post": {
        "tags": [
          "Standards"
        ],
        "summary": "Generate pacs.002",
        "operationId": "iso20022Pacs002Generator",
        "security": [
          {
            "bearerAuth": []
          }
        ],
        "parameters": [
          {
            "name": "Idempotency-Key",
            "in": "header",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid"
            },
            "description": "Required on all POST/PUT endpoints. Unique key for idempotent request processing (UUID v4 recommended). Keys expire after 24 hours."
          },
          {
            "$ref": "#/components/parameters/RequestId"
          },
          {
            "$ref": "#/components/parameters/Traceparent"
          },
          {
            "$ref": "#/components/parameters/Tracestate"
          },
          {
            "$ref": "#/components/parameters/AcceptLanguage"
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Generated payment status report",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "xml": {
                      "type": "string"
                    },
                    "message_id": {
                      "type": "string"
                    },
                    "status": {
                      "type": "string"
                    }
                  }
                },
                "example": {
                  "xml": "string",
                  "message_id": "string",
                  "status": "string"
                }
              }
            },
            "headers": {
              "x-fapi-interaction-id": {
                "$ref": "#/components/headers/XFapiInteractionIdResponse"
              },
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/XRateLimitLimit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/XRateLimitRemaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/XRateLimitReset"
              },
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              },
              "traceparent": {
                "$ref": "#/components/headers/Traceparent"
              },
              "Content-Language": {
                "$ref": "#/components/headers/Content-Language"
              }
            }
          },
          "400": {
            "description": "Bad request",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              },
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                },
                "examples": {
                  "error": {
                    "$ref": "#/components/examples/ErrorBadRequest"
                  }
                }
              }
            },
            "headers": {
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/XRateLimitLimit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/XRateLimitRemaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/XRateLimitReset"
              },
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "403": {
            "$ref": "#/components/responses/Forbidden",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "404": {
            "$ref": "#/components/responses/NotFound",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "409": {
            "$ref": "#/components/responses/Conflict",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "429": {
            "$ref": "#/components/responses/TooManyRequests",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "500": {
            "$ref": "#/components/responses/InternalServerError",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          }
        },
        "x-iso20022-message": "pacs.002.001.10",
        "x-codeSamples": [
          {
            "lang": "cURL",
            "label": "cURL",
            "source": "curl -X POST \"https://api.kangopenbanking.com/v1/standards/iso20022/pacs002/generate\" \\\n  -H \"Authorization: Bearer $KOB_ACCESS_TOKEN\" \\\n  -H \"Content-Type: application/json\" \\\n  -d '{}'"
          },
          {
            "lang": "JavaScript",
            "label": "Node.js",
            "source": "import { KangOpenBanking } from \"@kangopenbanking/sdk\";\n\nconst kob = new KangOpenBanking({ apiKey: process.env.KOB_API_KEY });\nconst res = await kob.request(\"POST\", \"/v1/standards/iso20022/pacs002/generate\", { /* payload */ });\nconsole.log(res);"
          },
          {
            "lang": "Python",
            "label": "Python",
            "source": "from kangopenbanking import KangOpenBanking\n\nkob = KangOpenBanking(api_key=os.environ[\"KOB_API_KEY\"])\nres = kob.request(\"POST\", \"/v1/standards/iso20022/pacs002/generate\", json={})\nprint(res)"
          },
          {
            "lang": "PHP",
            "label": "PHP",
            "source": "<?php\n$kob = new KangOpenBanking\\KangOpenBanking(getenv('KOB_API_KEY'));\n$res = $kob->request('POST', '/v1/standards/iso20022/pacs002/generate', []);\nprint_r($res);"
          }
        ]
      }
    },
    "/v1/standards/swift/mt103/parse": {
      "post": {
        "tags": [
          "Standards"
        ],
        "summary": "Parse MT103",
        "operationId": "swiftMt103Parser",
        "security": [
          {
            "bearerAuth": []
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "text/plain": {
              "schema": {
                "type": "string"
              }
            }
          }
        },
        "responses": {
          "410": {
            "description": "Gone — use /v1/standards/iso20022/pacs008/generate",
            "headers": {
              "Sunset": {
                "schema": {
                  "type": "string"
                },
                "description": "RFC 8594 sunset date (2025-11-22)."
              },
              "Link": {
                "schema": {
                  "type": "string"
                },
                "description": "</v1/standards/iso20022/pacs008/generate>; rel=\"successor-version\""
              },
              "Deprecation": {
                "schema": {
                  "type": "string"
                },
                "description": "true"
              },
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/XRateLimitLimit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/XRateLimitRemaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/XRateLimitReset"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                },
                "example": {
                  "type": "https://api.kangopenbanking.com/v1/errors/endpoint-retired",
                  "title": "Endpoint Retired",
                  "status": 410,
                  "detail": "This endpoint was retired on 2025-11-22. Use /v1/standards/iso20022/pacs008/generate.",
                  "error_code": "DEPRECATED_ENDPOINT_RETIRED"
                }
              }
            }
          },
          "429": {
            "description": "Rate limit exceeded. Retry after the interval in `Retry-After`.",
            "headers": {
              "Retry-After": {
                "schema": {
                  "type": "integer"
                },
                "description": "Seconds to wait before retrying."
              },
              "X-RateLimit-Limit": {
                "schema": {
                  "type": "integer"
                }
              },
              "X-RateLimit-Remaining": {
                "schema": {
                  "type": "integer"
                }
              },
              "X-RateLimit-Reset": {
                "schema": {
                  "type": "integer"
                }
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                },
                "examples": {
                  "rateLimited": {
                    "$ref": "#/components/examples/ErrorRateLimited"
                  }
                }
              }
            }
          }
        },
        "deprecated": true,
        "description": "**RETIRED on 2025-11-22.** This endpoint returns HTTP 410 Gone. Use the ISO 20022 operations listed under Migration below.\n\nDEPRECATED: SWIFT MT messages are being decommissioned as part of the global ISO 20022 migration programme. This endpoint will be removed on 2025-11-22. Please migrate to the equivalent ISO 20022 MX message endpoints: /v1/standards/iso20022/pacs008/generate (replaces MT103) and /v1/standards/iso20022/camt053/parse (replaces MT940). \n\n**Migration:** Replace with `iso20022Pain001Parser`. Submit the equivalent ISO 20022 pain.001 message.",
        "x-sunset": "2025-11-22",
        "x-replaced-by": "/v1/standards/iso20022/pacs008/generate",
        "x-retired": true,
        "x-sunset-date": "2025-11-22",
        "x-successor": "/v1/standards/iso20022/pacs008/generate",
        "x-replacement-endpoint": "/v1/standards/iso20022/pacs008/generate",
        "parameters": [
          {
            "$ref": "#/components/parameters/RequestId"
          },
          {
            "$ref": "#/components/parameters/Traceparent"
          },
          {
            "$ref": "#/components/parameters/Tracestate"
          },
          {
            "$ref": "#/components/parameters/AcceptLanguage"
          }
        ],
        "x-codeSamples": [
          {
            "lang": "cURL",
            "label": "cURL",
            "source": "curl -X POST \"https://api.kangopenbanking.com/v1/standards/swift/mt103/parse\" \\\n  -H \"Authorization: Bearer $KOB_ACCESS_TOKEN\" \\\n  -H \"Content-Type: application/json\" \\\n  -d '{}'"
          },
          {
            "lang": "JavaScript",
            "label": "Node.js",
            "source": "import { KangOpenBanking } from \"@kangopenbanking/sdk\";\n\nconst kob = new KangOpenBanking({ apiKey: process.env.KOB_API_KEY });\nconst res = await kob.request(\"POST\", \"/v1/standards/swift/mt103/parse\", { /* payload */ });\nconsole.log(res);"
          },
          {
            "lang": "Python",
            "label": "Python",
            "source": "from kangopenbanking import KangOpenBanking\n\nkob = KangOpenBanking(api_key=os.environ[\"KOB_API_KEY\"])\nres = kob.request(\"POST\", \"/v1/standards/swift/mt103/parse\", json={})\nprint(res)"
          },
          {
            "lang": "PHP",
            "label": "PHP",
            "source": "<?php\n$kob = new KangOpenBanking\\KangOpenBanking(getenv('KOB_API_KEY'));\n$res = $kob->request('POST', '/v1/standards/swift/mt103/parse', []);\nprint_r($res);"
          }
        ],
        "x-replacement-operation-ids": [
          "iso20022Pain001Parser"
        ],
        "x-migration-guide": "Submit the equivalent ISO 20022 pain.001 message."
      }
    },
    "/v1/standards/swift/mt940/parse": {
      "post": {
        "tags": [
          "Standards"
        ],
        "summary": "Parse MT940",
        "operationId": "swiftMt940Parser",
        "security": [
          {
            "bearerAuth": []
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "text/plain": {
              "schema": {
                "type": "string"
              }
            }
          }
        },
        "responses": {
          "410": {
            "description": "Gone — use /v1/standards/iso20022/camt053/parse",
            "headers": {
              "Sunset": {
                "schema": {
                  "type": "string"
                },
                "description": "RFC 8594 sunset date (2025-11-22)."
              },
              "Link": {
                "schema": {
                  "type": "string"
                },
                "description": "</v1/standards/iso20022/camt053/parse>; rel=\"successor-version\""
              },
              "Deprecation": {
                "schema": {
                  "type": "string"
                },
                "description": "true"
              },
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/XRateLimitLimit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/XRateLimitRemaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/XRateLimitReset"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                },
                "example": {
                  "type": "https://api.kangopenbanking.com/v1/errors/endpoint-retired",
                  "title": "Endpoint Retired",
                  "status": 410,
                  "detail": "This endpoint was retired on 2025-11-22. Use /v1/standards/iso20022/camt053/parse.",
                  "error_code": "DEPRECATED_ENDPOINT_RETIRED"
                }
              }
            }
          },
          "429": {
            "description": "Rate limit exceeded. Retry after the interval in `Retry-After`.",
            "headers": {
              "Retry-After": {
                "schema": {
                  "type": "integer"
                },
                "description": "Seconds to wait before retrying."
              },
              "X-RateLimit-Limit": {
                "schema": {
                  "type": "integer"
                }
              },
              "X-RateLimit-Remaining": {
                "schema": {
                  "type": "integer"
                }
              },
              "X-RateLimit-Reset": {
                "schema": {
                  "type": "integer"
                }
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                },
                "examples": {
                  "rateLimited": {
                    "$ref": "#/components/examples/ErrorRateLimited"
                  }
                }
              }
            }
          }
        },
        "deprecated": true,
        "description": "**RETIRED on 2025-11-22.** This endpoint returns HTTP 410 Gone. Use the ISO 20022 operations listed under Migration below.\n\nDEPRECATED: SWIFT MT messages are being decommissioned as part of the global ISO 20022 migration programme. This endpoint will be removed on 2025-11-22. Please migrate to the equivalent ISO 20022 MX message endpoints: /v1/standards/iso20022/pacs008/generate (replaces MT103) and /v1/standards/iso20022/camt053/parse (replaces MT940). \n\n**Migration:** Replace with `iso20022Camt053Parser`. Submit the equivalent ISO 20022 camt.053 statement.",
        "x-sunset": "2025-11-22",
        "x-replaced-by": "/v1/standards/iso20022/camt053/parse",
        "x-retired": true,
        "x-sunset-date": "2025-11-22",
        "x-successor": "/v1/standards/iso20022/camt053/parse",
        "x-replacement-endpoint": "/v1/standards/iso20022/camt053/parse",
        "parameters": [
          {
            "$ref": "#/components/parameters/RequestId"
          },
          {
            "$ref": "#/components/parameters/Traceparent"
          },
          {
            "$ref": "#/components/parameters/Tracestate"
          },
          {
            "$ref": "#/components/parameters/AcceptLanguage"
          }
        ],
        "x-codeSamples": [
          {
            "lang": "cURL",
            "label": "cURL",
            "source": "curl -X POST \"https://api.kangopenbanking.com/v1/standards/swift/mt940/parse\" \\\n  -H \"Authorization: Bearer $KOB_ACCESS_TOKEN\" \\\n  -H \"Content-Type: application/json\" \\\n  -d '{}'"
          },
          {
            "lang": "JavaScript",
            "label": "Node.js",
            "source": "import { KangOpenBanking } from \"@kangopenbanking/sdk\";\n\nconst kob = new KangOpenBanking({ apiKey: process.env.KOB_API_KEY });\nconst res = await kob.request(\"POST\", \"/v1/standards/swift/mt940/parse\", { /* payload */ });\nconsole.log(res);"
          },
          {
            "lang": "Python",
            "label": "Python",
            "source": "from kangopenbanking import KangOpenBanking\n\nkob = KangOpenBanking(api_key=os.environ[\"KOB_API_KEY\"])\nres = kob.request(\"POST\", \"/v1/standards/swift/mt940/parse\", json={})\nprint(res)"
          },
          {
            "lang": "PHP",
            "label": "PHP",
            "source": "<?php\n$kob = new KangOpenBanking\\KangOpenBanking(getenv('KOB_API_KEY'));\n$res = $kob->request('POST', '/v1/standards/swift/mt940/parse', []);\nprint_r($res);"
          }
        ],
        "x-replacement-operation-ids": [
          "iso20022Camt053Parser"
        ],
        "x-migration-guide": "Submit the equivalent ISO 20022 camt.053 statement."
      }
    },
    "/v1/standards/swift/mt103/generate": {
      "post": {
        "tags": [
          "Standards"
        ],
        "summary": "Generate MT103",
        "operationId": "swiftMt103Generator",
        "security": [
          {
            "bearerAuth": []
          }
        ],
        "parameters": [
          {
            "name": "Idempotency-Key",
            "in": "header",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid"
            },
            "description": "Required on all POST/PUT endpoints. Unique key for idempotent request processing (UUID v4 recommended). Keys expire after 24 hours."
          },
          {
            "$ref": "#/components/parameters/RequestId"
          },
          {
            "$ref": "#/components/parameters/Traceparent"
          },
          {
            "$ref": "#/components/parameters/Tracestate"
          },
          {
            "$ref": "#/components/parameters/AcceptLanguage"
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object"
              }
            }
          }
        },
        "responses": {
          "410": {
            "description": "Gone — use /v1/standards/iso20022/pacs008/generate",
            "headers": {
              "Sunset": {
                "schema": {
                  "type": "string"
                },
                "description": "RFC 8594 sunset date (2025-11-22)."
              },
              "Link": {
                "schema": {
                  "type": "string"
                },
                "description": "</v1/standards/iso20022/pacs008/generate>; rel=\"successor-version\""
              },
              "Deprecation": {
                "schema": {
                  "type": "string"
                },
                "description": "true"
              },
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/XRateLimitLimit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/XRateLimitRemaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/XRateLimitReset"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                },
                "example": {
                  "type": "https://api.kangopenbanking.com/v1/errors/endpoint-retired",
                  "title": "Endpoint Retired",
                  "status": 410,
                  "detail": "This endpoint was retired on 2025-11-22. Use /v1/standards/iso20022/pacs008/generate.",
                  "error_code": "DEPRECATED_ENDPOINT_RETIRED"
                }
              }
            }
          },
          "429": {
            "description": "Rate limit exceeded. Retry after the interval in `Retry-After`.",
            "headers": {
              "Retry-After": {
                "schema": {
                  "type": "integer"
                },
                "description": "Seconds to wait before retrying."
              },
              "X-RateLimit-Limit": {
                "schema": {
                  "type": "integer"
                }
              },
              "X-RateLimit-Remaining": {
                "schema": {
                  "type": "integer"
                }
              },
              "X-RateLimit-Reset": {
                "schema": {
                  "type": "integer"
                }
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                },
                "examples": {
                  "rateLimited": {
                    "$ref": "#/components/examples/ErrorRateLimited"
                  }
                }
              }
            }
          }
        },
        "deprecated": true,
        "description": "**RETIRED on 2025-11-22.** This endpoint returns HTTP 410 Gone. Use the ISO 20022 operations listed under Migration below.\n\nDEPRECATED: SWIFT MT messages are being decommissioned as part of the global ISO 20022 migration programme. This endpoint will be removed on 2025-11-22. Please migrate to the equivalent ISO 20022 MX message endpoints: /v1/standards/iso20022/pacs008/generate (replaces MT103) and /v1/standards/iso20022/camt053/parse (replaces MT940). \n\n**Migration:** Replace with `interbankPaymentCreate`. Create an interbank payment; ISO 20022 messages are produced server-side and listed by `interbankMessagesList`.",
        "x-sunset": "2025-11-22",
        "x-replaced-by": "/v1/standards/iso20022/pacs008/generate",
        "x-retired": true,
        "x-sunset-date": "2025-11-22",
        "x-successor": "/v1/standards/iso20022/pacs008/generate",
        "x-replacement-endpoint": "/v1/standards/iso20022/pacs008/generate",
        "x-codeSamples": [
          {
            "lang": "cURL",
            "label": "cURL",
            "source": "curl -X POST \"https://api.kangopenbanking.com/v1/standards/swift/mt103/generate\" \\\n  -H \"Authorization: Bearer $KOB_ACCESS_TOKEN\" \\\n  -H \"Content-Type: application/json\" \\\n  -d '{}'"
          },
          {
            "lang": "JavaScript",
            "label": "Node.js",
            "source": "import { KangOpenBanking } from \"@kangopenbanking/sdk\";\n\nconst kob = new KangOpenBanking({ apiKey: process.env.KOB_API_KEY });\nconst res = await kob.request(\"POST\", \"/v1/standards/swift/mt103/generate\", { /* payload */ });\nconsole.log(res);"
          },
          {
            "lang": "Python",
            "label": "Python",
            "source": "from kangopenbanking import KangOpenBanking\n\nkob = KangOpenBanking(api_key=os.environ[\"KOB_API_KEY\"])\nres = kob.request(\"POST\", \"/v1/standards/swift/mt103/generate\", json={})\nprint(res)"
          },
          {
            "lang": "PHP",
            "label": "PHP",
            "source": "<?php\n$kob = new KangOpenBanking\\KangOpenBanking(getenv('KOB_API_KEY'));\n$res = $kob->request('POST', '/v1/standards/swift/mt103/generate', []);\nprint_r($res);"
          }
        ],
        "x-replacement-operation-ids": [
          "interbankPaymentCreate"
        ],
        "x-migration-guide": "Create an interbank payment; ISO 20022 messages are produced server-side and listed by `interbankMessagesList`."
      }
    },
    "/v1/standards/validate/iban": {
      "post": {
        "tags": [
          "Standards"
        ],
        "summary": "Validate IBAN",
        "operationId": "validateIban",
        "security": [],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "required": [
                  "iban"
                ],
                "properties": {
                  "iban": {
                    "type": "string",
                    "example": "CM21 10003 00100 0123456789 023"
                  }
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Validation result",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "valid": {
                      "type": "boolean"
                    },
                    "iban": {
                      "type": "string"
                    },
                    "country": {
                      "type": "string"
                    },
                    "bank_code": {
                      "type": "string"
                    },
                    "errors": {
                      "type": "array",
                      "items": {
                        "type": "string"
                      }
                    }
                  }
                },
                "example": {
                  "valid": true,
                  "iban": "string",
                  "country": "string",
                  "bank_code": "string",
                  "errors": [
                    "string"
                  ]
                }
              }
            },
            "headers": {
              "x-fapi-interaction-id": {
                "$ref": "#/components/headers/XFapiInteractionIdResponse"
              },
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/XRateLimitLimit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/XRateLimitRemaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/XRateLimitReset"
              },
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              },
              "traceparent": {
                "$ref": "#/components/headers/Traceparent"
              },
              "Content-Language": {
                "$ref": "#/components/headers/Content-Language"
              }
            }
          },
          "400": {
            "description": "Bad request",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              },
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                },
                "examples": {
                  "error": {
                    "$ref": "#/components/examples/ErrorBadRequest"
                  }
                }
              }
            },
            "headers": {
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/XRateLimitLimit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/XRateLimitRemaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/XRateLimitReset"
              },
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "403": {
            "$ref": "#/components/responses/Forbidden",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "404": {
            "$ref": "#/components/responses/NotFound",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "409": {
            "$ref": "#/components/responses/Conflict",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "429": {
            "$ref": "#/components/responses/TooManyRequests",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "500": {
            "$ref": "#/components/responses/InternalServerError",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          }
        },
        "parameters": [
          {
            "$ref": "#/components/parameters/RequestId"
          },
          {
            "$ref": "#/components/parameters/Traceparent"
          },
          {
            "$ref": "#/components/parameters/Tracestate"
          },
          {
            "$ref": "#/components/parameters/AcceptLanguage"
          }
        ],
        "x-codeSamples": [
          {
            "lang": "cURL",
            "label": "cURL",
            "source": "curl -X POST \"https://api.kangopenbanking.com/v1/standards/validate/iban\" \\\n  -H \"Authorization: Bearer $KOB_ACCESS_TOKEN\" \\\n  -H \"Content-Type: application/json\" \\\n  -d '{}'"
          },
          {
            "lang": "JavaScript",
            "label": "Node.js",
            "source": "import { KangOpenBanking } from \"@kangopenbanking/sdk\";\n\nconst kob = new KangOpenBanking({ apiKey: process.env.KOB_API_KEY });\nconst res = await kob.request(\"POST\", \"/v1/standards/validate/iban\", { /* payload */ });\nconsole.log(res);"
          },
          {
            "lang": "Python",
            "label": "Python",
            "source": "from kangopenbanking import KangOpenBanking\n\nkob = KangOpenBanking(api_key=os.environ[\"KOB_API_KEY\"])\nres = kob.request(\"POST\", \"/v1/standards/validate/iban\", json={})\nprint(res)"
          },
          {
            "lang": "PHP",
            "label": "PHP",
            "source": "<?php\n$kob = new KangOpenBanking\\KangOpenBanking(getenv('KOB_API_KEY'));\n$res = $kob->request('POST', '/v1/standards/validate/iban', []);\nprint_r($res);"
          }
        ]
      }
    },
    "/v1/standards/validate/bic": {
      "post": {
        "tags": [
          "Standards"
        ],
        "summary": "Validate BIC/SWIFT code",
        "operationId": "validateBic",
        "security": [],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "required": [
                  "bic"
                ],
                "properties": {
                  "bic": {
                    "type": "string"
                  }
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Validation result",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "valid": {
                      "type": "boolean"
                    },
                    "bic": {
                      "type": "string"
                    },
                    "institution": {
                      "type": "string"
                    },
                    "country": {
                      "type": "string"
                    },
                    "errors": {
                      "type": "array",
                      "items": {
                        "type": "string"
                      }
                    }
                  }
                },
                "example": {
                  "valid": true,
                  "bic": "string",
                  "institution": "string",
                  "country": "string",
                  "errors": [
                    "string"
                  ]
                }
              }
            },
            "headers": {
              "x-fapi-interaction-id": {
                "$ref": "#/components/headers/XFapiInteractionIdResponse"
              },
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/XRateLimitLimit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/XRateLimitRemaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/XRateLimitReset"
              },
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              },
              "traceparent": {
                "$ref": "#/components/headers/Traceparent"
              },
              "Content-Language": {
                "$ref": "#/components/headers/Content-Language"
              }
            }
          },
          "400": {
            "description": "Bad request",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              },
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                },
                "examples": {
                  "error": {
                    "$ref": "#/components/examples/ErrorBadRequest"
                  }
                }
              }
            },
            "headers": {
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/XRateLimitLimit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/XRateLimitRemaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/XRateLimitReset"
              },
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "403": {
            "$ref": "#/components/responses/Forbidden",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "404": {
            "$ref": "#/components/responses/NotFound",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "409": {
            "$ref": "#/components/responses/Conflict",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "429": {
            "$ref": "#/components/responses/TooManyRequests",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "500": {
            "$ref": "#/components/responses/InternalServerError",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          }
        },
        "parameters": [
          {
            "$ref": "#/components/parameters/RequestId"
          },
          {
            "$ref": "#/components/parameters/Traceparent"
          },
          {
            "$ref": "#/components/parameters/Tracestate"
          },
          {
            "$ref": "#/components/parameters/AcceptLanguage"
          }
        ],
        "x-codeSamples": [
          {
            "lang": "cURL",
            "label": "cURL",
            "source": "curl -X POST \"https://api.kangopenbanking.com/v1/standards/validate/bic\" \\\n  -H \"Authorization: Bearer $KOB_ACCESS_TOKEN\" \\\n  -H \"Content-Type: application/json\" \\\n  -d '{}'"
          },
          {
            "lang": "JavaScript",
            "label": "Node.js",
            "source": "import { KangOpenBanking } from \"@kangopenbanking/sdk\";\n\nconst kob = new KangOpenBanking({ apiKey: process.env.KOB_API_KEY });\nconst res = await kob.request(\"POST\", \"/v1/standards/validate/bic\", { /* payload */ });\nconsole.log(res);"
          },
          {
            "lang": "Python",
            "label": "Python",
            "source": "from kangopenbanking import KangOpenBanking\n\nkob = KangOpenBanking(api_key=os.environ[\"KOB_API_KEY\"])\nres = kob.request(\"POST\", \"/v1/standards/validate/bic\", json={})\nprint(res)"
          },
          {
            "lang": "PHP",
            "label": "PHP",
            "source": "<?php\n$kob = new KangOpenBanking\\KangOpenBanking(getenv('KOB_API_KEY'));\n$res = $kob->request('POST', '/v1/standards/validate/bic', []);\nprint_r($res);"
          }
        ]
      }
    },
    "/v1/standards/validate/rib": {
      "post": {
        "tags": [
          "Standards"
        ],
        "summary": "Validate Cameroon Domestic RIB",
        "operationId": "validateRib",
        "security": [],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "required": [
                  "rib"
                ],
                "properties": {
                  "rib": {
                    "type": "string",
                    "example": "10005001000123456789023",
                    "description": "23-digit Cameroon domestic RIB/BBAN"
                  },
                  "country": {
                    "type": "string",
                    "default": "CM"
                  }
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "RIB validation result with structured fields (bank_code, branch_code, account_number, rib_key), derived IBAN, and bank lookup",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "valid": {
                      "type": "boolean"
                    },
                    "bank_code": {
                      "type": "string",
                      "example": "10005"
                    },
                    "branch_code": {
                      "type": "string",
                      "example": "00100"
                    },
                    "account_number": {
                      "type": "string",
                      "example": "01234567890"
                    },
                    "rib_key": {
                      "type": "string",
                      "example": "23"
                    },
                    "bank_name": {
                      "type": "string",
                      "example": "Afriland First Bank"
                    },
                    "swift_bic": {
                      "type": "string",
                      "example": "AFRIACMCXXX"
                    },
                    "derived_iban": {
                      "type": "string",
                      "example": "CM21 1000 5001 0001 2345 6789 023"
                    },
                    "formatted_display": {
                      "type": "string",
                      "example": "10005-00100-01234567890-23"
                    },
                    "errors": {
                      "type": "array",
                      "items": {
                        "type": "string"
                      }
                    }
                  }
                },
                "example": {
                  "valid": true,
                  "bank_code": "10005",
                  "branch_code": "00100",
                  "account_number": "01234567890",
                  "rib_key": "23",
                  "bank_name": "Afriland First Bank",
                  "swift_bic": "AFRIACMCXXX",
                  "derived_iban": "CM21 1000 5001 0001 2345 6789 023",
                  "formatted_display": "10005-00100-01234567890-23",
                  "errors": [
                    "string"
                  ]
                }
              }
            },
            "headers": {
              "x-fapi-interaction-id": {
                "$ref": "#/components/headers/XFapiInteractionIdResponse"
              },
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/XRateLimitLimit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/XRateLimitRemaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/XRateLimitReset"
              },
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              },
              "traceparent": {
                "$ref": "#/components/headers/Traceparent"
              },
              "Content-Language": {
                "$ref": "#/components/headers/Content-Language"
              }
            }
          },
          "400": {
            "description": "Bad request",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              },
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                },
                "examples": {
                  "error": {
                    "$ref": "#/components/examples/ErrorBadRequest"
                  }
                }
              }
            },
            "headers": {
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/XRateLimitLimit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/XRateLimitRemaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/XRateLimitReset"
              },
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "403": {
            "$ref": "#/components/responses/Forbidden",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "404": {
            "$ref": "#/components/responses/NotFound",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "409": {
            "$ref": "#/components/responses/Conflict",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "429": {
            "$ref": "#/components/responses/TooManyRequests",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "500": {
            "$ref": "#/components/responses/InternalServerError",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          }
        },
        "parameters": [
          {
            "$ref": "#/components/parameters/RequestId"
          },
          {
            "$ref": "#/components/parameters/Traceparent"
          },
          {
            "$ref": "#/components/parameters/Tracestate"
          },
          {
            "$ref": "#/components/parameters/AcceptLanguage"
          }
        ],
        "x-codeSamples": [
          {
            "lang": "cURL",
            "label": "cURL",
            "source": "curl -X POST \"https://api.kangopenbanking.com/v1/standards/validate/rib\" \\\n  -H \"Authorization: Bearer $KOB_ACCESS_TOKEN\" \\\n  -H \"Content-Type: application/json\" \\\n  -d '{}'"
          },
          {
            "lang": "JavaScript",
            "label": "Node.js",
            "source": "import { KangOpenBanking } from \"@kangopenbanking/sdk\";\n\nconst kob = new KangOpenBanking({ apiKey: process.env.KOB_API_KEY });\nconst res = await kob.request(\"POST\", \"/v1/standards/validate/rib\", { /* payload */ });\nconsole.log(res);"
          },
          {
            "lang": "Python",
            "label": "Python",
            "source": "from kangopenbanking import KangOpenBanking\n\nkob = KangOpenBanking(api_key=os.environ[\"KOB_API_KEY\"])\nres = kob.request(\"POST\", \"/v1/standards/validate/rib\", json={})\nprint(res)"
          },
          {
            "lang": "PHP",
            "label": "PHP",
            "source": "<?php\n$kob = new KangOpenBanking\\KangOpenBanking(getenv('KOB_API_KEY'));\n$res = $kob->request('POST', '/v1/standards/validate/rib', []);\nprint_r($res);"
          }
        ]
      }
    },
    "/v1/standards/validate/account-identifier": {
      "post": {
        "tags": [
          "Standards"
        ],
        "summary": "Validate any account identifier (RIB, IBAN, LOCAL_BANK, MOMO)",
        "operationId": "validateAccountIdentifier",
        "security": [],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "required": [
                  "type",
                  "value"
                ],
                "properties": {
                  "type": {
                    "type": "string",
                    "enum": [
                      "DOMESTIC_RIB",
                      "IBAN",
                      "LOCAL_BANK",
                      "MOMO"
                    ]
                  },
                  "value": {
                    "type": "string"
                  },
                  "country": {
                    "type": "string",
                    "default": "CM"
                  }
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Unified validation result with rail determination",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "valid": {
                      "type": "boolean"
                    },
                    "identifier_type": {
                      "type": "string",
                      "enum": [
                        "DOMESTIC_RIB",
                        "IBAN",
                        "LOCAL_BANK",
                        "MOMO"
                      ]
                    },
                    "rail": {
                      "type": "string",
                      "enum": [
                        "DOMESTIC",
                        "INTERNATIONAL",
                        "LOCAL"
                      ]
                    },
                    "normalized_value": {
                      "type": "string"
                    },
                    "display": {
                      "type": "string"
                    },
                    "country": {
                      "type": "string"
                    },
                    "errors": {
                      "type": "array",
                      "items": {
                        "type": "string"
                      }
                    }
                  }
                },
                "example": {
                  "valid": true,
                  "identifier_type": "DOMESTIC_RIB",
                  "rail": "DOMESTIC",
                  "normalized_value": "string",
                  "display": "string",
                  "country": "string",
                  "errors": [
                    "string"
                  ]
                }
              }
            },
            "headers": {
              "x-fapi-interaction-id": {
                "$ref": "#/components/headers/XFapiInteractionIdResponse"
              },
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/XRateLimitLimit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/XRateLimitRemaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/XRateLimitReset"
              },
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              },
              "traceparent": {
                "$ref": "#/components/headers/Traceparent"
              },
              "Content-Language": {
                "$ref": "#/components/headers/Content-Language"
              }
            }
          },
          "400": {
            "description": "Bad request",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              },
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                },
                "examples": {
                  "error": {
                    "$ref": "#/components/examples/ErrorBadRequest"
                  }
                }
              }
            },
            "headers": {
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/XRateLimitLimit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/XRateLimitRemaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/XRateLimitReset"
              },
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "403": {
            "$ref": "#/components/responses/Forbidden",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "404": {
            "$ref": "#/components/responses/NotFound",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "409": {
            "$ref": "#/components/responses/Conflict",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "429": {
            "$ref": "#/components/responses/TooManyRequests",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "500": {
            "$ref": "#/components/responses/InternalServerError",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          }
        },
        "parameters": [
          {
            "$ref": "#/components/parameters/RequestId"
          },
          {
            "$ref": "#/components/parameters/Traceparent"
          },
          {
            "$ref": "#/components/parameters/Tracestate"
          },
          {
            "$ref": "#/components/parameters/AcceptLanguage"
          }
        ],
        "x-codeSamples": [
          {
            "lang": "cURL",
            "label": "cURL",
            "source": "curl -X POST \"https://api.kangopenbanking.com/v1/standards/validate/account-identifier\" \\\n  -H \"Authorization: Bearer $KOB_ACCESS_TOKEN\" \\\n  -H \"Content-Type: application/json\" \\\n  -d '{}'"
          },
          {
            "lang": "JavaScript",
            "label": "Node.js",
            "source": "import { KangOpenBanking } from \"@kangopenbanking/sdk\";\n\nconst kob = new KangOpenBanking({ apiKey: process.env.KOB_API_KEY });\nconst res = await kob.request(\"POST\", \"/v1/standards/validate/account-identifier\", { /* payload */ });\nconsole.log(res);"
          },
          {
            "lang": "Python",
            "label": "Python",
            "source": "from kangopenbanking import KangOpenBanking\n\nkob = KangOpenBanking(api_key=os.environ[\"KOB_API_KEY\"])\nres = kob.request(\"POST\", \"/v1/standards/validate/account-identifier\", json={})\nprint(res)"
          },
          {
            "lang": "PHP",
            "label": "PHP",
            "source": "<?php\n$kob = new KangOpenBanking\\KangOpenBanking(getenv('KOB_API_KEY'));\n$res = $kob->request('POST', '/v1/standards/validate/account-identifier', []);\nprint_r($res);"
          }
        ]
      }
    },
    "/v1/directory/banks/cm": {
      "get": {
        "tags": [
          "Directory"
        ],
        "summary": "List Cameroon banks with RIB structure and SWIFT codes",
        "operationId": "directoryBanksCm",
        "security": [],
        "responses": {
          "200": {
            "description": "Cameroon bank directory",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "country": {
                      "type": "string"
                    },
                    "banks": {
                      "type": "array",
                      "items": {
                        "type": "object",
                        "properties": {
                          "bank_code": {
                            "type": "string"
                          },
                          "bank_name": {
                            "type": "string"
                          },
                          "swift_bic": {
                            "type": "string"
                          },
                          "supports_rib": {
                            "type": "boolean"
                          }
                        }
                      }
                    }
                  }
                },
                "example": {
                  "country": "string",
                  "banks": [
                    {
                      "bank_code": "string",
                      "bank_name": "string",
                      "swift_bic": "string",
                      "supports_rib": true
                    }
                  ]
                }
              }
            },
            "headers": {
              "x-fapi-interaction-id": {
                "$ref": "#/components/headers/XFapiInteractionIdResponse"
              },
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/XRateLimitLimit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/XRateLimitRemaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/XRateLimitReset"
              },
              "Cache-Control": {
                "$ref": "#/components/headers/CacheControl"
              },
              "ETag": {
                "$ref": "#/components/headers/ETag"
              },
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              },
              "traceparent": {
                "$ref": "#/components/headers/Traceparent"
              },
              "Content-Language": {
                "$ref": "#/components/headers/Content-Language"
              }
            }
          },
          "429": {
            "$ref": "#/components/responses/TooManyRequests",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "default": {
            "description": "Server error — see ProblemDetails for trace ID.",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            },
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/XRateLimitLimit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/XRateLimitRemaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/XRateLimitReset"
              }
            }
          }
        },
        "parameters": [
          {
            "$ref": "#/components/parameters/RequestId"
          },
          {
            "$ref": "#/components/parameters/Traceparent"
          },
          {
            "$ref": "#/components/parameters/Tracestate"
          },
          {
            "$ref": "#/components/parameters/AcceptLanguage"
          }
        ],
        "x-codeSamples": [
          {
            "lang": "cURL",
            "label": "cURL",
            "source": "curl -X GET \"https://api.kangopenbanking.com/v1/directory/banks/cm\" \\\n  -H \"Authorization: Bearer $KOB_ACCESS_TOKEN\" \\\n  -H \"Content-Type: application/json\""
          },
          {
            "lang": "JavaScript",
            "label": "Node.js",
            "source": "import { KangOpenBanking } from \"@kangopenbanking/sdk\";\n\nconst kob = new KangOpenBanking({ apiKey: process.env.KOB_API_KEY });\nconst res = await kob.request(\"GET\", \"/v1/directory/banks/cm\");\nconsole.log(res);"
          },
          {
            "lang": "Python",
            "label": "Python",
            "source": "from kangopenbanking import KangOpenBanking\n\nkob = KangOpenBanking(api_key=os.environ[\"KOB_API_KEY\"])\nres = kob.request(\"GET\", \"/v1/directory/banks/cm\")\nprint(res)"
          },
          {
            "lang": "PHP",
            "label": "PHP",
            "source": "<?php\n$kob = new KangOpenBanking\\KangOpenBanking(getenv('KOB_API_KEY'));\n$res = $kob->request('GET', '/v1/directory/banks/cm');\nprint_r($res);"
          }
        ]
      }
    },
    "/v1/kyc/submit": {
      "post": {
        "tags": [
          "KYC & Compliance"
        ],
        "summary": "Submit KYC documents",
        "operationId": "kycSubmit",
        "security": [
          {
            "bearerAuth": []
          }
        ],
        "parameters": [
          {
            "name": "Idempotency-Key",
            "in": "header",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid"
            },
            "description": "Required on all POST/PUT endpoints. Unique key for idempotent request processing (UUID v4 recommended). Keys expire after 24 hours."
          },
          {
            "$ref": "#/components/parameters/RequestId"
          },
          {
            "$ref": "#/components/parameters/Traceparent"
          },
          {
            "$ref": "#/components/parameters/Tracestate"
          },
          {
            "$ref": "#/components/parameters/AcceptLanguage"
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "required": [
                  "document_type",
                  "document_number",
                  "date_of_birth",
                  "nationality"
                ],
                "properties": {
                  "document_type": {
                    "type": "string",
                    "enum": [
                      "national_id",
                      "passport",
                      "drivers_license"
                    ]
                  },
                  "document_number": {
                    "type": "string"
                  },
                  "document_front_url": {
                    "type": "string"
                  },
                  "document_back_url": {
                    "type": "string"
                  },
                  "selfie_url": {
                    "type": "string",
                    "format": "uri",
                    "description": "URL of the selfie image captured during liveness check. Required for Tier 2 and above CDD."
                  },
                  "liveness_check_token": {
                    "type": "string",
                    "description": "Token returned by the liveness detection provider confirming a real person was captured."
                  },
                  "date_of_birth": {
                    "type": "string",
                    "format": "date",
                    "description": "Customer date of birth in ISO 8601 format. Required for PEP and sanctions screening age correlation.",
                    "example": "1985-06-15"
                  },
                  "nationality": {
                    "type": "string",
                    "maxLength": 2,
                    "description": "ISO 3166-1 alpha-2 nationality code. Required for jurisdictional risk assessment.",
                    "example": "CM"
                  },
                  "tax_identification_number": {
                    "type": "string",
                    "description": "Customer Tax Identification Number (TIN / NIU in Cameroon). Required under COBAC CDD obligations.",
                    "example": "P123456789"
                  },
                  "address_proof_url": {
                    "type": "string",
                    "format": "uri",
                    "description": "URL of supporting address verification document (utility bill, bank statement, etc.)."
                  },
                  "residential_address": {
                    "type": "object",
                    "description": "Customer's current residential address",
                    "properties": {
                      "street_line1": {
                        "type": "string"
                      },
                      "street_line2": {
                        "type": "string"
                      },
                      "city": {
                        "type": "string"
                      },
                      "region": {
                        "type": "string"
                      },
                      "postal_code": {
                        "type": "string"
                      },
                      "country": {
                        "type": "string",
                        "maxLength": 2,
                        "description": "ISO 3166-1 alpha-2 country code"
                      }
                    },
                    "required": [
                      "street_line1",
                      "city",
                      "country"
                    ]
                  }
                }
              }
            }
          }
        },
        "responses": {
          "201": {
            "description": "KYC submitted",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "success": {
                      "type": "boolean",
                      "example": true
                    },
                    "message": {
                      "type": "string"
                    }
                  }
                },
                "example": {
                  "success": true,
                  "message": "string"
                }
              }
            },
            "headers": {
              "x-fapi-interaction-id": {
                "$ref": "#/components/headers/XFapiInteractionIdResponse"
              },
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/XRateLimitLimit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/XRateLimitRemaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/XRateLimitReset"
              },
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              },
              "traceparent": {
                "$ref": "#/components/headers/Traceparent"
              },
              "Content-Language": {
                "$ref": "#/components/headers/Content-Language"
              }
            }
          },
          "400": {
            "description": "Bad request",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              },
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                },
                "examples": {
                  "error": {
                    "$ref": "#/components/examples/ErrorBadRequest"
                  }
                }
              }
            },
            "headers": {
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/XRateLimitLimit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/XRateLimitRemaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/XRateLimitReset"
              },
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "403": {
            "$ref": "#/components/responses/Forbidden",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "404": {
            "$ref": "#/components/responses/NotFound",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "409": {
            "$ref": "#/components/responses/Conflict",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "429": {
            "$ref": "#/components/responses/TooManyRequests",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "500": {
            "$ref": "#/components/responses/InternalServerError",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          }
        },
        "x-codeSamples": [
          {
            "lang": "cURL",
            "label": "cURL",
            "source": "curl -X POST \"https://api.kangopenbanking.com/v1/kyc/submit\" \\\n  -H \"Authorization: Bearer $KOB_ACCESS_TOKEN\" \\\n  -H \"Content-Type: application/json\" \\\n  -d '{}'"
          },
          {
            "lang": "JavaScript",
            "label": "Node.js",
            "source": "import { KangOpenBanking } from \"@kangopenbanking/sdk\";\n\nconst kob = new KangOpenBanking({ apiKey: process.env.KOB_API_KEY });\nconst res = await kob.request(\"POST\", \"/v1/kyc/submit\", { /* payload */ });\nconsole.log(res);"
          },
          {
            "lang": "Python",
            "label": "Python",
            "source": "from kangopenbanking import KangOpenBanking\n\nkob = KangOpenBanking(api_key=os.environ[\"KOB_API_KEY\"])\nres = kob.request(\"POST\", \"/v1/kyc/submit\", json={})\nprint(res)"
          },
          {
            "lang": "PHP",
            "label": "PHP",
            "source": "<?php\n$kob = new KangOpenBanking\\KangOpenBanking(getenv('KOB_API_KEY'));\n$res = $kob->request('POST', '/v1/kyc/submit', []);\nprint_r($res);"
          }
        ]
      }
    },
    "/v1/kyc/sanctions-screen": {
      "post": {
        "tags": [
          "KYC & Compliance"
        ],
        "summary": "Sanctions screening",
        "operationId": "sanctionsScreen",
        "security": [
          {
            "bearerAuth": []
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "required": [
                  "full_name"
                ],
                "properties": {
                  "full_name": {
                    "type": "string"
                  },
                  "date_of_birth": {
                    "type": "string",
                    "format": "date"
                  },
                  "nationality": {
                    "type": "string"
                  }
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Screening result",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "match_found": {
                      "type": "boolean"
                    },
                    "matches": {
                      "type": "array",
                      "items": {
                        "type": "object"
                      }
                    },
                    "screened_at": {
                      "type": "string",
                      "format": "date-time"
                    }
                  }
                },
                "example": {
                  "match_found": true,
                  "matches": [
                    {}
                  ],
                  "screened_at": "2026-01-01T00:00:00Z"
                }
              }
            },
            "headers": {
              "x-fapi-interaction-id": {
                "$ref": "#/components/headers/XFapiInteractionIdResponse"
              },
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/XRateLimitLimit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/XRateLimitRemaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/XRateLimitReset"
              },
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              },
              "traceparent": {
                "$ref": "#/components/headers/Traceparent"
              },
              "Content-Language": {
                "$ref": "#/components/headers/Content-Language"
              }
            }
          },
          "400": {
            "description": "Bad request",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              },
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                },
                "examples": {
                  "error": {
                    "$ref": "#/components/examples/ErrorBadRequest"
                  }
                }
              }
            },
            "headers": {
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/XRateLimitLimit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/XRateLimitRemaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/XRateLimitReset"
              },
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "403": {
            "$ref": "#/components/responses/Forbidden",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "404": {
            "$ref": "#/components/responses/NotFound",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "409": {
            "$ref": "#/components/responses/Conflict",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "429": {
            "$ref": "#/components/responses/TooManyRequests",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "500": {
            "$ref": "#/components/responses/InternalServerError",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          }
        },
        "parameters": [
          {
            "$ref": "#/components/parameters/RequestId"
          },
          {
            "$ref": "#/components/parameters/Traceparent"
          },
          {
            "$ref": "#/components/parameters/Tracestate"
          },
          {
            "$ref": "#/components/parameters/AcceptLanguage"
          }
        ],
        "x-codeSamples": [
          {
            "lang": "cURL",
            "label": "cURL",
            "source": "curl -X POST \"https://api.kangopenbanking.com/v1/kyc/sanctions-screen\" \\\n  -H \"Authorization: Bearer $KOB_ACCESS_TOKEN\" \\\n  -H \"Content-Type: application/json\" \\\n  -d '{}'"
          },
          {
            "lang": "JavaScript",
            "label": "Node.js",
            "source": "import { KangOpenBanking } from \"@kangopenbanking/sdk\";\n\nconst kob = new KangOpenBanking({ apiKey: process.env.KOB_API_KEY });\nconst res = await kob.request(\"POST\", \"/v1/kyc/sanctions-screen\", { /* payload */ });\nconsole.log(res);"
          },
          {
            "lang": "Python",
            "label": "Python",
            "source": "from kangopenbanking import KangOpenBanking\n\nkob = KangOpenBanking(api_key=os.environ[\"KOB_API_KEY\"])\nres = kob.request(\"POST\", \"/v1/kyc/sanctions-screen\", json={})\nprint(res)"
          },
          {
            "lang": "PHP",
            "label": "PHP",
            "source": "<?php\n$kob = new KangOpenBanking\\KangOpenBanking(getenv('KOB_API_KEY'));\n$res = $kob->request('POST', '/v1/kyc/sanctions-screen', []);\nprint_r($res);"
          }
        ]
      }
    },
    "/v1/kyc/data-export": {
      "get": {
        "tags": [
          "KYC & Compliance"
        ],
        "summary": "Export personal data (GDPR)",
        "operationId": "dataExport",
        "security": [
          {
            "bearerAuth": []
          }
        ],
        "responses": {
          "200": {
            "description": "User data export",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "user": {
                      "type": "object"
                    },
                    "accounts": {
                      "type": "array",
                      "items": {
                        "type": "object"
                      }
                    },
                    "transactions": {
                      "type": "array",
                      "items": {
                        "type": "object"
                      }
                    }
                  }
                },
                "example": {
                  "user": {},
                  "accounts": [
                    {}
                  ],
                  "transactions": [
                    {}
                  ]
                }
              }
            },
            "headers": {
              "x-fapi-interaction-id": {
                "$ref": "#/components/headers/XFapiInteractionIdResponse"
              },
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/XRateLimitLimit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/XRateLimitRemaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/XRateLimitReset"
              },
              "Cache-Control": {
                "$ref": "#/components/headers/CacheControl"
              },
              "ETag": {
                "$ref": "#/components/headers/ETag"
              },
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              },
              "traceparent": {
                "$ref": "#/components/headers/Traceparent"
              },
              "Content-Language": {
                "$ref": "#/components/headers/Content-Language"
              }
            }
          },
          "400": {
            "description": "Bad request",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              },
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                },
                "examples": {
                  "error": {
                    "$ref": "#/components/examples/ErrorBadRequest"
                  }
                }
              }
            },
            "headers": {
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/XRateLimitLimit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/XRateLimitRemaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/XRateLimitReset"
              },
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "403": {
            "$ref": "#/components/responses/Forbidden",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "404": {
            "$ref": "#/components/responses/NotFound",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "409": {
            "$ref": "#/components/responses/Conflict",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "429": {
            "$ref": "#/components/responses/TooManyRequests",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "500": {
            "$ref": "#/components/responses/InternalServerError",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          }
        },
        "parameters": [
          {
            "$ref": "#/components/parameters/PageParam"
          },
          {
            "$ref": "#/components/parameters/LimitParam"
          },
          {
            "$ref": "#/components/parameters/CursorParam"
          },
          {
            "$ref": "#/components/parameters/RequestId"
          },
          {
            "$ref": "#/components/parameters/Traceparent"
          },
          {
            "$ref": "#/components/parameters/Tracestate"
          },
          {
            "$ref": "#/components/parameters/AcceptLanguage"
          }
        ],
        "x-codeSamples": [
          {
            "lang": "cURL",
            "label": "cURL",
            "source": "curl -X GET \"https://api.kangopenbanking.com/v1/kyc/data-export\" \\\n  -H \"Authorization: Bearer $KOB_ACCESS_TOKEN\" \\\n  -H \"Content-Type: application/json\""
          },
          {
            "lang": "JavaScript",
            "label": "Node.js",
            "source": "import { KangOpenBanking } from \"@kangopenbanking/sdk\";\n\nconst kob = new KangOpenBanking({ apiKey: process.env.KOB_API_KEY });\nconst res = await kob.request(\"GET\", \"/v1/kyc/data-export\");\nconsole.log(res);"
          },
          {
            "lang": "Python",
            "label": "Python",
            "source": "from kangopenbanking import KangOpenBanking\n\nkob = KangOpenBanking(api_key=os.environ[\"KOB_API_KEY\"])\nres = kob.request(\"GET\", \"/v1/kyc/data-export\")\nprint(res)"
          },
          {
            "lang": "PHP",
            "label": "PHP",
            "source": "<?php\n$kob = new KangOpenBanking\\KangOpenBanking(getenv('KOB_API_KEY'));\n$res = $kob->request('GET', '/v1/kyc/data-export');\nprint_r($res);"
          }
        ]
      }
    },
    "/v1/webhooks": {
      "post": {
        "tags": [
          "Webhooks"
        ],
        "summary": "Register webhook",
        "operationId": "webhookRegister",
        "security": [
          {
            "bearerAuth": []
          }
        ],
        "parameters": [
          {
            "name": "Idempotency-Key",
            "in": "header",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid"
            },
            "description": "Required on all POST/PUT endpoints. Unique key for idempotent request processing (UUID v4 recommended). Keys expire after 24 hours."
          },
          {
            "$ref": "#/components/parameters/RequestId"
          },
          {
            "$ref": "#/components/parameters/Traceparent"
          },
          {
            "$ref": "#/components/parameters/Tracestate"
          },
          {
            "$ref": "#/components/parameters/AcceptLanguage"
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "required": [
                  "url",
                  "events"
                ],
                "properties": {
                  "url": {
                    "type": "string",
                    "format": "uri"
                  },
                  "events": {
                    "type": "array",
                    "items": {
                      "type": "string",
                      "enum": [
                        "wildcard.*",
                        "charge.created",
                        "charge.captured",
                        "charge.voided",
                        "charge.failed",
                        "charge.cancelled",
                        "refund.created",
                        "refund.processed",
                        "refund.failed",
                        "payout.created",
                        "payout.processing",
                        "payout.completed",
                        "payout.failed",
                        "payment.initiated",
                        "payment.authorised",
                        "payment.submitted",
                        "payment.completed",
                        "payment.rejected",
                        "payment.cancelled",
                        "dispute.created",
                        "dispute.evidence_required",
                        "dispute.resolved",
                        "settlement.created",
                        "settlement.processed",
                        "consent.authorised",
                        "consent.revoked",
                        "consent.expired",
                        "loan.applied",
                        "loan.approved",
                        "loan.disbursed",
                        "loan.repaid",
                        "loan.defaulted",
                        "kyc.submitted",
                        "kyc.approved",
                        "kyc.rejected",
                        "mobile_money.charge_initiated",
                        "mobile_money.charge_completed",
                        "mobile_money.charge_failed",
                        "escrow.funded",
                        "escrow.released",
                        "escrow.refunded",
                        "virtual_account.credited",
                        "interbank.payment_submitted",
                        "interbank.payment_completed",
                        "interbank.payment_returned",
                        "pay_by_bank.intent_authorised",
                        "pay_by_bank.intent_rejected",
                        "pay_by_bank.payment_completed",
                        "subscription.created",
                        "subscription.renewed",
                        "subscription.cancelled",
                        "subscription.payment_failed"
                      ]
                    },
                    "description": "List of event types to subscribe to. Use 'wildcard.*' to subscribe to all events.",
                    "minItems": 1,
                    "example": [
                      "charge.created",
                      "charge.captured",
                      "refund.created"
                    ]
                  },
                  "secret": {
                    "type": "string"
                  }
                }
              }
            }
          }
        },
        "responses": {
          "201": {
            "description": "Webhook registered",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Webhook"
                },
                "example": {
                  "webhook_id": "00000000-0000-4000-8000-000000000000",
                  "url": "https://api.kangopenbanking.com",
                  "events": [
                    {
                      "id": "evt_a1b2c3d4-e5f6-7890-abcd-ef1234567890",
                      "event": "charge.created",
                      "created_at": "2025-03-27T14:32:00Z",
                      "api_version": "4.6.0",
                      "data": {}
                    }
                  ],
                  "is_active": true,
                  "secret": "string"
                }
              }
            },
            "headers": {
              "x-fapi-interaction-id": {
                "$ref": "#/components/headers/XFapiInteractionIdResponse"
              },
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/XRateLimitLimit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/XRateLimitRemaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/XRateLimitReset"
              },
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              },
              "traceparent": {
                "$ref": "#/components/headers/Traceparent"
              },
              "Content-Language": {
                "$ref": "#/components/headers/Content-Language"
              }
            }
          },
          "400": {
            "description": "Bad request",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              },
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                },
                "examples": {
                  "error": {
                    "$ref": "#/components/examples/ErrorBadRequest"
                  }
                }
              }
            },
            "headers": {
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/XRateLimitLimit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/XRateLimitRemaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/XRateLimitReset"
              },
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "403": {
            "$ref": "#/components/responses/Forbidden",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "404": {
            "$ref": "#/components/responses/NotFound",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "409": {
            "$ref": "#/components/responses/Conflict",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "429": {
            "$ref": "#/components/responses/TooManyRequests",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "500": {
            "$ref": "#/components/responses/InternalServerError",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          }
        },
        "deprecated": true,
        "x-sunset-date": "2026-12-31",
        "x-successor": "/v1/webhooks/v2/endpoints",
        "x-codeSamples": [
          {
            "lang": "cURL",
            "label": "cURL",
            "source": "curl -X POST \"https://api.kangopenbanking.com/v1/webhooks\" \\\n  -H \"Authorization: Bearer $KOB_ACCESS_TOKEN\" \\\n  -H \"Content-Type: application/json\" \\\n  -d '{}'"
          },
          {
            "lang": "JavaScript",
            "label": "Node.js",
            "source": "import { KangOpenBanking } from \"@kangopenbanking/sdk\";\n\nconst kob = new KangOpenBanking({ apiKey: process.env.KOB_API_KEY });\nconst res = await kob.request(\"POST\", \"/v1/webhooks\", { /* payload */ });\nconsole.log(res);"
          },
          {
            "lang": "Python",
            "label": "Python",
            "source": "from kangopenbanking import KangOpenBanking\n\nkob = KangOpenBanking(api_key=os.environ[\"KOB_API_KEY\"])\nres = kob.request(\"POST\", \"/v1/webhooks\", json={})\nprint(res)"
          },
          {
            "lang": "PHP",
            "label": "PHP",
            "source": "<?php\n$kob = new KangOpenBanking\\KangOpenBanking(getenv('KOB_API_KEY'));\n$res = $kob->request('POST', '/v1/webhooks', []);\nprint_r($res);"
          }
        ],
        "description": "**Deprecated.** Use Webhooks v2 (`/v1/webhooks/v2/endpoints`). Sunset: 2026-12-31.\n\nRegister webhook.\n\n**Tag:** Webhooks\n\nAuthenticate with a bearer token issued by `/v1/oauth/token`. All state-changing requests\n(POST, PUT, PATCH, DELETE) MUST include an `Idempotency-Key` header (UUID v4) to make\nretries safe — Kang will return the original response for any duplicate key within 24 hours.\n\nErrors follow [RFC 7807](https://datatracker.ietf.org/doc/html/rfc7807) and are returned with\n`Content-Type: application/problem+json`. The `code` field is stable and machine-readable.\nRate-limit headers (`X-RateLimit-Limit`, `X-RateLimit-Remaining`, `X-RateLimit-Reset`)\nare present on every response.\n\n**Migration:** Replace with `webhookV2Create`. Move the endpoint to Webhooks v2 and verify the timestamped `X-Webhook-Signature` described in the webhook definitions.",
        "x-replacement-operation-ids": [
          "webhookV2Create"
        ],
        "x-migration-guide": "Move the endpoint to Webhooks v2 and verify the timestamped `X-Webhook-Signature` described in the webhook definitions."
      },
      "get": {
        "tags": [
          "Webhooks"
        ],
        "summary": "List webhooks",
        "operationId": "webhookList",
        "security": [
          {
            "bearerAuth": []
          }
        ],
        "responses": {
          "200": {
            "description": "Webhooks list",
            "content": {
              "application/json": {
                "schema": {
                  "allOf": [
                    {
                      "$ref": "#/components/schemas/PaginatedResponse"
                    },
                    {
                      "type": "object",
                      "properties": {
                        "data": {
                          "type": "array",
                          "items": {
                            "$ref": "#/components/schemas/Webhook"
                          }
                        }
                      }
                    }
                  ]
                },
                "example": {
                  "data": [
                    {
                      "webhook_id": "f1d6f4a0-1d4e-4a3a-9e0a-1a2b3c4d5e6f",
                      "url": "https://example.com/callback",
                      "events": [
                        {
                          "id": "evt_a1b2c3d4-e5f6-7890-abcd-ef1234567890",
                          "event": "charge.created",
                          "created_at": "2025-03-27T14:32:00Z",
                          "api_version": "4.6.0",
                          "livemode": true,
                          "data": {},
                          "metadata": {}
                        }
                      ],
                      "is_active": false,
                      "secret": "XAF"
                    }
                  ],
                  "pagination": {
                    "page": 1,
                    "limit": 20,
                    "total": 150,
                    "has_next": true,
                    "next_cursor": "eyJpZCI6IjEyMyJ9"
                  },
                  "meta": {
                    "request_id": "550e8400-e29b-41d4-a716-446655440000",
                    "timestamp": "2025-03-27T12:00:00Z",
                    "api_version": "4.3.0"
                  }
                }
              }
            },
            "headers": {
              "x-fapi-interaction-id": {
                "$ref": "#/components/headers/XFapiInteractionIdResponse"
              },
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/XRateLimitLimit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/XRateLimitRemaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/XRateLimitReset"
              },
              "Cache-Control": {
                "$ref": "#/components/headers/CacheControl"
              },
              "ETag": {
                "$ref": "#/components/headers/ETag"
              },
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              },
              "traceparent": {
                "$ref": "#/components/headers/Traceparent"
              },
              "Content-Language": {
                "$ref": "#/components/headers/Content-Language"
              }
            }
          },
          "400": {
            "description": "Bad request",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              },
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                },
                "examples": {
                  "error": {
                    "$ref": "#/components/examples/ErrorBadRequest"
                  }
                }
              }
            },
            "headers": {
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/XRateLimitLimit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/XRateLimitRemaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/XRateLimitReset"
              },
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "403": {
            "$ref": "#/components/responses/Forbidden",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "404": {
            "$ref": "#/components/responses/NotFound",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "409": {
            "$ref": "#/components/responses/Conflict",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "429": {
            "$ref": "#/components/responses/TooManyRequests",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "500": {
            "$ref": "#/components/responses/InternalServerError",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          }
        },
        "parameters": [
          {
            "$ref": "#/components/parameters/PageParam"
          },
          {
            "$ref": "#/components/parameters/LimitParam"
          },
          {
            "$ref": "#/components/parameters/CursorParam"
          },
          {
            "$ref": "#/components/parameters/RequestId"
          },
          {
            "$ref": "#/components/parameters/Traceparent"
          },
          {
            "$ref": "#/components/parameters/Tracestate"
          },
          {
            "$ref": "#/components/parameters/AcceptLanguage"
          }
        ],
        "deprecated": true,
        "x-sunset-date": "2026-12-31",
        "x-successor": "/v1/webhooks/v2/endpoints",
        "x-codeSamples": [
          {
            "lang": "cURL",
            "label": "cURL",
            "source": "curl -X GET \"https://api.kangopenbanking.com/v1/webhooks\" \\\n  -H \"Authorization: Bearer $KOB_ACCESS_TOKEN\" \\\n  -H \"Content-Type: application/json\""
          },
          {
            "lang": "JavaScript",
            "label": "Node.js",
            "source": "import { KangOpenBanking } from \"@kangopenbanking/sdk\";\n\nconst kob = new KangOpenBanking({ apiKey: process.env.KOB_API_KEY });\nconst res = await kob.request(\"GET\", \"/v1/webhooks\");\nconsole.log(res);"
          },
          {
            "lang": "Python",
            "label": "Python",
            "source": "from kangopenbanking import KangOpenBanking\n\nkob = KangOpenBanking(api_key=os.environ[\"KOB_API_KEY\"])\nres = kob.request(\"GET\", \"/v1/webhooks\")\nprint(res)"
          },
          {
            "lang": "PHP",
            "label": "PHP",
            "source": "<?php\n$kob = new KangOpenBanking\\KangOpenBanking(getenv('KOB_API_KEY'));\n$res = $kob->request('GET', '/v1/webhooks');\nprint_r($res);"
          }
        ],
        "description": "**Deprecated.** Use Webhooks v2 (`/v1/webhooks/v2/endpoints`). Sunset: 2026-12-31.\n\nList webhooks.\n\n**Tag:** Webhooks\n\nAuthenticate with a bearer token issued by `/v1/oauth/token`. All state-changing requests\n(POST, PUT, PATCH, DELETE) MUST include an `Idempotency-Key` header (UUID v4) to make\nretries safe — Kang will return the original response for any duplicate key within 24 hours.\n\nErrors follow [RFC 7807](https://datatracker.ietf.org/doc/html/rfc7807) and are returned with\n`Content-Type: application/problem+json`. The `code` field is stable and machine-readable.\nRate-limit headers (`X-RateLimit-Limit`, `X-RateLimit-Remaining`, `X-RateLimit-Reset`)\nare present on every response.\n\n**Migration:** Replace with `webhookV2List`. Move the endpoint to Webhooks v2 and verify the timestamped `X-Webhook-Signature` described in the webhook definitions.",
        "x-replacement-operation-ids": [
          "webhookV2List"
        ],
        "x-migration-guide": "Move the endpoint to Webhooks v2 and verify the timestamped `X-Webhook-Signature` described in the webhook definitions."
      }
    },
    "/v1/webhooks/{webhookId}/deliveries": {
      "get": {
        "tags": [
          "Webhooks"
        ],
        "summary": "List webhook deliveries",
        "operationId": "webhookDeliveries",
        "security": [
          {
            "bearerAuth": []
          }
        ],
        "parameters": [
          {
            "name": "webhookId",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "limit",
            "in": "query",
            "schema": {
              "type": "integer",
              "default": 25,
              "maximum": 100
            },
            "description": "Items per page"
          },
          {
            "name": "offset",
            "in": "query",
            "schema": {
              "type": "integer",
              "default": 0
            },
            "description": "Items to skip"
          },
          {
            "name": "sort_by",
            "in": "query",
            "schema": {
              "type": "string",
              "default": "created_at"
            },
            "description": "Sort field"
          },
          {
            "name": "sort_order",
            "in": "query",
            "schema": {
              "type": "string",
              "enum": [
                "asc",
                "desc"
              ],
              "default": "desc"
            },
            "description": "Sort direction"
          },
          {
            "$ref": "#/components/parameters/StartingAfter"
          },
          {
            "$ref": "#/components/parameters/EndingBefore"
          },
          {
            "$ref": "#/components/parameters/RequestId"
          },
          {
            "$ref": "#/components/parameters/Traceparent"
          },
          {
            "$ref": "#/components/parameters/Tracestate"
          },
          {
            "$ref": "#/components/parameters/AcceptLanguage"
          }
        ],
        "responses": {
          "200": {
            "description": "Delivery history",
            "content": {
              "application/json": {
                "schema": {
                  "allOf": [
                    {
                      "$ref": "#/components/schemas/PaginatedResponse"
                    },
                    {
                      "type": "object",
                      "properties": {
                        "data": {
                          "type": "array",
                          "items": {}
                        }
                      }
                    }
                  ]
                },
                "example": {
                  "data": [
                    {}
                  ],
                  "pagination": {
                    "page": 1,
                    "limit": 20,
                    "total": 150,
                    "has_next": true,
                    "next_cursor": "eyJpZCI6IjEyMyJ9"
                  },
                  "meta": {
                    "request_id": "550e8400-e29b-41d4-a716-446655440000",
                    "timestamp": "2025-03-27T12:00:00Z",
                    "api_version": "4.3.0"
                  }
                }
              }
            },
            "headers": {
              "x-fapi-interaction-id": {
                "$ref": "#/components/headers/XFapiInteractionIdResponse"
              },
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/XRateLimitLimit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/XRateLimitRemaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/XRateLimitReset"
              },
              "Cache-Control": {
                "$ref": "#/components/headers/CacheControl"
              },
              "ETag": {
                "$ref": "#/components/headers/ETag"
              },
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              },
              "traceparent": {
                "$ref": "#/components/headers/Traceparent"
              },
              "Content-Language": {
                "$ref": "#/components/headers/Content-Language"
              }
            }
          },
          "400": {
            "description": "Bad request",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              },
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                },
                "examples": {
                  "error": {
                    "$ref": "#/components/examples/ErrorBadRequest"
                  }
                }
              }
            },
            "headers": {
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/XRateLimitLimit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/XRateLimitRemaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/XRateLimitReset"
              },
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "403": {
            "$ref": "#/components/responses/Forbidden",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "404": {
            "$ref": "#/components/responses/NotFound",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "409": {
            "$ref": "#/components/responses/Conflict",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "429": {
            "$ref": "#/components/responses/TooManyRequests",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "500": {
            "$ref": "#/components/responses/InternalServerError",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          }
        },
        "deprecated": true,
        "x-sunset-date": "2026-12-31",
        "x-successor": "/v1/webhooks/v2/endpoints",
        "x-codeSamples": [
          {
            "lang": "cURL",
            "label": "cURL",
            "source": "curl -X GET \"https://api.kangopenbanking.com/v1/webhooks/{webhookId}/deliveries\" \\\n  -H \"Authorization: Bearer $KOB_ACCESS_TOKEN\" \\\n  -H \"Content-Type: application/json\""
          },
          {
            "lang": "JavaScript",
            "label": "Node.js",
            "source": "import { KangOpenBanking } from \"@kangopenbanking/sdk\";\n\nconst kob = new KangOpenBanking({ apiKey: process.env.KOB_API_KEY });\nconst res = await kob.request(\"GET\", \"/v1/webhooks/{webhookId}/deliveries\");\nconsole.log(res);"
          },
          {
            "lang": "Python",
            "label": "Python",
            "source": "from kangopenbanking import KangOpenBanking\n\nkob = KangOpenBanking(api_key=os.environ[\"KOB_API_KEY\"])\nres = kob.request(\"GET\", \"/v1/webhooks/{webhookId}/deliveries\")\nprint(res)"
          },
          {
            "lang": "PHP",
            "label": "PHP",
            "source": "<?php\n$kob = new KangOpenBanking\\KangOpenBanking(getenv('KOB_API_KEY'));\n$res = $kob->request('GET', '/v1/webhooks/{webhookId}/deliveries');\nprint_r($res);"
          }
        ],
        "description": "**Deprecated.** Use Webhooks v2 (`/v1/webhooks/v2/endpoints`). Sunset: 2026-12-31.\n\nList webhook deliveries.\n\n**Tag:** Webhooks\n\nAuthenticate with a bearer token issued by `/v1/oauth/token`. All state-changing requests\n(POST, PUT, PATCH, DELETE) MUST include an `Idempotency-Key` header (UUID v4) to make\nretries safe — Kang will return the original response for any duplicate key within 24 hours.\n\nErrors follow [RFC 7807](https://datatracker.ietf.org/doc/html/rfc7807) and are returned with\n`Content-Type: application/problem+json`. The `code` field is stable and machine-readable.\nRate-limit headers (`X-RateLimit-Limit`, `X-RateLimit-Remaining`, `X-RateLimit-Reset`)\nare present on every response.\n\n**Migration:** Replace with `webhookV2List`. Move the endpoint to Webhooks v2 and verify the timestamped `X-Webhook-Signature` described in the webhook definitions.",
        "x-replacement-operation-ids": [
          "webhookV2List"
        ],
        "x-migration-guide": "Move the endpoint to Webhooks v2 and verify the timestamped `X-Webhook-Signature` described in the webhook definitions."
      }
    },
    "/v1/admin/users": {
      "post": {
        "tags": [
          "Admin"
        ],
        "summary": "Create user",
        "operationId": "adminCreateUser",
        "security": [
          {
            "bearerAuth": []
          }
        ],
        "parameters": [
          {
            "name": "Idempotency-Key",
            "in": "header",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid"
            },
            "description": "Required on all POST/PUT endpoints. Unique key for idempotent request processing (UUID v4 recommended). Keys expire after 24 hours."
          },
          {
            "$ref": "#/components/parameters/RequestId"
          },
          {
            "$ref": "#/components/parameters/Traceparent"
          },
          {
            "$ref": "#/components/parameters/Tracestate"
          },
          {
            "$ref": "#/components/parameters/AcceptLanguage"
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "required": [
                  "email",
                  "role"
                ],
                "properties": {
                  "email": {
                    "type": "string"
                  },
                  "role": {
                    "type": "string",
                    "enum": [
                      "admin",
                      "institution",
                      "tpp",
                      "personal"
                    ]
                  },
                  "full_name": {
                    "type": "string"
                  }
                }
              }
            }
          }
        },
        "responses": {
          "201": {
            "description": "User created",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "id": {
                      "type": "string",
                      "format": "uuid"
                    },
                    "email": {
                      "type": "string"
                    },
                    "role": {
                      "type": "string"
                    },
                    "created_at": {
                      "type": "string",
                      "format": "date-time"
                    }
                  }
                },
                "example": {
                  "id": "00000000-0000-4000-8000-000000000000",
                  "email": "agent@example.cm",
                  "role": "string",
                  "created_at": "2026-01-01T00:00:00Z"
                }
              }
            },
            "headers": {
              "x-fapi-interaction-id": {
                "$ref": "#/components/headers/XFapiInteractionIdResponse"
              },
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/XRateLimitLimit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/XRateLimitRemaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/XRateLimitReset"
              },
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              },
              "traceparent": {
                "$ref": "#/components/headers/Traceparent"
              },
              "Content-Language": {
                "$ref": "#/components/headers/Content-Language"
              }
            }
          },
          "400": {
            "description": "Bad request",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              },
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                },
                "examples": {
                  "error": {
                    "$ref": "#/components/examples/ErrorBadRequest"
                  }
                }
              }
            },
            "headers": {
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/XRateLimitLimit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/XRateLimitRemaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/XRateLimitReset"
              },
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "403": {
            "$ref": "#/components/responses/Forbidden",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "404": {
            "$ref": "#/components/responses/NotFound",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "409": {
            "$ref": "#/components/responses/Conflict",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "429": {
            "$ref": "#/components/responses/TooManyRequests",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "500": {
            "$ref": "#/components/responses/InternalServerError",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          }
        },
        "x-codeSamples": [
          {
            "lang": "cURL",
            "label": "cURL",
            "source": "curl -X POST \"https://api.kangopenbanking.com/v1/admin/users\" \\\n  -H \"Authorization: Bearer $KOB_ACCESS_TOKEN\" \\\n  -H \"Content-Type: application/json\" \\\n  -d '{}'"
          },
          {
            "lang": "JavaScript",
            "label": "Node.js",
            "source": "import { KangOpenBanking } from \"@kangopenbanking/sdk\";\n\nconst kob = new KangOpenBanking({ apiKey: process.env.KOB_API_KEY });\nconst res = await kob.request(\"POST\", \"/v1/admin/users\", { /* payload */ });\nconsole.log(res);"
          },
          {
            "lang": "Python",
            "label": "Python",
            "source": "from kangopenbanking import KangOpenBanking\n\nkob = KangOpenBanking(api_key=os.environ[\"KOB_API_KEY\"])\nres = kob.request(\"POST\", \"/v1/admin/users\", json={})\nprint(res)"
          },
          {
            "lang": "PHP",
            "label": "PHP",
            "source": "<?php\n$kob = new KangOpenBanking\\KangOpenBanking(getenv('KOB_API_KEY'));\n$res = $kob->request('POST', '/v1/admin/users', []);\nprint_r($res);"
          }
        ]
      }
    },
    "/v1/admin/clients": {
      "post": {
        "tags": [
          "Admin"
        ],
        "summary": "Create API client",
        "operationId": "adminCreateClient",
        "security": [
          {
            "bearerAuth": []
          }
        ],
        "parameters": [
          {
            "name": "Idempotency-Key",
            "in": "header",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid"
            },
            "description": "Required on all POST/PUT endpoints. Unique key for idempotent request processing (UUID v4 recommended). Keys expire after 24 hours."
          },
          {
            "$ref": "#/components/parameters/RequestId"
          },
          {
            "$ref": "#/components/parameters/Traceparent"
          },
          {
            "$ref": "#/components/parameters/Tracestate"
          },
          {
            "$ref": "#/components/parameters/AcceptLanguage"
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "required": [
                  "client_name"
                ],
                "properties": {
                  "client_name": {
                    "type": "string"
                  },
                  "scopes": {
                    "type": "array",
                    "items": {
                      "type": "string"
                    }
                  }
                }
              }
            }
          }
        },
        "responses": {
          "201": {
            "description": "Client created",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "client_id": {
                      "type": "string"
                    },
                    "client_secret": {
                      "type": "string",
                      "description": "Shown once"
                    },
                    "client_name": {
                      "type": "string"
                    },
                    "scopes": {
                      "type": "array",
                      "items": {
                        "type": "string"
                      }
                    },
                    "created_at": {
                      "type": "string",
                      "format": "date-time"
                    }
                  }
                },
                "example": {
                  "client_id": "string",
                  "client_secret": "string",
                  "client_name": "string",
                  "scopes": [
                    "string"
                  ],
                  "created_at": "2026-01-01T00:00:00Z"
                }
              }
            },
            "headers": {
              "x-fapi-interaction-id": {
                "$ref": "#/components/headers/XFapiInteractionIdResponse"
              },
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/XRateLimitLimit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/XRateLimitRemaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/XRateLimitReset"
              },
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              },
              "traceparent": {
                "$ref": "#/components/headers/Traceparent"
              },
              "Content-Language": {
                "$ref": "#/components/headers/Content-Language"
              }
            }
          },
          "400": {
            "description": "Bad request",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              },
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                },
                "examples": {
                  "error": {
                    "$ref": "#/components/examples/ErrorBadRequest"
                  }
                }
              }
            },
            "headers": {
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/XRateLimitLimit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/XRateLimitRemaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/XRateLimitReset"
              },
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "403": {
            "$ref": "#/components/responses/Forbidden",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "404": {
            "$ref": "#/components/responses/NotFound",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "409": {
            "$ref": "#/components/responses/Conflict",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "429": {
            "$ref": "#/components/responses/TooManyRequests",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "500": {
            "$ref": "#/components/responses/InternalServerError",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          }
        },
        "x-codeSamples": [
          {
            "lang": "cURL",
            "label": "cURL",
            "source": "curl -X POST \"https://api.kangopenbanking.com/v1/admin/clients\" \\\n  -H \"Authorization: Bearer $KOB_ACCESS_TOKEN\" \\\n  -H \"Content-Type: application/json\" \\\n  -d '{}'"
          },
          {
            "lang": "JavaScript",
            "label": "Node.js",
            "source": "import { KangOpenBanking } from \"@kangopenbanking/sdk\";\n\nconst kob = new KangOpenBanking({ apiKey: process.env.KOB_API_KEY });\nconst res = await kob.request(\"POST\", \"/v1/admin/clients\", { /* payload */ });\nconsole.log(res);"
          },
          {
            "lang": "Python",
            "label": "Python",
            "source": "from kangopenbanking import KangOpenBanking\n\nkob = KangOpenBanking(api_key=os.environ[\"KOB_API_KEY\"])\nres = kob.request(\"POST\", \"/v1/admin/clients\", json={})\nprint(res)"
          },
          {
            "lang": "PHP",
            "label": "PHP",
            "source": "<?php\n$kob = new KangOpenBanking\\KangOpenBanking(getenv('KOB_API_KEY'));\n$res = $kob->request('POST', '/v1/admin/clients', []);\nprint_r($res);"
          }
        ]
      }
    },
    "/v1/admin/metrics": {
      "get": {
        "tags": [
          "Admin"
        ],
        "summary": "Platform metrics",
        "operationId": "adminMetrics",
        "security": [
          {
            "bearerAuth": []
          }
        ],
        "responses": {
          "200": {
            "description": "Metrics dashboard data",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "total_users": {
                      "type": "integer"
                    },
                    "total_transactions": {
                      "type": "integer"
                    },
                    "total_volume": {
                      "type": "number"
                    }
                  }
                },
                "example": {
                  "total_users": 0,
                  "total_transactions": 0,
                  "total_volume": 0
                }
              }
            },
            "headers": {
              "x-fapi-interaction-id": {
                "$ref": "#/components/headers/XFapiInteractionIdResponse"
              },
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/XRateLimitLimit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/XRateLimitRemaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/XRateLimitReset"
              },
              "Cache-Control": {
                "$ref": "#/components/headers/CacheControl"
              },
              "ETag": {
                "$ref": "#/components/headers/ETag"
              },
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              },
              "traceparent": {
                "$ref": "#/components/headers/Traceparent"
              },
              "Content-Language": {
                "$ref": "#/components/headers/Content-Language"
              }
            }
          },
          "400": {
            "description": "Bad request",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              },
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                },
                "examples": {
                  "error": {
                    "$ref": "#/components/examples/ErrorBadRequest"
                  }
                }
              }
            },
            "headers": {
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/XRateLimitLimit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/XRateLimitRemaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/XRateLimitReset"
              },
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "403": {
            "$ref": "#/components/responses/Forbidden",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "404": {
            "$ref": "#/components/responses/NotFound",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "409": {
            "$ref": "#/components/responses/Conflict",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "429": {
            "$ref": "#/components/responses/TooManyRequests",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "500": {
            "$ref": "#/components/responses/InternalServerError",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          }
        },
        "parameters": [
          {
            "$ref": "#/components/parameters/RequestId"
          },
          {
            "$ref": "#/components/parameters/Traceparent"
          },
          {
            "$ref": "#/components/parameters/Tracestate"
          },
          {
            "$ref": "#/components/parameters/AcceptLanguage"
          }
        ],
        "x-codeSamples": [
          {
            "lang": "cURL",
            "label": "cURL",
            "source": "curl -X GET \"https://api.kangopenbanking.com/v1/admin/metrics\" \\\n  -H \"Authorization: Bearer $KOB_ACCESS_TOKEN\" \\\n  -H \"Content-Type: application/json\""
          },
          {
            "lang": "JavaScript",
            "label": "Node.js",
            "source": "import { KangOpenBanking } from \"@kangopenbanking/sdk\";\n\nconst kob = new KangOpenBanking({ apiKey: process.env.KOB_API_KEY });\nconst res = await kob.request(\"GET\", \"/v1/admin/metrics\");\nconsole.log(res);"
          },
          {
            "lang": "Python",
            "label": "Python",
            "source": "from kangopenbanking import KangOpenBanking\n\nkob = KangOpenBanking(api_key=os.environ[\"KOB_API_KEY\"])\nres = kob.request(\"GET\", \"/v1/admin/metrics\")\nprint(res)"
          },
          {
            "lang": "PHP",
            "label": "PHP",
            "source": "<?php\n$kob = new KangOpenBanking\\KangOpenBanking(getenv('KOB_API_KEY'));\n$res = $kob->request('GET', '/v1/admin/metrics');\nprint_r($res);"
          }
        ]
      }
    },
    "/v1/admin/sandbox/accounts": {
      "get": {
        "tags": [
          "Admin"
        ],
        "summary": "List sandbox accounts",
        "operationId": "adminSandboxAccounts",
        "security": [
          {
            "bearerAuth": []
          }
        ],
        "responses": {
          "200": {
            "description": "Sandbox accounts",
            "content": {
              "application/json": {
                "schema": {
                  "allOf": [
                    {
                      "$ref": "#/components/schemas/PaginatedResponse"
                    },
                    {
                      "type": "object",
                      "properties": {
                        "data": {
                          "type": "array",
                          "items": {
                            "$ref": "#/components/schemas/Account"
                          }
                        }
                      }
                    }
                  ]
                },
                "example": {
                  "data": [
                    {
                      "account_id": "f1d6f4a0-1d4e-4a3a-9e0a-1a2b3c4d5e6f",
                      "account_number": "CM21 10003 00100 0123456789 023",
                      "account_type": "checking",
                      "account_subtype": "personal_current",
                      "identification_scheme": "LOCAL_BANK",
                      "identification_value": "XAF",
                      "currency": "XAF",
                      "balance": "1500000",
                      "account_holder_name": "Jean-Pierre Kamga",
                      "status": "active",
                      "opened_date": "2025-03-15",
                      "rib_bank_code": "10005",
                      "rib_branch_code": "00100",
                      "rib_account_number": "01234567890",
                      "rib_key": "23",
                      "swift_bic": "AFRIACMCXXX",
                      "account_country": "CM"
                    }
                  ],
                  "pagination": {
                    "page": 1,
                    "limit": 20,
                    "total": 150,
                    "has_next": true,
                    "next_cursor": "eyJpZCI6IjEyMyJ9"
                  },
                  "meta": {
                    "request_id": "550e8400-e29b-41d4-a716-446655440000",
                    "timestamp": "2025-03-27T12:00:00Z",
                    "api_version": "4.3.0"
                  }
                }
              }
            },
            "headers": {
              "x-fapi-interaction-id": {
                "$ref": "#/components/headers/XFapiInteractionIdResponse"
              },
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/XRateLimitLimit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/XRateLimitRemaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/XRateLimitReset"
              },
              "Cache-Control": {
                "$ref": "#/components/headers/CacheControl"
              },
              "ETag": {
                "$ref": "#/components/headers/ETag"
              },
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              },
              "traceparent": {
                "$ref": "#/components/headers/Traceparent"
              },
              "Content-Language": {
                "$ref": "#/components/headers/Content-Language"
              }
            }
          },
          "400": {
            "description": "Bad request",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              },
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                },
                "examples": {
                  "error": {
                    "$ref": "#/components/examples/ErrorBadRequest"
                  }
                }
              }
            },
            "headers": {
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/XRateLimitLimit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/XRateLimitRemaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/XRateLimitReset"
              },
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "403": {
            "$ref": "#/components/responses/Forbidden",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "404": {
            "$ref": "#/components/responses/NotFound",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "409": {
            "$ref": "#/components/responses/Conflict",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "429": {
            "$ref": "#/components/responses/TooManyRequests",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "500": {
            "$ref": "#/components/responses/InternalServerError",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          }
        },
        "parameters": [
          {
            "$ref": "#/components/parameters/PageParam"
          },
          {
            "$ref": "#/components/parameters/LimitParam"
          },
          {
            "$ref": "#/components/parameters/CursorParam"
          },
          {
            "$ref": "#/components/parameters/RequestId"
          },
          {
            "$ref": "#/components/parameters/Traceparent"
          },
          {
            "$ref": "#/components/parameters/Tracestate"
          },
          {
            "$ref": "#/components/parameters/AcceptLanguage"
          }
        ],
        "x-codeSamples": [
          {
            "lang": "cURL",
            "label": "cURL",
            "source": "curl -X GET \"https://api.kangopenbanking.com/v1/admin/sandbox/accounts\" \\\n  -H \"Authorization: Bearer $KOB_ACCESS_TOKEN\" \\\n  -H \"Content-Type: application/json\""
          },
          {
            "lang": "JavaScript",
            "label": "Node.js",
            "source": "import { KangOpenBanking } from \"@kangopenbanking/sdk\";\n\nconst kob = new KangOpenBanking({ apiKey: process.env.KOB_API_KEY });\nconst res = await kob.request(\"GET\", \"/v1/admin/sandbox/accounts\");\nconsole.log(res);"
          },
          {
            "lang": "Python",
            "label": "Python",
            "source": "from kangopenbanking import KangOpenBanking\n\nkob = KangOpenBanking(api_key=os.environ[\"KOB_API_KEY\"])\nres = kob.request(\"GET\", \"/v1/admin/sandbox/accounts\")\nprint(res)"
          },
          {
            "lang": "PHP",
            "label": "PHP",
            "source": "<?php\n$kob = new KangOpenBanking\\KangOpenBanking(getenv('KOB_API_KEY'));\n$res = $kob->request('GET', '/v1/admin/sandbox/accounts');\nprint_r($res);"
          }
        ]
      }
    },
    "/v1/admin/system-config": {
      "get": {
        "tags": [
          "Admin"
        ],
        "summary": "Get system configuration",
        "operationId": "adminSystemConfig",
        "security": [
          {
            "bearerAuth": []
          }
        ],
        "responses": {
          "200": {
            "description": "System config",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "additionalProperties": true
                },
                "example": {}
              }
            },
            "headers": {
              "x-fapi-interaction-id": {
                "$ref": "#/components/headers/XFapiInteractionIdResponse"
              },
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/XRateLimitLimit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/XRateLimitRemaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/XRateLimitReset"
              },
              "Cache-Control": {
                "$ref": "#/components/headers/CacheControl"
              },
              "ETag": {
                "$ref": "#/components/headers/ETag"
              },
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              },
              "traceparent": {
                "$ref": "#/components/headers/Traceparent"
              },
              "Content-Language": {
                "$ref": "#/components/headers/Content-Language"
              }
            }
          },
          "400": {
            "description": "Bad request",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              },
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                },
                "examples": {
                  "error": {
                    "$ref": "#/components/examples/ErrorBadRequest"
                  }
                }
              }
            },
            "headers": {
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/XRateLimitLimit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/XRateLimitRemaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/XRateLimitReset"
              },
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "403": {
            "$ref": "#/components/responses/Forbidden",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "404": {
            "$ref": "#/components/responses/NotFound",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "409": {
            "$ref": "#/components/responses/Conflict",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "429": {
            "$ref": "#/components/responses/TooManyRequests",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "500": {
            "$ref": "#/components/responses/InternalServerError",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          }
        },
        "parameters": [
          {
            "$ref": "#/components/parameters/RequestId"
          },
          {
            "$ref": "#/components/parameters/Traceparent"
          },
          {
            "$ref": "#/components/parameters/Tracestate"
          },
          {
            "$ref": "#/components/parameters/AcceptLanguage"
          }
        ],
        "x-codeSamples": [
          {
            "lang": "cURL",
            "label": "cURL",
            "source": "curl -X GET \"https://api.kangopenbanking.com/v1/admin/system-config\" \\\n  -H \"Authorization: Bearer $KOB_ACCESS_TOKEN\" \\\n  -H \"Content-Type: application/json\""
          },
          {
            "lang": "JavaScript",
            "label": "Node.js",
            "source": "import { KangOpenBanking } from \"@kangopenbanking/sdk\";\n\nconst kob = new KangOpenBanking({ apiKey: process.env.KOB_API_KEY });\nconst res = await kob.request(\"GET\", \"/v1/admin/system-config\");\nconsole.log(res);"
          },
          {
            "lang": "Python",
            "label": "Python",
            "source": "from kangopenbanking import KangOpenBanking\n\nkob = KangOpenBanking(api_key=os.environ[\"KOB_API_KEY\"])\nres = kob.request(\"GET\", \"/v1/admin/system-config\")\nprint(res)"
          },
          {
            "lang": "PHP",
            "label": "PHP",
            "source": "<?php\n$kob = new KangOpenBanking\\KangOpenBanking(getenv('KOB_API_KEY'));\n$res = $kob->request('GET', '/v1/admin/system-config');\nprint_r($res);"
          }
        ]
      },
      "put": {
        "tags": [
          "Admin"
        ],
        "summary": "Update system configuration",
        "operationId": "adminSystemConfigUpdate",
        "security": [
          {
            "bearerAuth": []
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "additionalProperties": true
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "System configuration updated",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "success": {
                      "type": "boolean",
                      "example": true
                    },
                    "message": {
                      "type": "string"
                    }
                  }
                },
                "example": {
                  "success": true,
                  "message": "string"
                }
              }
            },
            "headers": {
              "x-fapi-interaction-id": {
                "$ref": "#/components/headers/XFapiInteractionIdResponse"
              },
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/XRateLimitLimit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/XRateLimitRemaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/XRateLimitReset"
              },
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              },
              "traceparent": {
                "$ref": "#/components/headers/Traceparent"
              },
              "Content-Language": {
                "$ref": "#/components/headers/Content-Language"
              }
            }
          },
          "400": {
            "description": "Bad request",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              },
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                },
                "examples": {
                  "error": {
                    "$ref": "#/components/examples/ErrorBadRequest"
                  }
                }
              }
            },
            "headers": {
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/XRateLimitLimit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/XRateLimitRemaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/XRateLimitReset"
              },
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "403": {
            "$ref": "#/components/responses/Forbidden",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "404": {
            "$ref": "#/components/responses/NotFound",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "409": {
            "$ref": "#/components/responses/Conflict",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "429": {
            "$ref": "#/components/responses/TooManyRequests",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "500": {
            "$ref": "#/components/responses/InternalServerError",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          }
        },
        "parameters": [
          {
            "$ref": "#/components/parameters/RequestId"
          },
          {
            "$ref": "#/components/parameters/Traceparent"
          },
          {
            "$ref": "#/components/parameters/Tracestate"
          },
          {
            "$ref": "#/components/parameters/AcceptLanguage"
          }
        ],
        "x-codeSamples": [
          {
            "lang": "cURL",
            "label": "cURL",
            "source": "curl -X PUT \"https://api.kangopenbanking.com/v1/admin/system-config\" \\\n  -H \"Authorization: Bearer $KOB_ACCESS_TOKEN\" \\\n  -H \"Content-Type: application/json\" \\\n  -d '{}'"
          },
          {
            "lang": "JavaScript",
            "label": "Node.js",
            "source": "import { KangOpenBanking } from \"@kangopenbanking/sdk\";\n\nconst kob = new KangOpenBanking({ apiKey: process.env.KOB_API_KEY });\nconst res = await kob.request(\"PUT\", \"/v1/admin/system-config\", { /* payload */ });\nconsole.log(res);"
          },
          {
            "lang": "Python",
            "label": "Python",
            "source": "from kangopenbanking import KangOpenBanking\n\nkob = KangOpenBanking(api_key=os.environ[\"KOB_API_KEY\"])\nres = kob.request(\"PUT\", \"/v1/admin/system-config\", json={})\nprint(res)"
          },
          {
            "lang": "PHP",
            "label": "PHP",
            "source": "<?php\n$kob = new KangOpenBanking\\KangOpenBanking(getenv('KOB_API_KEY'));\n$res = $kob->request('PUT', '/v1/admin/system-config', []);\nprint_r($res);"
          }
        ]
      }
    },
    "/v1/admin/webhooks": {
      "get": {
        "tags": [
          "Admin"
        ],
        "summary": "List all webhooks (admin)",
        "operationId": "adminWebhooks",
        "security": [
          {
            "bearerAuth": []
          }
        ],
        "parameters": [
          {
            "name": "sort_by",
            "in": "query",
            "schema": {
              "type": "string",
              "default": "created_at"
            },
            "description": "Sort field"
          },
          {
            "name": "sort_order",
            "in": "query",
            "schema": {
              "type": "string",
              "enum": [
                "asc",
                "desc"
              ],
              "default": "desc"
            },
            "description": "Sort direction"
          },
          {
            "$ref": "#/components/parameters/PageParam"
          },
          {
            "$ref": "#/components/parameters/LimitParam"
          },
          {
            "$ref": "#/components/parameters/CursorParam"
          },
          {
            "$ref": "#/components/parameters/RequestId"
          },
          {
            "$ref": "#/components/parameters/Traceparent"
          },
          {
            "$ref": "#/components/parameters/Tracestate"
          },
          {
            "$ref": "#/components/parameters/AcceptLanguage"
          }
        ],
        "responses": {
          "200": {
            "description": "All webhooks",
            "content": {
              "application/json": {
                "schema": {
                  "allOf": [
                    {
                      "$ref": "#/components/schemas/PaginatedResponse"
                    },
                    {
                      "type": "object",
                      "properties": {
                        "data": {
                          "type": "array",
                          "items": {
                            "$ref": "#/components/schemas/Webhook"
                          }
                        }
                      }
                    }
                  ]
                },
                "example": {
                  "data": [
                    {
                      "webhook_id": "f1d6f4a0-1d4e-4a3a-9e0a-1a2b3c4d5e6f",
                      "url": "https://example.com/callback",
                      "events": [
                        {
                          "id": "evt_a1b2c3d4-e5f6-7890-abcd-ef1234567890",
                          "event": "charge.created",
                          "created_at": "2025-03-27T14:32:00Z",
                          "api_version": "4.6.0",
                          "livemode": true,
                          "data": {},
                          "metadata": {}
                        }
                      ],
                      "is_active": false,
                      "secret": "XAF"
                    }
                  ],
                  "pagination": {
                    "page": 1,
                    "limit": 20,
                    "total": 150,
                    "has_next": true,
                    "next_cursor": "eyJpZCI6IjEyMyJ9"
                  },
                  "meta": {
                    "request_id": "550e8400-e29b-41d4-a716-446655440000",
                    "timestamp": "2025-03-27T12:00:00Z",
                    "api_version": "4.3.0"
                  }
                }
              }
            },
            "headers": {
              "x-fapi-interaction-id": {
                "$ref": "#/components/headers/XFapiInteractionIdResponse"
              },
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/XRateLimitLimit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/XRateLimitRemaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/XRateLimitReset"
              },
              "Cache-Control": {
                "$ref": "#/components/headers/CacheControl"
              },
              "ETag": {
                "$ref": "#/components/headers/ETag"
              },
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              },
              "traceparent": {
                "$ref": "#/components/headers/Traceparent"
              },
              "Content-Language": {
                "$ref": "#/components/headers/Content-Language"
              }
            }
          },
          "400": {
            "description": "Bad request",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              },
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                },
                "examples": {
                  "error": {
                    "$ref": "#/components/examples/ErrorBadRequest"
                  }
                }
              }
            },
            "headers": {
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/XRateLimitLimit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/XRateLimitRemaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/XRateLimitReset"
              },
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "403": {
            "$ref": "#/components/responses/Forbidden",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "404": {
            "$ref": "#/components/responses/NotFound",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "409": {
            "$ref": "#/components/responses/Conflict",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "429": {
            "$ref": "#/components/responses/TooManyRequests",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "500": {
            "$ref": "#/components/responses/InternalServerError",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          }
        },
        "x-codeSamples": [
          {
            "lang": "cURL",
            "label": "cURL",
            "source": "curl -X GET \"https://api.kangopenbanking.com/v1/admin/webhooks\" \\\n  -H \"Authorization: Bearer $KOB_ACCESS_TOKEN\" \\\n  -H \"Content-Type: application/json\""
          },
          {
            "lang": "JavaScript",
            "label": "Node.js",
            "source": "import { KangOpenBanking } from \"@kangopenbanking/sdk\";\n\nconst kob = new KangOpenBanking({ apiKey: process.env.KOB_API_KEY });\nconst res = await kob.request(\"GET\", \"/v1/admin/webhooks\");\nconsole.log(res);"
          },
          {
            "lang": "Python",
            "label": "Python",
            "source": "from kangopenbanking import KangOpenBanking\n\nkob = KangOpenBanking(api_key=os.environ[\"KOB_API_KEY\"])\nres = kob.request(\"GET\", \"/v1/admin/webhooks\")\nprint(res)"
          },
          {
            "lang": "PHP",
            "label": "PHP",
            "source": "<?php\n$kob = new KangOpenBanking\\KangOpenBanking(getenv('KOB_API_KEY'));\n$res = $kob->request('GET', '/v1/admin/webhooks');\nprint_r($res);"
          }
        ]
      }
    },
    "/v1/admin/transactions/review": {
      "get": {
        "tags": [
          "Admin"
        ],
        "summary": "Review transactions",
        "operationId": "adminTransactionReview",
        "security": [
          {
            "bearerAuth": []
          }
        ],
        "parameters": [
          {
            "name": "sort_by",
            "in": "query",
            "schema": {
              "type": "string",
              "default": "created_at"
            },
            "description": "Sort field"
          },
          {
            "name": "sort_order",
            "in": "query",
            "schema": {
              "type": "string",
              "enum": [
                "asc",
                "desc"
              ],
              "default": "desc"
            },
            "description": "Sort direction"
          },
          {
            "name": "status",
            "in": "query",
            "schema": {
              "type": "string"
            }
          },
          {
            "$ref": "#/components/parameters/PageParam"
          },
          {
            "$ref": "#/components/parameters/LimitParam"
          },
          {
            "$ref": "#/components/parameters/CursorParam"
          },
          {
            "$ref": "#/components/parameters/RequestId"
          },
          {
            "$ref": "#/components/parameters/Traceparent"
          },
          {
            "$ref": "#/components/parameters/Tracestate"
          },
          {
            "$ref": "#/components/parameters/AcceptLanguage"
          }
        ],
        "responses": {
          "200": {
            "description": "Transactions for review",
            "content": {
              "application/json": {
                "schema": {
                  "allOf": [
                    {
                      "$ref": "#/components/schemas/PaginatedResponse"
                    },
                    {
                      "type": "object",
                      "properties": {
                        "data": {
                          "type": "array",
                          "items": {
                            "$ref": "#/components/schemas/Transaction"
                          }
                        }
                      }
                    }
                  ]
                },
                "example": {
                  "data": [
                    {
                      "transaction_id": "f1d6f4a0-1d4e-4a3a-9e0a-1a2b3c4d5e6f",
                      "amount": "25000",
                      "currency": "XAF",
                      "type": "debit",
                      "description": "Mobile Money transfer from 237650000000",
                      "balance_after": "1475000",
                      "booking_date": "2026-01-31",
                      "value_date": "2026-01-31",
                      "timestamp": "2026-01-31T12:00:00Z",
                      "AccountId": "XAF",
                      "TransactionId": "XAF",
                      "Amount": "1000",
                      "Currency": "XAF",
                      "CreditDebitIndicator": "Credit",
                      "BookingDateTime": "2026-01-31T12:00:00Z",
                      "ValueDateTime": "2026-01-31T12:00:00Z",
                      "TransactionInformation": "Payment for Invoice INV-2025-001 — Professional Services",
                      "Status": "Booked"
                    }
                  ],
                  "pagination": {
                    "page": 1,
                    "limit": 20,
                    "total": 150,
                    "has_next": true,
                    "next_cursor": "eyJpZCI6IjEyMyJ9"
                  },
                  "meta": {
                    "request_id": "550e8400-e29b-41d4-a716-446655440000",
                    "timestamp": "2025-03-27T12:00:00Z",
                    "api_version": "4.3.0"
                  }
                }
              }
            },
            "headers": {
              "x-fapi-interaction-id": {
                "$ref": "#/components/headers/XFapiInteractionIdResponse"
              },
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/XRateLimitLimit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/XRateLimitRemaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/XRateLimitReset"
              },
              "Cache-Control": {
                "$ref": "#/components/headers/CacheControl"
              },
              "ETag": {
                "$ref": "#/components/headers/ETag"
              },
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              },
              "traceparent": {
                "$ref": "#/components/headers/Traceparent"
              },
              "Content-Language": {
                "$ref": "#/components/headers/Content-Language"
              }
            }
          },
          "400": {
            "description": "Bad request",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              },
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                },
                "examples": {
                  "error": {
                    "$ref": "#/components/examples/ErrorBadRequest"
                  }
                }
              }
            },
            "headers": {
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/XRateLimitLimit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/XRateLimitRemaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/XRateLimitReset"
              },
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "403": {
            "$ref": "#/components/responses/Forbidden",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "404": {
            "$ref": "#/components/responses/NotFound",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "409": {
            "$ref": "#/components/responses/Conflict",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "429": {
            "$ref": "#/components/responses/TooManyRequests",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "500": {
            "$ref": "#/components/responses/InternalServerError",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          }
        },
        "x-codeSamples": [
          {
            "lang": "cURL",
            "label": "cURL",
            "source": "curl -X GET \"https://api.kangopenbanking.com/v1/admin/transactions/review\" \\\n  -H \"Authorization: Bearer $KOB_ACCESS_TOKEN\" \\\n  -H \"Content-Type: application/json\""
          },
          {
            "lang": "JavaScript",
            "label": "Node.js",
            "source": "import { KangOpenBanking } from \"@kangopenbanking/sdk\";\n\nconst kob = new KangOpenBanking({ apiKey: process.env.KOB_API_KEY });\nconst res = await kob.request(\"GET\", \"/v1/admin/transactions/review\");\nconsole.log(res);"
          },
          {
            "lang": "Python",
            "label": "Python",
            "source": "from kangopenbanking import KangOpenBanking\n\nkob = KangOpenBanking(api_key=os.environ[\"KOB_API_KEY\"])\nres = kob.request(\"GET\", \"/v1/admin/transactions/review\")\nprint(res)"
          },
          {
            "lang": "PHP",
            "label": "PHP",
            "source": "<?php\n$kob = new KangOpenBanking\\KangOpenBanking(getenv('KOB_API_KEY'));\n$res = $kob->request('GET', '/v1/admin/transactions/review');\nprint_r($res);"
          }
        ]
      }
    },
    "/v1/admin/loans": {
      "get": {
        "tags": [
          "Admin"
        ],
        "summary": "List all loans (admin)",
        "operationId": "adminListLoans",
        "security": [
          {
            "bearerAuth": []
          }
        ],
        "parameters": [
          {
            "name": "sort_by",
            "in": "query",
            "schema": {
              "type": "string",
              "default": "created_at"
            },
            "description": "Sort field"
          },
          {
            "name": "sort_order",
            "in": "query",
            "schema": {
              "type": "string",
              "enum": [
                "asc",
                "desc"
              ],
              "default": "desc"
            },
            "description": "Sort direction"
          },
          {
            "name": "status",
            "in": "query",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "user_id",
            "in": "query",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "product_id",
            "in": "query",
            "schema": {
              "type": "string"
            }
          },
          {
            "$ref": "#/components/parameters/PageParam"
          },
          {
            "$ref": "#/components/parameters/LimitParam"
          },
          {
            "$ref": "#/components/parameters/CursorParam"
          },
          {
            "$ref": "#/components/parameters/RequestId"
          },
          {
            "$ref": "#/components/parameters/Traceparent"
          },
          {
            "$ref": "#/components/parameters/Tracestate"
          },
          {
            "$ref": "#/components/parameters/AcceptLanguage"
          }
        ],
        "responses": {
          "200": {
            "description": "Loan applications with accounts",
            "content": {
              "application/json": {
                "schema": {
                  "allOf": [
                    {
                      "$ref": "#/components/schemas/PaginatedResponse"
                    },
                    {
                      "type": "object",
                      "properties": {
                        "data": {
                          "type": "array",
                          "items": {
                            "$ref": "#/components/schemas/LoanApplication"
                          }
                        }
                      }
                    }
                  ]
                },
                "example": {
                  "data": [
                    {
                      "id": "f1d6f4a0-1d4e-4a3a-9e0a-1a2b3c4d5e6f",
                      "product_id": "f1d6f4a0-1d4e-4a3a-9e0a-1a2b3c4d5e6f",
                      "amount": "1000000",
                      "currency": "XAF",
                      "term_months": 12,
                      "interest_rate": 15,
                      "status": "applied",
                      "purpose": "Business expansion",
                      "created_at": "2026-01-31T12:00:00Z"
                    }
                  ],
                  "pagination": {
                    "page": 1,
                    "limit": 20,
                    "total": 150,
                    "has_next": true,
                    "next_cursor": "eyJpZCI6IjEyMyJ9"
                  },
                  "meta": {
                    "request_id": "550e8400-e29b-41d4-a716-446655440000",
                    "timestamp": "2025-03-27T12:00:00Z",
                    "api_version": "4.3.0"
                  }
                }
              }
            },
            "headers": {
              "x-fapi-interaction-id": {
                "$ref": "#/components/headers/XFapiInteractionIdResponse"
              },
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/XRateLimitLimit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/XRateLimitRemaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/XRateLimitReset"
              },
              "Cache-Control": {
                "$ref": "#/components/headers/CacheControl"
              },
              "ETag": {
                "$ref": "#/components/headers/ETag"
              },
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              },
              "traceparent": {
                "$ref": "#/components/headers/Traceparent"
              },
              "Content-Language": {
                "$ref": "#/components/headers/Content-Language"
              }
            }
          },
          "400": {
            "description": "Bad request",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              },
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                },
                "examples": {
                  "error": {
                    "$ref": "#/components/examples/ErrorBadRequest"
                  }
                }
              }
            },
            "headers": {
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/XRateLimitLimit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/XRateLimitRemaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/XRateLimitReset"
              },
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "403": {
            "$ref": "#/components/responses/Forbidden",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "404": {
            "$ref": "#/components/responses/NotFound",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "409": {
            "$ref": "#/components/responses/Conflict",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "429": {
            "$ref": "#/components/responses/TooManyRequests",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "500": {
            "$ref": "#/components/responses/InternalServerError",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          }
        },
        "x-codeSamples": [
          {
            "lang": "cURL",
            "label": "cURL",
            "source": "curl -X GET \"https://api.kangopenbanking.com/v1/admin/loans\" \\\n  -H \"Authorization: Bearer $KOB_ACCESS_TOKEN\" \\\n  -H \"Content-Type: application/json\""
          },
          {
            "lang": "JavaScript",
            "label": "Node.js",
            "source": "import { KangOpenBanking } from \"@kangopenbanking/sdk\";\n\nconst kob = new KangOpenBanking({ apiKey: process.env.KOB_API_KEY });\nconst res = await kob.request(\"GET\", \"/v1/admin/loans\");\nconsole.log(res);"
          },
          {
            "lang": "Python",
            "label": "Python",
            "source": "from kangopenbanking import KangOpenBanking\n\nkob = KangOpenBanking(api_key=os.environ[\"KOB_API_KEY\"])\nres = kob.request(\"GET\", \"/v1/admin/loans\")\nprint(res)"
          },
          {
            "lang": "PHP",
            "label": "PHP",
            "source": "<?php\n$kob = new KangOpenBanking\\KangOpenBanking(getenv('KOB_API_KEY'));\n$res = $kob->request('GET', '/v1/admin/loans');\nprint_r($res);"
          }
        ]
      }
    },
    "/v1/admin/savings": {
      "get": {
        "tags": [
          "Admin"
        ],
        "summary": "List all savings accounts (admin)",
        "operationId": "adminListSavings",
        "security": [
          {
            "bearerAuth": []
          }
        ],
        "parameters": [
          {
            "name": "sort_by",
            "in": "query",
            "schema": {
              "type": "string",
              "default": "created_at"
            },
            "description": "Sort field"
          },
          {
            "name": "sort_order",
            "in": "query",
            "schema": {
              "type": "string",
              "enum": [
                "asc",
                "desc"
              ],
              "default": "desc"
            },
            "description": "Sort direction"
          },
          {
            "name": "status",
            "in": "query",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "user_id",
            "in": "query",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "product_id",
            "in": "query",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "account_type",
            "in": "query",
            "schema": {
              "type": "string"
            }
          },
          {
            "$ref": "#/components/parameters/PageParam"
          },
          {
            "$ref": "#/components/parameters/LimitParam"
          },
          {
            "$ref": "#/components/parameters/CursorParam"
          },
          {
            "$ref": "#/components/parameters/RequestId"
          },
          {
            "$ref": "#/components/parameters/Traceparent"
          },
          {
            "$ref": "#/components/parameters/Tracestate"
          },
          {
            "$ref": "#/components/parameters/AcceptLanguage"
          }
        ],
        "responses": {
          "200": {
            "description": "Savings accounts with products",
            "content": {
              "application/json": {
                "schema": {
                  "allOf": [
                    {
                      "$ref": "#/components/schemas/PaginatedResponse"
                    },
                    {
                      "type": "object",
                      "properties": {
                        "data": {
                          "type": "array",
                          "items": {
                            "$ref": "#/components/schemas/SavingsAccount"
                          }
                        }
                      }
                    }
                  ]
                },
                "example": {
                  "data": [
                    {
                      "account_id": "f1d6f4a0-1d4e-4a3a-9e0a-1a2b3c4d5e6f",
                      "product_id": "XAF",
                      "account_number": "XAF",
                      "account_holder_name": "XAF",
                      "balance": "1000",
                      "currency": "XAF",
                      "status": "active",
                      "interest_rate": 1,
                      "opened_date": "2026-01-31",
                      "maturity_date": "2026-01-31",
                      "created_at": "2026-01-31T12:00:00Z",
                      "updated_at": "2026-01-31T12:00:00Z"
                    }
                  ],
                  "pagination": {
                    "page": 1,
                    "limit": 20,
                    "total": 150,
                    "has_next": true,
                    "next_cursor": "eyJpZCI6IjEyMyJ9"
                  },
                  "meta": {
                    "request_id": "550e8400-e29b-41d4-a716-446655440000",
                    "timestamp": "2025-03-27T12:00:00Z",
                    "api_version": "4.3.0"
                  }
                }
              }
            },
            "headers": {
              "x-fapi-interaction-id": {
                "$ref": "#/components/headers/XFapiInteractionIdResponse"
              },
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/XRateLimitLimit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/XRateLimitRemaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/XRateLimitReset"
              },
              "Cache-Control": {
                "$ref": "#/components/headers/CacheControl"
              },
              "ETag": {
                "$ref": "#/components/headers/ETag"
              },
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              },
              "traceparent": {
                "$ref": "#/components/headers/Traceparent"
              },
              "Content-Language": {
                "$ref": "#/components/headers/Content-Language"
              }
            }
          },
          "400": {
            "description": "Bad request",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              },
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                },
                "examples": {
                  "error": {
                    "$ref": "#/components/examples/ErrorBadRequest"
                  }
                }
              }
            },
            "headers": {
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/XRateLimitLimit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/XRateLimitRemaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/XRateLimitReset"
              },
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "403": {
            "$ref": "#/components/responses/Forbidden",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "404": {
            "$ref": "#/components/responses/NotFound",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "409": {
            "$ref": "#/components/responses/Conflict",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "429": {
            "$ref": "#/components/responses/TooManyRequests",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "500": {
            "$ref": "#/components/responses/InternalServerError",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          }
        },
        "x-codeSamples": [
          {
            "lang": "cURL",
            "label": "cURL",
            "source": "curl -X GET \"https://api.kangopenbanking.com/v1/admin/savings\" \\\n  -H \"Authorization: Bearer $KOB_ACCESS_TOKEN\" \\\n  -H \"Content-Type: application/json\""
          },
          {
            "lang": "JavaScript",
            "label": "Node.js",
            "source": "import { KangOpenBanking } from \"@kangopenbanking/sdk\";\n\nconst kob = new KangOpenBanking({ apiKey: process.env.KOB_API_KEY });\nconst res = await kob.request(\"GET\", \"/v1/admin/savings\");\nconsole.log(res);"
          },
          {
            "lang": "Python",
            "label": "Python",
            "source": "from kangopenbanking import KangOpenBanking\n\nkob = KangOpenBanking(api_key=os.environ[\"KOB_API_KEY\"])\nres = kob.request(\"GET\", \"/v1/admin/savings\")\nprint(res)"
          },
          {
            "lang": "PHP",
            "label": "PHP",
            "source": "<?php\n$kob = new KangOpenBanking\\KangOpenBanking(getenv('KOB_API_KEY'));\n$res = $kob->request('GET', '/v1/admin/savings');\nprint_r($res);"
          }
        ]
      }
    },
    "/v1/admin/consents": {
      "get": {
        "tags": [
          "Admin"
        ],
        "summary": "List all consents (admin)",
        "operationId": "adminListConsents",
        "security": [
          {
            "bearerAuth": []
          }
        ],
        "parameters": [
          {
            "name": "sort_by",
            "in": "query",
            "schema": {
              "type": "string",
              "default": "created_at"
            },
            "description": "Sort field"
          },
          {
            "name": "sort_order",
            "in": "query",
            "schema": {
              "type": "string",
              "enum": [
                "asc",
                "desc"
              ],
              "default": "desc"
            },
            "description": "Sort direction"
          },
          {
            "name": "type",
            "in": "query",
            "schema": {
              "type": "string",
              "enum": [
                "aisp",
                "pisp"
              ],
              "default": "aisp"
            }
          },
          {
            "name": "status",
            "in": "query",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "user_id",
            "in": "query",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "client_id",
            "in": "query",
            "schema": {
              "type": "string"
            }
          },
          {
            "$ref": "#/components/parameters/PageParam"
          },
          {
            "$ref": "#/components/parameters/LimitParam"
          },
          {
            "$ref": "#/components/parameters/CursorParam"
          },
          {
            "$ref": "#/components/parameters/RequestId"
          },
          {
            "$ref": "#/components/parameters/Traceparent"
          },
          {
            "$ref": "#/components/parameters/Tracestate"
          },
          {
            "$ref": "#/components/parameters/AcceptLanguage"
          }
        ],
        "responses": {
          "200": {
            "description": "AISP or PISP consents",
            "content": {
              "application/json": {
                "schema": {
                  "allOf": [
                    {
                      "$ref": "#/components/schemas/PaginatedResponse"
                    },
                    {
                      "type": "object",
                      "properties": {
                        "data": {
                          "type": "array",
                          "items": {
                            "$ref": "#/components/schemas/Consent"
                          }
                        }
                      }
                    }
                  ]
                },
                "example": {
                  "data": [
                    {
                      "consent_id": "XAF",
                      "status": "AwaitingAuthorisation",
                      "permissions": [
                        "XAF"
                      ],
                      "expiration_date": "2026-01-31T12:00:00Z",
                      "created_at": "2026-01-31T12:00:00Z"
                    }
                  ],
                  "pagination": {
                    "page": 1,
                    "limit": 20,
                    "total": 150,
                    "has_next": true,
                    "next_cursor": "eyJpZCI6IjEyMyJ9"
                  },
                  "meta": {
                    "request_id": "550e8400-e29b-41d4-a716-446655440000",
                    "timestamp": "2025-03-27T12:00:00Z",
                    "api_version": "4.3.0"
                  }
                }
              }
            },
            "headers": {
              "x-fapi-interaction-id": {
                "$ref": "#/components/headers/XFapiInteractionIdResponse"
              },
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/XRateLimitLimit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/XRateLimitRemaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/XRateLimitReset"
              },
              "Cache-Control": {
                "$ref": "#/components/headers/CacheControl"
              },
              "ETag": {
                "$ref": "#/components/headers/ETag"
              },
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              },
              "traceparent": {
                "$ref": "#/components/headers/Traceparent"
              },
              "Content-Language": {
                "$ref": "#/components/headers/Content-Language"
              }
            }
          },
          "400": {
            "description": "Bad request",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              },
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                },
                "examples": {
                  "error": {
                    "$ref": "#/components/examples/ErrorBadRequest"
                  }
                }
              }
            },
            "headers": {
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/XRateLimitLimit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/XRateLimitRemaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/XRateLimitReset"
              },
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "403": {
            "$ref": "#/components/responses/Forbidden",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "404": {
            "$ref": "#/components/responses/NotFound",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "409": {
            "$ref": "#/components/responses/Conflict",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "429": {
            "$ref": "#/components/responses/TooManyRequests",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "500": {
            "$ref": "#/components/responses/InternalServerError",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          }
        },
        "x-codeSamples": [
          {
            "lang": "cURL",
            "label": "cURL",
            "source": "curl -X GET \"https://api.kangopenbanking.com/v1/admin/consents\" \\\n  -H \"Authorization: Bearer $KOB_ACCESS_TOKEN\" \\\n  -H \"Content-Type: application/json\""
          },
          {
            "lang": "JavaScript",
            "label": "Node.js",
            "source": "import { KangOpenBanking } from \"@kangopenbanking/sdk\";\n\nconst kob = new KangOpenBanking({ apiKey: process.env.KOB_API_KEY });\nconst res = await kob.request(\"GET\", \"/v1/admin/consents\");\nconsole.log(res);"
          },
          {
            "lang": "Python",
            "label": "Python",
            "source": "from kangopenbanking import KangOpenBanking\n\nkob = KangOpenBanking(api_key=os.environ[\"KOB_API_KEY\"])\nres = kob.request(\"GET\", \"/v1/admin/consents\")\nprint(res)"
          },
          {
            "lang": "PHP",
            "label": "PHP",
            "source": "<?php\n$kob = new KangOpenBanking\\KangOpenBanking(getenv('KOB_API_KEY'));\n$res = $kob->request('GET', '/v1/admin/consents');\nprint_r($res);"
          }
        ]
      }
    },
    "/v1/admin/staff/assign": {
      "post": {
        "tags": [
          "Admin"
        ],
        "summary": "Assign staff to branch",
        "operationId": "adminAssignStaff",
        "security": [
          {
            "bearerAuth": []
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "required": [
                  "user_id",
                  "branch_id",
                  "role"
                ],
                "properties": {
                  "user_id": {
                    "type": "string"
                  },
                  "branch_id": {
                    "type": "string"
                  },
                  "role": {
                    "type": "string"
                  }
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Staff assigned to branch",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "success": {
                      "type": "boolean",
                      "example": true
                    },
                    "message": {
                      "type": "string"
                    }
                  }
                },
                "example": {
                  "success": true,
                  "message": "string"
                }
              }
            },
            "headers": {
              "x-fapi-interaction-id": {
                "$ref": "#/components/headers/XFapiInteractionIdResponse"
              },
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/XRateLimitLimit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/XRateLimitRemaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/XRateLimitReset"
              },
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              },
              "traceparent": {
                "$ref": "#/components/headers/Traceparent"
              },
              "Content-Language": {
                "$ref": "#/components/headers/Content-Language"
              }
            }
          },
          "400": {
            "description": "Bad request",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              },
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                },
                "examples": {
                  "error": {
                    "$ref": "#/components/examples/ErrorBadRequest"
                  }
                }
              }
            },
            "headers": {
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/XRateLimitLimit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/XRateLimitRemaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/XRateLimitReset"
              },
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "403": {
            "$ref": "#/components/responses/Forbidden",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "404": {
            "$ref": "#/components/responses/NotFound",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "409": {
            "$ref": "#/components/responses/Conflict",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "429": {
            "$ref": "#/components/responses/TooManyRequests",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "500": {
            "$ref": "#/components/responses/InternalServerError",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          }
        },
        "parameters": [
          {
            "$ref": "#/components/parameters/RequestId"
          },
          {
            "$ref": "#/components/parameters/Traceparent"
          },
          {
            "$ref": "#/components/parameters/Tracestate"
          },
          {
            "$ref": "#/components/parameters/AcceptLanguage"
          }
        ],
        "x-codeSamples": [
          {
            "lang": "cURL",
            "label": "cURL",
            "source": "curl -X POST \"https://api.kangopenbanking.com/v1/admin/staff/assign\" \\\n  -H \"Authorization: Bearer $KOB_ACCESS_TOKEN\" \\\n  -H \"Content-Type: application/json\" \\\n  -d '{}'"
          },
          {
            "lang": "JavaScript",
            "label": "Node.js",
            "source": "import { KangOpenBanking } from \"@kangopenbanking/sdk\";\n\nconst kob = new KangOpenBanking({ apiKey: process.env.KOB_API_KEY });\nconst res = await kob.request(\"POST\", \"/v1/admin/staff/assign\", { /* payload */ });\nconsole.log(res);"
          },
          {
            "lang": "Python",
            "label": "Python",
            "source": "from kangopenbanking import KangOpenBanking\n\nkob = KangOpenBanking(api_key=os.environ[\"KOB_API_KEY\"])\nres = kob.request(\"POST\", \"/v1/admin/staff/assign\", json={})\nprint(res)"
          },
          {
            "lang": "PHP",
            "label": "PHP",
            "source": "<?php\n$kob = new KangOpenBanking\\KangOpenBanking(getenv('KOB_API_KEY'));\n$res = $kob->request('POST', '/v1/admin/staff/assign', []);\nprint_r($res);"
          }
        ]
      }
    },
    "/v1/admin/branches": {
      "get": {
        "tags": [
          "Admin"
        ],
        "summary": "List branches",
        "operationId": "adminManageBranches",
        "security": [
          {
            "bearerAuth": []
          }
        ],
        "responses": {
          "200": {
            "description": "Branches list",
            "content": {
              "application/json": {
                "schema": {
                  "allOf": [
                    {
                      "$ref": "#/components/schemas/PaginatedResponse"
                    },
                    {
                      "type": "object",
                      "properties": {
                        "data": {
                          "type": "array",
                          "items": {}
                        }
                      }
                    }
                  ]
                },
                "example": {
                  "data": [
                    {}
                  ],
                  "pagination": {
                    "page": 1,
                    "limit": 20,
                    "total": 150,
                    "has_next": true,
                    "next_cursor": "eyJpZCI6IjEyMyJ9"
                  },
                  "meta": {
                    "request_id": "550e8400-e29b-41d4-a716-446655440000",
                    "timestamp": "2025-03-27T12:00:00Z",
                    "api_version": "4.3.0"
                  }
                }
              }
            },
            "headers": {
              "x-fapi-interaction-id": {
                "$ref": "#/components/headers/XFapiInteractionIdResponse"
              },
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/XRateLimitLimit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/XRateLimitRemaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/XRateLimitReset"
              },
              "Cache-Control": {
                "$ref": "#/components/headers/CacheControl"
              },
              "ETag": {
                "$ref": "#/components/headers/ETag"
              },
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              },
              "traceparent": {
                "$ref": "#/components/headers/Traceparent"
              },
              "Content-Language": {
                "$ref": "#/components/headers/Content-Language"
              }
            }
          },
          "400": {
            "description": "Bad request",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              },
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                },
                "examples": {
                  "error": {
                    "$ref": "#/components/examples/ErrorBadRequest"
                  }
                }
              }
            },
            "headers": {
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/XRateLimitLimit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/XRateLimitRemaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/XRateLimitReset"
              },
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "403": {
            "$ref": "#/components/responses/Forbidden",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "404": {
            "$ref": "#/components/responses/NotFound",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "409": {
            "$ref": "#/components/responses/Conflict",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "429": {
            "$ref": "#/components/responses/TooManyRequests",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "500": {
            "$ref": "#/components/responses/InternalServerError",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          }
        },
        "parameters": [
          {
            "$ref": "#/components/parameters/PageParam"
          },
          {
            "$ref": "#/components/parameters/LimitParam"
          },
          {
            "$ref": "#/components/parameters/CursorParam"
          },
          {
            "$ref": "#/components/parameters/RequestId"
          },
          {
            "$ref": "#/components/parameters/Traceparent"
          },
          {
            "$ref": "#/components/parameters/Tracestate"
          },
          {
            "$ref": "#/components/parameters/AcceptLanguage"
          }
        ],
        "x-codeSamples": [
          {
            "lang": "cURL",
            "label": "cURL",
            "source": "curl -X GET \"https://api.kangopenbanking.com/v1/admin/branches\" \\\n  -H \"Authorization: Bearer $KOB_ACCESS_TOKEN\" \\\n  -H \"Content-Type: application/json\""
          },
          {
            "lang": "JavaScript",
            "label": "Node.js",
            "source": "import { KangOpenBanking } from \"@kangopenbanking/sdk\";\n\nconst kob = new KangOpenBanking({ apiKey: process.env.KOB_API_KEY });\nconst res = await kob.request(\"GET\", \"/v1/admin/branches\");\nconsole.log(res);"
          },
          {
            "lang": "Python",
            "label": "Python",
            "source": "from kangopenbanking import KangOpenBanking\n\nkob = KangOpenBanking(api_key=os.environ[\"KOB_API_KEY\"])\nres = kob.request(\"GET\", \"/v1/admin/branches\")\nprint(res)"
          },
          {
            "lang": "PHP",
            "label": "PHP",
            "source": "<?php\n$kob = new KangOpenBanking\\KangOpenBanking(getenv('KOB_API_KEY'));\n$res = $kob->request('GET', '/v1/admin/branches');\nprint_r($res);"
          }
        ]
      },
      "post": {
        "tags": [
          "Admin"
        ],
        "summary": "Create branch",
        "operationId": "adminCreateBranch",
        "security": [
          {
            "bearerAuth": []
          }
        ],
        "parameters": [
          {
            "name": "Idempotency-Key",
            "in": "header",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid"
            },
            "description": "Required on all POST/PUT endpoints. Unique key for idempotent request processing (UUID v4 recommended). Keys expire after 24 hours."
          },
          {
            "$ref": "#/components/parameters/RequestId"
          },
          {
            "$ref": "#/components/parameters/Traceparent"
          },
          {
            "$ref": "#/components/parameters/Tracestate"
          },
          {
            "$ref": "#/components/parameters/AcceptLanguage"
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object"
              }
            }
          }
        },
        "responses": {
          "201": {
            "description": "Branch created",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "id": {
                      "type": "string",
                      "format": "uuid"
                    },
                    "name": {
                      "type": "string"
                    },
                    "city": {
                      "type": "string"
                    },
                    "created_at": {
                      "type": "string",
                      "format": "date-time"
                    }
                  }
                },
                "example": {
                  "id": "00000000-0000-4000-8000-000000000000",
                  "name": "string",
                  "city": "string",
                  "created_at": "2026-01-01T00:00:00Z"
                }
              }
            },
            "headers": {
              "x-fapi-interaction-id": {
                "$ref": "#/components/headers/XFapiInteractionIdResponse"
              },
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/XRateLimitLimit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/XRateLimitRemaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/XRateLimitReset"
              },
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              },
              "traceparent": {
                "$ref": "#/components/headers/Traceparent"
              },
              "Content-Language": {
                "$ref": "#/components/headers/Content-Language"
              }
            }
          },
          "400": {
            "description": "Bad request",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              },
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                },
                "examples": {
                  "error": {
                    "$ref": "#/components/examples/ErrorBadRequest"
                  }
                }
              }
            },
            "headers": {
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/XRateLimitLimit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/XRateLimitRemaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/XRateLimitReset"
              },
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "403": {
            "$ref": "#/components/responses/Forbidden",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "404": {
            "$ref": "#/components/responses/NotFound",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "409": {
            "$ref": "#/components/responses/Conflict",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "429": {
            "$ref": "#/components/responses/TooManyRequests",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "500": {
            "$ref": "#/components/responses/InternalServerError",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          }
        },
        "x-codeSamples": [
          {
            "lang": "cURL",
            "label": "cURL",
            "source": "curl -X POST \"https://api.kangopenbanking.com/v1/admin/branches\" \\\n  -H \"Authorization: Bearer $KOB_ACCESS_TOKEN\" \\\n  -H \"Content-Type: application/json\" \\\n  -d '{}'"
          },
          {
            "lang": "JavaScript",
            "label": "Node.js",
            "source": "import { KangOpenBanking } from \"@kangopenbanking/sdk\";\n\nconst kob = new KangOpenBanking({ apiKey: process.env.KOB_API_KEY });\nconst res = await kob.request(\"POST\", \"/v1/admin/branches\", { /* payload */ });\nconsole.log(res);"
          },
          {
            "lang": "Python",
            "label": "Python",
            "source": "from kangopenbanking import KangOpenBanking\n\nkob = KangOpenBanking(api_key=os.environ[\"KOB_API_KEY\"])\nres = kob.request(\"POST\", \"/v1/admin/branches\", json={})\nprint(res)"
          },
          {
            "lang": "PHP",
            "label": "PHP",
            "source": "<?php\n$kob = new KangOpenBanking\\KangOpenBanking(getenv('KOB_API_KEY'));\n$res = $kob->request('POST', '/v1/admin/branches', []);\nprint_r($res);"
          }
        ]
      }
    },
    "/v1/communications/send": {
      "post": {
        "tags": [
          "Communications"
        ],
        "summary": "Send communication",
        "operationId": "sendCommunication",
        "security": [
          {
            "bearerAuth": []
          }
        ],
        "parameters": [
          {
            "name": "Idempotency-Key",
            "in": "header",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid"
            },
            "description": "Required on all POST/PUT endpoints. Unique key for idempotent request processing (UUID v4 recommended). Keys expire after 24 hours."
          },
          {
            "$ref": "#/components/parameters/RequestId"
          },
          {
            "$ref": "#/components/parameters/Traceparent"
          },
          {
            "$ref": "#/components/parameters/Tracestate"
          },
          {
            "$ref": "#/components/parameters/AcceptLanguage"
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "required": [
                  "type",
                  "recipient",
                  "body"
                ],
                "properties": {
                  "type": {
                    "type": "string",
                    "enum": [
                      "email",
                      "sms",
                      "push"
                    ]
                  },
                  "recipient": {
                    "type": "string"
                  },
                  "subject": {
                    "type": "string"
                  },
                  "body": {
                    "type": "string"
                  }
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Communication sent",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "success": {
                      "type": "boolean",
                      "example": true
                    },
                    "message": {
                      "type": "string"
                    }
                  }
                },
                "example": {
                  "success": true,
                  "message": "string"
                }
              }
            },
            "headers": {
              "x-fapi-interaction-id": {
                "$ref": "#/components/headers/XFapiInteractionIdResponse"
              },
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/XRateLimitLimit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/XRateLimitRemaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/XRateLimitReset"
              },
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              },
              "traceparent": {
                "$ref": "#/components/headers/Traceparent"
              },
              "Content-Language": {
                "$ref": "#/components/headers/Content-Language"
              }
            }
          },
          "400": {
            "description": "Bad request",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              },
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                },
                "examples": {
                  "error": {
                    "$ref": "#/components/examples/ErrorBadRequest"
                  }
                }
              }
            },
            "headers": {
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/XRateLimitLimit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/XRateLimitRemaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/XRateLimitReset"
              },
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "403": {
            "$ref": "#/components/responses/Forbidden",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "404": {
            "$ref": "#/components/responses/NotFound",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "409": {
            "$ref": "#/components/responses/Conflict",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "429": {
            "$ref": "#/components/responses/TooManyRequests",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "500": {
            "$ref": "#/components/responses/InternalServerError",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          }
        },
        "x-codeSamples": [
          {
            "lang": "cURL",
            "label": "cURL",
            "source": "curl -X POST \"https://api.kangopenbanking.com/v1/communications/send\" \\\n  -H \"Authorization: Bearer $KOB_ACCESS_TOKEN\" \\\n  -H \"Content-Type: application/json\" \\\n  -d '{}'"
          },
          {
            "lang": "JavaScript",
            "label": "Node.js",
            "source": "import { KangOpenBanking } from \"@kangopenbanking/sdk\";\n\nconst kob = new KangOpenBanking({ apiKey: process.env.KOB_API_KEY });\nconst res = await kob.request(\"POST\", \"/v1/communications/send\", { /* payload */ });\nconsole.log(res);"
          },
          {
            "lang": "Python",
            "label": "Python",
            "source": "from kangopenbanking import KangOpenBanking\n\nkob = KangOpenBanking(api_key=os.environ[\"KOB_API_KEY\"])\nres = kob.request(\"POST\", \"/v1/communications/send\", json={})\nprint(res)"
          },
          {
            "lang": "PHP",
            "label": "PHP",
            "source": "<?php\n$kob = new KangOpenBanking\\KangOpenBanking(getenv('KOB_API_KEY'));\n$res = $kob->request('POST', '/v1/communications/send', []);\nprint_r($res);"
          }
        ]
      }
    },
    "/v1/communications/bulk": {
      "post": {
        "tags": [
          "Communications"
        ],
        "summary": "Send bulk communication",
        "operationId": "sendBulkCommunication",
        "security": [
          {
            "bearerAuth": []
          }
        ],
        "parameters": [
          {
            "name": "Idempotency-Key",
            "in": "header",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid"
            },
            "description": "Required on all POST/PUT endpoints. Unique key for idempotent request processing (UUID v4 recommended). Keys expire after 24 hours."
          },
          {
            "$ref": "#/components/parameters/RequestId"
          },
          {
            "$ref": "#/components/parameters/Traceparent"
          },
          {
            "$ref": "#/components/parameters/Tracestate"
          },
          {
            "$ref": "#/components/parameters/AcceptLanguage"
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Bulk communication queued",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "queued": {
                      "type": "integer"
                    },
                    "batch_id": {
                      "type": "string"
                    },
                    "status": {
                      "type": "string",
                      "example": "queued"
                    }
                  }
                },
                "example": {
                  "queued": 0,
                  "batch_id": "string",
                  "status": "queued"
                }
              }
            },
            "headers": {
              "x-fapi-interaction-id": {
                "$ref": "#/components/headers/XFapiInteractionIdResponse"
              },
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/XRateLimitLimit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/XRateLimitRemaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/XRateLimitReset"
              },
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              },
              "traceparent": {
                "$ref": "#/components/headers/Traceparent"
              },
              "Content-Language": {
                "$ref": "#/components/headers/Content-Language"
              }
            }
          },
          "400": {
            "description": "Bad request",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              },
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                },
                "examples": {
                  "error": {
                    "$ref": "#/components/examples/ErrorBadRequest"
                  }
                }
              }
            },
            "headers": {
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/XRateLimitLimit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/XRateLimitRemaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/XRateLimitReset"
              },
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "403": {
            "$ref": "#/components/responses/Forbidden",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "404": {
            "$ref": "#/components/responses/NotFound",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "409": {
            "$ref": "#/components/responses/Conflict",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "429": {
            "$ref": "#/components/responses/TooManyRequests",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "500": {
            "$ref": "#/components/responses/InternalServerError",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          }
        },
        "x-codeSamples": [
          {
            "lang": "cURL",
            "label": "cURL",
            "source": "curl -X POST \"https://api.kangopenbanking.com/v1/communications/bulk\" \\\n  -H \"Authorization: Bearer $KOB_ACCESS_TOKEN\" \\\n  -H \"Content-Type: application/json\" \\\n  -d '{}'"
          },
          {
            "lang": "JavaScript",
            "label": "Node.js",
            "source": "import { KangOpenBanking } from \"@kangopenbanking/sdk\";\n\nconst kob = new KangOpenBanking({ apiKey: process.env.KOB_API_KEY });\nconst res = await kob.request(\"POST\", \"/v1/communications/bulk\", { /* payload */ });\nconsole.log(res);"
          },
          {
            "lang": "Python",
            "label": "Python",
            "source": "from kangopenbanking import KangOpenBanking\n\nkob = KangOpenBanking(api_key=os.environ[\"KOB_API_KEY\"])\nres = kob.request(\"POST\", \"/v1/communications/bulk\", json={})\nprint(res)"
          },
          {
            "lang": "PHP",
            "label": "PHP",
            "source": "<?php\n$kob = new KangOpenBanking\\KangOpenBanking(getenv('KOB_API_KEY'));\n$res = $kob->request('POST', '/v1/communications/bulk', []);\nprint_r($res);"
          }
        ]
      }
    },
    "/v1/invoices/generate": {
      "post": {
        "tags": [
          "Settlement"
        ],
        "summary": "Generate invoice",
        "operationId": "generateInvoice",
        "security": [
          {
            "bearerAuth": []
          }
        ],
        "parameters": [
          {
            "name": "Idempotency-Key",
            "in": "header",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid"
            },
            "description": "Required on all POST/PUT endpoints. Unique key for idempotent request processing (UUID v4 recommended). Keys expire after 24 hours."
          },
          {
            "$ref": "#/components/parameters/RequestId"
          },
          {
            "$ref": "#/components/parameters/Traceparent"
          },
          {
            "$ref": "#/components/parameters/Tracestate"
          },
          {
            "$ref": "#/components/parameters/AcceptLanguage"
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object"
              }
            }
          }
        },
        "responses": {
          "201": {
            "description": "Invoice generated",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "id": {
                      "type": "string",
                      "format": "uuid"
                    },
                    "invoice_number": {
                      "type": "string"
                    },
                    "amount": {
                      "type": "string",
                      "pattern": "^[0-9]{1,15}$",
                      "description": "Represented as a string integer in the currency's minor unit (XAF has no subunits). Must be consistent with the currency field."
                    },
                    "currency": {
                      "type": "string",
                      "enum": [
                        "XAF",
                        "XOF",
                        "USD",
                        "EUR",
                        "GBP",
                        "CNY",
                        "NGN",
                        "GHS",
                        "KES",
                        "ZAR"
                      ],
                      "default": "XAF",
                      "description": "ISO 4217 currency code. Default is XAF (Central African CFA Franc)."
                    },
                    "status": {
                      "type": "string"
                    },
                    "created_at": {
                      "type": "string",
                      "format": "date-time"
                    }
                  }
                },
                "example": {
                  "id": "00000000-0000-4000-8000-000000000000",
                  "invoice_number": "string",
                  "amount": "1000",
                  "currency": "XAF",
                  "status": "string",
                  "created_at": "2026-01-01T00:00:00Z"
                }
              }
            },
            "headers": {
              "x-fapi-interaction-id": {
                "$ref": "#/components/headers/XFapiInteractionIdResponse"
              },
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/XRateLimitLimit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/XRateLimitRemaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/XRateLimitReset"
              },
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              },
              "X-Idempotent-Replay": {
                "$ref": "#/components/headers/X-Idempotent-Replay"
              },
              "X-Idempotency-Status": {
                "$ref": "#/components/headers/X-Idempotency-Status"
              },
              "traceparent": {
                "$ref": "#/components/headers/Traceparent"
              },
              "Content-Language": {
                "$ref": "#/components/headers/Content-Language"
              }
            }
          },
          "400": {
            "description": "Bad request",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              },
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                },
                "examples": {
                  "error": {
                    "$ref": "#/components/examples/ErrorBadRequest"
                  }
                }
              }
            },
            "headers": {
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/XRateLimitLimit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/XRateLimitRemaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/XRateLimitReset"
              },
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "403": {
            "$ref": "#/components/responses/Forbidden",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "404": {
            "$ref": "#/components/responses/NotFound",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "409": {
            "$ref": "#/components/responses/Conflict",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "429": {
            "$ref": "#/components/responses/TooManyRequests",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "500": {
            "$ref": "#/components/responses/InternalServerError",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          }
        },
        "x-codeSamples": [
          {
            "lang": "cURL",
            "label": "cURL",
            "source": "curl -X POST \"https://api.kangopenbanking.com/v1/invoices/generate\" \\\n  -H \"Authorization: Bearer $KOB_ACCESS_TOKEN\" \\\n  -H \"Content-Type: application/json\" \\\n  -d '{}'"
          },
          {
            "lang": "JavaScript",
            "label": "Node.js",
            "source": "import { KangOpenBanking } from \"@kangopenbanking/sdk\";\n\nconst kob = new KangOpenBanking({ apiKey: process.env.KOB_API_KEY });\nconst res = await kob.request(\"POST\", \"/v1/invoices/generate\", { /* payload */ });\nconsole.log(res);"
          },
          {
            "lang": "Python",
            "label": "Python",
            "source": "from kangopenbanking import KangOpenBanking\n\nkob = KangOpenBanking(api_key=os.environ[\"KOB_API_KEY\"])\nres = kob.request(\"POST\", \"/v1/invoices/generate\", json={})\nprint(res)"
          },
          {
            "lang": "PHP",
            "label": "PHP",
            "source": "<?php\n$kob = new KangOpenBanking\\KangOpenBanking(getenv('KOB_API_KEY'));\n$res = $kob->request('POST', '/v1/invoices/generate', []);\nprint_r($res);"
          }
        ]
      }
    },
    "/v1/institutions/register": {
      "post": {
        "tags": [
          "Institution"
        ],
        "summary": "Register institution",
        "operationId": "institutionRegister",
        "security": [
          {
            "bearerAuth": []
          }
        ],
        "parameters": [
          {
            "name": "Idempotency-Key",
            "in": "header",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid"
            },
            "description": "Required on all POST/PUT endpoints. Unique key for idempotent request processing (UUID v4 recommended). Keys expire after 24 hours."
          },
          {
            "$ref": "#/components/parameters/RequestId"
          },
          {
            "$ref": "#/components/parameters/Traceparent"
          },
          {
            "$ref": "#/components/parameters/Tracestate"
          },
          {
            "$ref": "#/components/parameters/AcceptLanguage"
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object"
              }
            }
          }
        },
        "responses": {
          "201": {
            "description": "Institution registered",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "id": {
                      "type": "string",
                      "format": "uuid"
                    },
                    "name": {
                      "type": "string"
                    },
                    "status": {
                      "type": "string"
                    },
                    "created_at": {
                      "type": "string",
                      "format": "date-time"
                    }
                  }
                },
                "example": {
                  "id": "00000000-0000-4000-8000-000000000000",
                  "name": "string",
                  "status": "string",
                  "created_at": "2026-01-01T00:00:00Z"
                }
              }
            },
            "headers": {
              "x-fapi-interaction-id": {
                "$ref": "#/components/headers/XFapiInteractionIdResponse"
              },
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/XRateLimitLimit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/XRateLimitRemaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/XRateLimitReset"
              },
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              },
              "traceparent": {
                "$ref": "#/components/headers/Traceparent"
              },
              "Content-Language": {
                "$ref": "#/components/headers/Content-Language"
              }
            }
          },
          "400": {
            "description": "Bad request",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              },
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                },
                "examples": {
                  "error": {
                    "$ref": "#/components/examples/ErrorBadRequest"
                  }
                }
              }
            },
            "headers": {
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/XRateLimitLimit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/XRateLimitRemaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/XRateLimitReset"
              },
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "403": {
            "$ref": "#/components/responses/Forbidden",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "404": {
            "$ref": "#/components/responses/NotFound",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "409": {
            "$ref": "#/components/responses/Conflict",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "429": {
            "$ref": "#/components/responses/TooManyRequests",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "500": {
            "$ref": "#/components/responses/InternalServerError",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          }
        },
        "x-codeSamples": [
          {
            "lang": "cURL",
            "label": "cURL",
            "source": "curl -X POST \"https://api.kangopenbanking.com/v1/institutions/register\" \\\n  -H \"Authorization: Bearer $KOB_ACCESS_TOKEN\" \\\n  -H \"Content-Type: application/json\" \\\n  -d '{}'"
          },
          {
            "lang": "JavaScript",
            "label": "Node.js",
            "source": "import { KangOpenBanking } from \"@kangopenbanking/sdk\";\n\nconst kob = new KangOpenBanking({ apiKey: process.env.KOB_API_KEY });\nconst res = await kob.request(\"POST\", \"/v1/institutions/register\", { /* payload */ });\nconsole.log(res);"
          },
          {
            "lang": "Python",
            "label": "Python",
            "source": "from kangopenbanking import KangOpenBanking\n\nkob = KangOpenBanking(api_key=os.environ[\"KOB_API_KEY\"])\nres = kob.request(\"POST\", \"/v1/institutions/register\", json={})\nprint(res)"
          },
          {
            "lang": "PHP",
            "label": "PHP",
            "source": "<?php\n$kob = new KangOpenBanking\\KangOpenBanking(getenv('KOB_API_KEY'));\n$res = $kob->request('POST', '/v1/institutions/register', []);\nprint_r($res);"
          }
        ]
      }
    },
    "/v1/institutions/{institutionId}/clients": {
      "post": {
        "tags": [
          "Institution"
        ],
        "summary": "Create institution API client",
        "operationId": "institutionCreateClient",
        "security": [
          {
            "bearerAuth": []
          }
        ],
        "parameters": [
          {
            "name": "institutionId",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "Idempotency-Key",
            "in": "header",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid"
            },
            "description": "Required on all POST/PUT endpoints. Unique key for idempotent request processing (UUID v4 recommended). Keys expire after 24 hours."
          },
          {
            "$ref": "#/components/parameters/RequestId"
          },
          {
            "$ref": "#/components/parameters/Traceparent"
          },
          {
            "$ref": "#/components/parameters/Tracestate"
          },
          {
            "$ref": "#/components/parameters/AcceptLanguage"
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object"
              }
            }
          }
        },
        "responses": {
          "201": {
            "description": "Client created",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "client_id": {
                      "type": "string"
                    },
                    "client_secret": {
                      "type": "string",
                      "description": "Shown once"
                    },
                    "scopes": {
                      "type": "array",
                      "items": {
                        "type": "string"
                      }
                    },
                    "created_at": {
                      "type": "string",
                      "format": "date-time"
                    }
                  }
                },
                "example": {
                  "client_id": "string",
                  "client_secret": "string",
                  "scopes": [
                    "string"
                  ],
                  "created_at": "2026-01-01T00:00:00Z"
                }
              }
            },
            "headers": {
              "x-fapi-interaction-id": {
                "$ref": "#/components/headers/XFapiInteractionIdResponse"
              },
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/XRateLimitLimit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/XRateLimitRemaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/XRateLimitReset"
              },
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              },
              "traceparent": {
                "$ref": "#/components/headers/Traceparent"
              },
              "Content-Language": {
                "$ref": "#/components/headers/Content-Language"
              }
            }
          },
          "400": {
            "description": "Bad request",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              },
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                },
                "examples": {
                  "error": {
                    "$ref": "#/components/examples/ErrorBadRequest"
                  }
                }
              }
            },
            "headers": {
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/XRateLimitLimit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/XRateLimitRemaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/XRateLimitReset"
              },
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "403": {
            "$ref": "#/components/responses/Forbidden",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "404": {
            "$ref": "#/components/responses/NotFound",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "409": {
            "$ref": "#/components/responses/Conflict",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "429": {
            "$ref": "#/components/responses/TooManyRequests",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "500": {
            "$ref": "#/components/responses/InternalServerError",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          }
        },
        "x-codeSamples": [
          {
            "lang": "cURL",
            "label": "cURL",
            "source": "curl -X POST \"https://api.kangopenbanking.com/v1/institutions/{institutionId}/clients\" \\\n  -H \"Authorization: Bearer $KOB_ACCESS_TOKEN\" \\\n  -H \"Content-Type: application/json\" \\\n  -d '{}'"
          },
          {
            "lang": "JavaScript",
            "label": "Node.js",
            "source": "import { KangOpenBanking } from \"@kangopenbanking/sdk\";\n\nconst kob = new KangOpenBanking({ apiKey: process.env.KOB_API_KEY });\nconst res = await kob.request(\"POST\", \"/v1/institutions/{institutionId}/clients\", { /* payload */ });\nconsole.log(res);"
          },
          {
            "lang": "Python",
            "label": "Python",
            "source": "from kangopenbanking import KangOpenBanking\n\nkob = KangOpenBanking(api_key=os.environ[\"KOB_API_KEY\"])\nres = kob.request(\"POST\", \"/v1/institutions/{institutionId}/clients\", json={})\nprint(res)"
          },
          {
            "lang": "PHP",
            "label": "PHP",
            "source": "<?php\n$kob = new KangOpenBanking\\KangOpenBanking(getenv('KOB_API_KEY'));\n$res = $kob->request('POST', '/v1/institutions/{institutionId}/clients', []);\nprint_r($res);"
          }
        ]
      }
    },
    "/v1/institutions/{institutionId}/kyb": {
      "post": {
        "tags": [
          "Institution"
        ],
        "summary": "Submit business KYC",
        "operationId": "businessKycSubmit",
        "security": [
          {
            "bearerAuth": []
          }
        ],
        "parameters": [
          {
            "name": "institutionId",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "Idempotency-Key",
            "in": "header",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid"
            },
            "description": "Required on all POST/PUT endpoints. Unique key for idempotent request processing (UUID v4 recommended). Keys expire after 24 hours."
          },
          {
            "$ref": "#/components/parameters/RequestId"
          },
          {
            "$ref": "#/components/parameters/Traceparent"
          },
          {
            "$ref": "#/components/parameters/Tracestate"
          },
          {
            "$ref": "#/components/parameters/AcceptLanguage"
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object"
              }
            }
          }
        },
        "responses": {
          "201": {
            "description": "KYB submitted",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "submission_id": {
                      "type": "string",
                      "format": "uuid"
                    },
                    "status": {
                      "type": "string",
                      "example": "pending_review"
                    },
                    "submitted_at": {
                      "type": "string",
                      "format": "date-time"
                    }
                  }
                },
                "example": {
                  "submission_id": "00000000-0000-4000-8000-000000000000",
                  "status": "pending_review",
                  "submitted_at": "2026-01-01T00:00:00Z"
                }
              }
            },
            "headers": {
              "x-fapi-interaction-id": {
                "$ref": "#/components/headers/XFapiInteractionIdResponse"
              },
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/XRateLimitLimit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/XRateLimitRemaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/XRateLimitReset"
              },
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              },
              "traceparent": {
                "$ref": "#/components/headers/Traceparent"
              },
              "Content-Language": {
                "$ref": "#/components/headers/Content-Language"
              }
            }
          },
          "400": {
            "description": "Bad request",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              },
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                },
                "examples": {
                  "error": {
                    "$ref": "#/components/examples/ErrorBadRequest"
                  }
                }
              }
            },
            "headers": {
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/XRateLimitLimit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/XRateLimitRemaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/XRateLimitReset"
              },
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "403": {
            "$ref": "#/components/responses/Forbidden",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "404": {
            "$ref": "#/components/responses/NotFound",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "409": {
            "$ref": "#/components/responses/Conflict",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "429": {
            "$ref": "#/components/responses/TooManyRequests",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "500": {
            "$ref": "#/components/responses/InternalServerError",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          }
        },
        "x-codeSamples": [
          {
            "lang": "cURL",
            "label": "cURL",
            "source": "curl -X POST \"https://api.kangopenbanking.com/v1/institutions/{institutionId}/kyb\" \\\n  -H \"Authorization: Bearer $KOB_ACCESS_TOKEN\" \\\n  -H \"Content-Type: application/json\" \\\n  -d '{}'"
          },
          {
            "lang": "JavaScript",
            "label": "Node.js",
            "source": "import { KangOpenBanking } from \"@kangopenbanking/sdk\";\n\nconst kob = new KangOpenBanking({ apiKey: process.env.KOB_API_KEY });\nconst res = await kob.request(\"POST\", \"/v1/institutions/{institutionId}/kyb\", { /* payload */ });\nconsole.log(res);"
          },
          {
            "lang": "Python",
            "label": "Python",
            "source": "from kangopenbanking import KangOpenBanking\n\nkob = KangOpenBanking(api_key=os.environ[\"KOB_API_KEY\"])\nres = kob.request(\"POST\", \"/v1/institutions/{institutionId}/kyb\", json={})\nprint(res)"
          },
          {
            "lang": "PHP",
            "label": "PHP",
            "source": "<?php\n$kob = new KangOpenBanking\\KangOpenBanking(getenv('KOB_API_KEY'));\n$res = $kob->request('POST', '/v1/institutions/{institutionId}/kyb', []);\nprint_r($res);"
          }
        ]
      }
    },
    "/v1/crediq/health-check": {
      "get": {
        "tags": [
          "CrediQ"
        ],
        "summary": "CrediQ health check",
        "operationId": "crediqHealthCheck",
        "security": [
          {
            "bearerAuth": []
          }
        ],
        "responses": {
          "200": {
            "description": "Health status",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "success": {
                      "type": "boolean",
                      "example": true
                    },
                    "message": {
                      "type": "string"
                    }
                  }
                },
                "example": {
                  "success": true,
                  "message": "string"
                }
              }
            },
            "headers": {
              "x-fapi-interaction-id": {
                "$ref": "#/components/headers/XFapiInteractionIdResponse"
              },
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/XRateLimitLimit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/XRateLimitRemaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/XRateLimitReset"
              },
              "Cache-Control": {
                "$ref": "#/components/headers/CacheControl"
              },
              "ETag": {
                "$ref": "#/components/headers/ETag"
              },
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              },
              "traceparent": {
                "$ref": "#/components/headers/Traceparent"
              },
              "Content-Language": {
                "$ref": "#/components/headers/Content-Language"
              }
            }
          },
          "400": {
            "description": "Bad request",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              },
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                },
                "examples": {
                  "error": {
                    "$ref": "#/components/examples/ErrorBadRequest"
                  }
                }
              }
            },
            "headers": {
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/XRateLimitLimit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/XRateLimitRemaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/XRateLimitReset"
              },
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "403": {
            "$ref": "#/components/responses/Forbidden",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "404": {
            "$ref": "#/components/responses/NotFound",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "409": {
            "$ref": "#/components/responses/Conflict",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "429": {
            "$ref": "#/components/responses/TooManyRequests",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "500": {
            "$ref": "#/components/responses/InternalServerError",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          }
        },
        "parameters": [
          {
            "$ref": "#/components/parameters/RequestId"
          },
          {
            "$ref": "#/components/parameters/Traceparent"
          },
          {
            "$ref": "#/components/parameters/Tracestate"
          },
          {
            "$ref": "#/components/parameters/AcceptLanguage"
          }
        ],
        "x-codeSamples": [
          {
            "lang": "cURL",
            "label": "cURL",
            "source": "curl -X GET \"https://api.kangopenbanking.com/v1/crediq/health-check\" \\\n  -H \"Authorization: Bearer $KOB_ACCESS_TOKEN\" \\\n  -H \"Content-Type: application/json\""
          },
          {
            "lang": "JavaScript",
            "label": "Node.js",
            "source": "import { KangOpenBanking } from \"@kangopenbanking/sdk\";\n\nconst kob = new KangOpenBanking({ apiKey: process.env.KOB_API_KEY });\nconst res = await kob.request(\"GET\", \"/v1/crediq/health-check\");\nconsole.log(res);"
          },
          {
            "lang": "Python",
            "label": "Python",
            "source": "from kangopenbanking import KangOpenBanking\n\nkob = KangOpenBanking(api_key=os.environ[\"KOB_API_KEY\"])\nres = kob.request(\"GET\", \"/v1/crediq/health-check\")\nprint(res)"
          },
          {
            "lang": "PHP",
            "label": "PHP",
            "source": "<?php\n$kob = new KangOpenBanking\\KangOpenBanking(getenv('KOB_API_KEY'));\n$res = $kob->request('GET', '/v1/crediq/health-check');\nprint_r($res);"
          }
        ]
      }
    },
    "/v1/crediq/baseline-score": {
      "post": {
        "tags": [
          "CrediQ"
        ],
        "summary": "Generate baseline score",
        "operationId": "crediqBaselineScore",
        "security": [
          {
            "bearerAuth": []
          }
        ],
        "responses": {
          "200": {
            "description": "Baseline score",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/CreditScore"
                },
                "example": {
                  "score": 680,
                  "grade": "A",
                  "score_range": "Poor",
                  "calculated_at": "2026-01-01T00:00:00Z",
                  "data_sources": [
                    "mobile_money_history",
                    "njangi_participation",
                    "cobac_registry"
                  ],
                  "locale_band": "cemac_v1"
                }
              }
            },
            "headers": {
              "x-fapi-interaction-id": {
                "$ref": "#/components/headers/XFapiInteractionIdResponse"
              },
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/XRateLimitLimit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/XRateLimitRemaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/XRateLimitReset"
              },
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              },
              "traceparent": {
                "$ref": "#/components/headers/Traceparent"
              },
              "Content-Language": {
                "$ref": "#/components/headers/Content-Language"
              }
            }
          },
          "400": {
            "description": "Bad request",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              },
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                },
                "examples": {
                  "error": {
                    "$ref": "#/components/examples/ErrorBadRequest"
                  }
                }
              }
            },
            "headers": {
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/XRateLimitLimit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/XRateLimitRemaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/XRateLimitReset"
              },
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "403": {
            "$ref": "#/components/responses/Forbidden",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "404": {
            "$ref": "#/components/responses/NotFound",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "409": {
            "$ref": "#/components/responses/Conflict",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "429": {
            "$ref": "#/components/responses/TooManyRequests",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "500": {
            "$ref": "#/components/responses/InternalServerError",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          }
        },
        "parameters": [
          {
            "$ref": "#/components/parameters/RequestId"
          },
          {
            "$ref": "#/components/parameters/Traceparent"
          },
          {
            "$ref": "#/components/parameters/Tracestate"
          },
          {
            "$ref": "#/components/parameters/AcceptLanguage"
          }
        ],
        "x-codeSamples": [
          {
            "lang": "cURL",
            "label": "cURL",
            "source": "curl -X POST \"https://api.kangopenbanking.com/v1/crediq/baseline-score\" \\\n  -H \"Authorization: Bearer $KOB_ACCESS_TOKEN\" \\\n  -H \"Content-Type: application/json\""
          },
          {
            "lang": "JavaScript",
            "label": "Node.js",
            "source": "import { KangOpenBanking } from \"@kangopenbanking/sdk\";\n\nconst kob = new KangOpenBanking({ apiKey: process.env.KOB_API_KEY });\nconst res = await kob.request(\"POST\", \"/v1/crediq/baseline-score\");\nconsole.log(res);"
          },
          {
            "lang": "Python",
            "label": "Python",
            "source": "from kangopenbanking import KangOpenBanking\n\nkob = KangOpenBanking(api_key=os.environ[\"KOB_API_KEY\"])\nres = kob.request(\"POST\", \"/v1/crediq/baseline-score\")\nprint(res)"
          },
          {
            "lang": "PHP",
            "label": "PHP",
            "source": "<?php\n$kob = new KangOpenBanking\\KangOpenBanking(getenv('KOB_API_KEY'));\n$res = $kob->request('POST', '/v1/crediq/baseline-score');\nprint_r($res);"
          }
        ]
      }
    },
    "/v1/crediq/health-metrics": {
      "post": {
        "tags": [
          "CrediQ"
        ],
        "summary": "Calculate health metrics",
        "operationId": "crediqHealthMetrics",
        "security": [
          {
            "bearerAuth": []
          }
        ],
        "responses": {
          "200": {
            "description": "Health metrics",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "success": {
                      "type": "boolean",
                      "example": true
                    },
                    "message": {
                      "type": "string"
                    }
                  }
                },
                "example": {
                  "success": true,
                  "message": "string"
                }
              }
            },
            "headers": {
              "x-fapi-interaction-id": {
                "$ref": "#/components/headers/XFapiInteractionIdResponse"
              },
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/XRateLimitLimit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/XRateLimitRemaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/XRateLimitReset"
              },
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              },
              "traceparent": {
                "$ref": "#/components/headers/Traceparent"
              },
              "Content-Language": {
                "$ref": "#/components/headers/Content-Language"
              }
            }
          },
          "400": {
            "description": "Bad request",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              },
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                },
                "examples": {
                  "error": {
                    "$ref": "#/components/examples/ErrorBadRequest"
                  }
                }
              }
            },
            "headers": {
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/XRateLimitLimit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/XRateLimitRemaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/XRateLimitReset"
              },
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "403": {
            "$ref": "#/components/responses/Forbidden",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "404": {
            "$ref": "#/components/responses/NotFound",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "409": {
            "$ref": "#/components/responses/Conflict",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "429": {
            "$ref": "#/components/responses/TooManyRequests",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "500": {
            "$ref": "#/components/responses/InternalServerError",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          }
        },
        "parameters": [
          {
            "$ref": "#/components/parameters/RequestId"
          },
          {
            "$ref": "#/components/parameters/Traceparent"
          },
          {
            "$ref": "#/components/parameters/Tracestate"
          },
          {
            "$ref": "#/components/parameters/AcceptLanguage"
          }
        ],
        "x-codeSamples": [
          {
            "lang": "cURL",
            "label": "cURL",
            "source": "curl -X POST \"https://api.kangopenbanking.com/v1/crediq/health-metrics\" \\\n  -H \"Authorization: Bearer $KOB_ACCESS_TOKEN\" \\\n  -H \"Content-Type: application/json\""
          },
          {
            "lang": "JavaScript",
            "label": "Node.js",
            "source": "import { KangOpenBanking } from \"@kangopenbanking/sdk\";\n\nconst kob = new KangOpenBanking({ apiKey: process.env.KOB_API_KEY });\nconst res = await kob.request(\"POST\", \"/v1/crediq/health-metrics\");\nconsole.log(res);"
          },
          {
            "lang": "Python",
            "label": "Python",
            "source": "from kangopenbanking import KangOpenBanking\n\nkob = KangOpenBanking(api_key=os.environ[\"KOB_API_KEY\"])\nres = kob.request(\"POST\", \"/v1/crediq/health-metrics\")\nprint(res)"
          },
          {
            "lang": "PHP",
            "label": "PHP",
            "source": "<?php\n$kob = new KangOpenBanking\\KangOpenBanking(getenv('KOB_API_KEY'));\n$res = $kob->request('POST', '/v1/crediq/health-metrics');\nprint_r($res);"
          }
        ]
      }
    },
    "/v1/crediq/action-plan": {
      "post": {
        "tags": [
          "CrediQ"
        ],
        "summary": "Generate action plan",
        "operationId": "crediqActionPlan",
        "security": [
          {
            "bearerAuth": []
          }
        ],
        "responses": {
          "200": {
            "description": "Action plan",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "success": {
                      "type": "boolean",
                      "example": true
                    },
                    "message": {
                      "type": "string"
                    }
                  }
                },
                "example": {
                  "success": true,
                  "message": "string"
                }
              }
            },
            "headers": {
              "x-fapi-interaction-id": {
                "$ref": "#/components/headers/XFapiInteractionIdResponse"
              },
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/XRateLimitLimit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/XRateLimitRemaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/XRateLimitReset"
              },
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              },
              "traceparent": {
                "$ref": "#/components/headers/Traceparent"
              },
              "Content-Language": {
                "$ref": "#/components/headers/Content-Language"
              }
            }
          },
          "400": {
            "description": "Bad request",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              },
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                },
                "examples": {
                  "error": {
                    "$ref": "#/components/examples/ErrorBadRequest"
                  }
                }
              }
            },
            "headers": {
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/XRateLimitLimit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/XRateLimitRemaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/XRateLimitReset"
              },
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "403": {
            "$ref": "#/components/responses/Forbidden",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "404": {
            "$ref": "#/components/responses/NotFound",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "409": {
            "$ref": "#/components/responses/Conflict",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "429": {
            "$ref": "#/components/responses/TooManyRequests",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "500": {
            "$ref": "#/components/responses/InternalServerError",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          }
        },
        "parameters": [
          {
            "$ref": "#/components/parameters/RequestId"
          },
          {
            "$ref": "#/components/parameters/Traceparent"
          },
          {
            "$ref": "#/components/parameters/Tracestate"
          },
          {
            "$ref": "#/components/parameters/AcceptLanguage"
          }
        ],
        "x-codeSamples": [
          {
            "lang": "cURL",
            "label": "cURL",
            "source": "curl -X POST \"https://api.kangopenbanking.com/v1/crediq/action-plan\" \\\n  -H \"Authorization: Bearer $KOB_ACCESS_TOKEN\" \\\n  -H \"Content-Type: application/json\""
          },
          {
            "lang": "JavaScript",
            "label": "Node.js",
            "source": "import { KangOpenBanking } from \"@kangopenbanking/sdk\";\n\nconst kob = new KangOpenBanking({ apiKey: process.env.KOB_API_KEY });\nconst res = await kob.request(\"POST\", \"/v1/crediq/action-plan\");\nconsole.log(res);"
          },
          {
            "lang": "Python",
            "label": "Python",
            "source": "from kangopenbanking import KangOpenBanking\n\nkob = KangOpenBanking(api_key=os.environ[\"KOB_API_KEY\"])\nres = kob.request(\"POST\", \"/v1/crediq/action-plan\")\nprint(res)"
          },
          {
            "lang": "PHP",
            "label": "PHP",
            "source": "<?php\n$kob = new KangOpenBanking\\KangOpenBanking(getenv('KOB_API_KEY'));\n$res = $kob->request('POST', '/v1/crediq/action-plan');\nprint_r($res);"
          }
        ]
      }
    },
    "/v1/postiq/codes": {
      "post": {
        "tags": [
          "PostiQ"
        ],
        "summary": "Create PostiQ code",
        "operationId": "postiqCreateCode",
        "security": [
          {
            "bearerAuth": []
          }
        ],
        "parameters": [
          {
            "name": "Idempotency-Key",
            "in": "header",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid"
            },
            "description": "Required on all POST/PUT endpoints. Unique key for idempotent request processing (UUID v4 recommended). Keys expire after 24 hours."
          },
          {
            "$ref": "#/components/parameters/RequestId"
          },
          {
            "$ref": "#/components/parameters/Traceparent"
          },
          {
            "$ref": "#/components/parameters/Tracestate"
          },
          {
            "$ref": "#/components/parameters/AcceptLanguage"
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object"
              }
            }
          }
        },
        "responses": {
          "201": {
            "description": "Code created",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "postiq_code": {
                      "type": "string"
                    },
                    "full_address": {
                      "type": "string"
                    },
                    "verified_at": {
                      "type": "string",
                      "format": "date-time"
                    }
                  }
                },
                "example": {
                  "postiq_code": "string",
                  "full_address": "string",
                  "verified_at": "2026-01-01T00:00:00Z"
                }
              }
            },
            "headers": {
              "x-fapi-interaction-id": {
                "$ref": "#/components/headers/XFapiInteractionIdResponse"
              },
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/XRateLimitLimit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/XRateLimitRemaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/XRateLimitReset"
              },
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              },
              "traceparent": {
                "$ref": "#/components/headers/Traceparent"
              },
              "Content-Language": {
                "$ref": "#/components/headers/Content-Language"
              }
            }
          },
          "400": {
            "description": "Bad request",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              },
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                },
                "examples": {
                  "error": {
                    "$ref": "#/components/examples/ErrorBadRequest"
                  }
                }
              }
            },
            "headers": {
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/XRateLimitLimit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/XRateLimitRemaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/XRateLimitReset"
              },
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "403": {
            "$ref": "#/components/responses/Forbidden",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "404": {
            "$ref": "#/components/responses/NotFound",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "409": {
            "$ref": "#/components/responses/Conflict",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "429": {
            "$ref": "#/components/responses/TooManyRequests",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "500": {
            "$ref": "#/components/responses/InternalServerError",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          }
        },
        "x-codeSamples": [
          {
            "lang": "cURL",
            "label": "cURL",
            "source": "curl -X POST \"https://api.kangopenbanking.com/v1/postiq/codes\" \\\n  -H \"Authorization: Bearer $KOB_ACCESS_TOKEN\" \\\n  -H \"Content-Type: application/json\" \\\n  -d '{}'"
          },
          {
            "lang": "JavaScript",
            "label": "Node.js",
            "source": "import { KangOpenBanking } from \"@kangopenbanking/sdk\";\n\nconst kob = new KangOpenBanking({ apiKey: process.env.KOB_API_KEY });\nconst res = await kob.request(\"POST\", \"/v1/postiq/codes\", { /* payload */ });\nconsole.log(res);"
          },
          {
            "lang": "Python",
            "label": "Python",
            "source": "from kangopenbanking import KangOpenBanking\n\nkob = KangOpenBanking(api_key=os.environ[\"KOB_API_KEY\"])\nres = kob.request(\"POST\", \"/v1/postiq/codes\", json={})\nprint(res)"
          },
          {
            "lang": "PHP",
            "label": "PHP",
            "source": "<?php\n$kob = new KangOpenBanking\\KangOpenBanking(getenv('KOB_API_KEY'));\n$res = $kob->request('POST', '/v1/postiq/codes', []);\nprint_r($res);"
          }
        ]
      }
    },
    "/v1/postiq/codes/{code}": {
      "get": {
        "tags": [
          "PostiQ"
        ],
        "summary": "Lookup PostiQ code",
        "operationId": "postiqLookupCode",
        "security": [],
        "parameters": [
          {
            "name": "code",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "$ref": "#/components/parameters/RequestId"
          },
          {
            "$ref": "#/components/parameters/Traceparent"
          },
          {
            "$ref": "#/components/parameters/Tracestate"
          },
          {
            "$ref": "#/components/parameters/AcceptLanguage"
          }
        ],
        "responses": {
          "200": {
            "description": "Address details",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "postiq_code": {
                      "type": "string"
                    },
                    "full_address": {
                      "type": "string"
                    },
                    "city": {
                      "type": "string"
                    },
                    "country": {
                      "type": "string"
                    }
                  }
                },
                "example": {
                  "postiq_code": "string",
                  "full_address": "string",
                  "city": "string",
                  "country": "string"
                }
              }
            },
            "headers": {
              "x-fapi-interaction-id": {
                "$ref": "#/components/headers/XFapiInteractionIdResponse"
              },
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/XRateLimitLimit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/XRateLimitRemaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/XRateLimitReset"
              },
              "Cache-Control": {
                "$ref": "#/components/headers/CacheControl"
              },
              "ETag": {
                "$ref": "#/components/headers/ETag"
              },
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              },
              "traceparent": {
                "$ref": "#/components/headers/Traceparent"
              },
              "Content-Language": {
                "$ref": "#/components/headers/Content-Language"
              }
            }
          },
          "400": {
            "description": "Bad request",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              },
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                },
                "examples": {
                  "error": {
                    "$ref": "#/components/examples/ErrorBadRequest"
                  }
                }
              }
            },
            "headers": {
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/XRateLimitLimit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/XRateLimitRemaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/XRateLimitReset"
              },
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "403": {
            "$ref": "#/components/responses/Forbidden",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "404": {
            "$ref": "#/components/responses/NotFound",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "409": {
            "$ref": "#/components/responses/Conflict",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "429": {
            "$ref": "#/components/responses/TooManyRequests",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "500": {
            "$ref": "#/components/responses/InternalServerError",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          }
        },
        "x-codeSamples": [
          {
            "lang": "cURL",
            "label": "cURL",
            "source": "curl -X GET \"https://api.kangopenbanking.com/v1/postiq/codes/{code}\" \\\n  -H \"Authorization: Bearer $KOB_ACCESS_TOKEN\" \\\n  -H \"Content-Type: application/json\""
          },
          {
            "lang": "JavaScript",
            "label": "Node.js",
            "source": "import { KangOpenBanking } from \"@kangopenbanking/sdk\";\n\nconst kob = new KangOpenBanking({ apiKey: process.env.KOB_API_KEY });\nconst res = await kob.request(\"GET\", \"/v1/postiq/codes/{code}\");\nconsole.log(res);"
          },
          {
            "lang": "Python",
            "label": "Python",
            "source": "from kangopenbanking import KangOpenBanking\n\nkob = KangOpenBanking(api_key=os.environ[\"KOB_API_KEY\"])\nres = kob.request(\"GET\", \"/v1/postiq/codes/{code}\")\nprint(res)"
          },
          {
            "lang": "PHP",
            "label": "PHP",
            "source": "<?php\n$kob = new KangOpenBanking\\KangOpenBanking(getenv('KOB_API_KEY'));\n$res = $kob->request('GET', '/v1/postiq/codes/{code}');\nprint_r($res);"
          }
        ]
      }
    },
    "/v1/woocommerce/merchants": {
      "post": {
        "tags": [
          "WooCommerce"
        ],
        "summary": "Register WooCommerce merchant",
        "description": "Register a WooCommerce store for Kang Open Banking payment processing. Returns API credentials.",
        "operationId": "woocommerceRegisterMerchant",
        "security": [
          {
            "bearerAuth": []
          }
        ],
        "parameters": [
          {
            "name": "Idempotency-Key",
            "in": "header",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid"
            },
            "description": "Required on all POST/PUT endpoints. Unique key for idempotent request processing (UUID v4 recommended). Keys expire after 24 hours."
          },
          {
            "$ref": "#/components/parameters/RequestId"
          },
          {
            "$ref": "#/components/parameters/Traceparent"
          },
          {
            "$ref": "#/components/parameters/Tracestate"
          },
          {
            "$ref": "#/components/parameters/AcceptLanguage"
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "required": [
                  "store_name",
                  "store_url",
                  "admin_email"
                ],
                "properties": {
                  "store_name": {
                    "type": "string",
                    "example": "My Cameroon Store"
                  },
                  "store_url": {
                    "type": "string",
                    "format": "uri",
                    "example": "https://mystore.cm"
                  },
                  "admin_email": {
                    "type": "string",
                    "format": "email"
                  },
                  "plugin_version": {
                    "type": "string",
                    "example": "1.0.0"
                  },
                  "business_type": {
                    "type": "string",
                    "enum": [
                      "individual",
                      "company"
                    ]
                  },
                  "phone": {
                    "type": "string"
                  },
                  "country": {
                    "type": "string",
                    "default": "CM"
                  }
                }
              }
            }
          }
        },
        "responses": {
          "201": {
            "description": "Merchant registered",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/WooCommerceMerchant"
                },
                "example": {
                  "id": "00000000-0000-4000-8000-000000000000",
                  "store_name": "string",
                  "store_url": "https://api.kangopenbanking.com",
                  "admin_email": "agent@example.cm",
                  "api_key": "string",
                  "client_secret": "string",
                  "webhook_secret": "string",
                  "status": "active",
                  "plugin_version": "string",
                  "created_at": "2026-01-01T00:00:00Z"
                }
              }
            },
            "headers": {
              "x-fapi-interaction-id": {
                "$ref": "#/components/headers/XFapiInteractionIdResponse"
              },
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/XRateLimitLimit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/XRateLimitRemaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/XRateLimitReset"
              },
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              },
              "traceparent": {
                "$ref": "#/components/headers/Traceparent"
              },
              "Content-Language": {
                "$ref": "#/components/headers/Content-Language"
              }
            }
          },
          "400": {
            "description": "Bad request",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              },
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                },
                "examples": {
                  "error": {
                    "$ref": "#/components/examples/ErrorBadRequest"
                  }
                }
              }
            },
            "headers": {
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/XRateLimitLimit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/XRateLimitRemaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/XRateLimitReset"
              },
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "403": {
            "$ref": "#/components/responses/Forbidden",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "404": {
            "$ref": "#/components/responses/NotFound",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "409": {
            "$ref": "#/components/responses/Conflict",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "429": {
            "$ref": "#/components/responses/TooManyRequests",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "500": {
            "$ref": "#/components/responses/InternalServerError",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          }
        },
        "x-codeSamples": [
          {
            "lang": "cURL",
            "label": "cURL",
            "source": "curl -X POST \"https://api.kangopenbanking.com/v1/woocommerce/merchants\" \\\n  -H \"Authorization: Bearer $KOB_ACCESS_TOKEN\" \\\n  -H \"Content-Type: application/json\" \\\n  -d '{}'"
          },
          {
            "lang": "JavaScript",
            "label": "Node.js",
            "source": "import { KangOpenBanking } from \"@kangopenbanking/sdk\";\n\nconst kob = new KangOpenBanking({ apiKey: process.env.KOB_API_KEY });\nconst res = await kob.request(\"POST\", \"/v1/woocommerce/merchants\", { /* payload */ });\nconsole.log(res);"
          },
          {
            "lang": "Python",
            "label": "Python",
            "source": "from kangopenbanking import KangOpenBanking\n\nkob = KangOpenBanking(api_key=os.environ[\"KOB_API_KEY\"])\nres = kob.request(\"POST\", \"/v1/woocommerce/merchants\", json={})\nprint(res)"
          },
          {
            "lang": "PHP",
            "label": "PHP",
            "source": "<?php\n$kob = new KangOpenBanking\\KangOpenBanking(getenv('KOB_API_KEY'));\n$res = $kob->request('POST', '/v1/woocommerce/merchants', []);\nprint_r($res);"
          }
        ]
      }
    },
    "/v1/woocommerce/validate-install": {
      "post": {
        "tags": [
          "WooCommerce"
        ],
        "summary": "Validate WooCommerce plugin installation",
        "description": "Validates the plugin is correctly installed and API credentials are working.",
        "operationId": "woocommerceValidateInstall",
        "security": [
          {
            "bearerAuth": []
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "required": [
                  "api_key",
                  "store_url"
                ],
                "properties": {
                  "api_key": {
                    "type": "string"
                  },
                  "plugin_version": {
                    "type": "string"
                  },
                  "store_url": {
                    "type": "string",
                    "format": "uri"
                  },
                  "php_version": {
                    "type": "string"
                  },
                  "wp_version": {
                    "type": "string"
                  },
                  "wc_version": {
                    "type": "string"
                  }
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Validation result",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "valid": {
                      "type": "boolean"
                    },
                    "merchant_id": {
                      "type": "string"
                    },
                    "store_name": {
                      "type": "string"
                    },
                    "status": {
                      "type": "string",
                      "enum": [
                        "active",
                        "inactive",
                        "suspended"
                      ]
                    },
                    "features": {
                      "type": "array",
                      "items": {
                        "type": "string"
                      }
                    }
                  }
                },
                "example": {
                  "valid": true,
                  "merchant_id": "string",
                  "store_name": "string",
                  "status": "active",
                  "features": [
                    "string"
                  ]
                }
              }
            },
            "headers": {
              "x-fapi-interaction-id": {
                "$ref": "#/components/headers/XFapiInteractionIdResponse"
              },
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/XRateLimitLimit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/XRateLimitRemaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/XRateLimitReset"
              },
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              },
              "traceparent": {
                "$ref": "#/components/headers/Traceparent"
              },
              "Content-Language": {
                "$ref": "#/components/headers/Content-Language"
              }
            }
          },
          "400": {
            "description": "Bad request",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              },
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                },
                "examples": {
                  "error": {
                    "$ref": "#/components/examples/ErrorBadRequest"
                  }
                }
              }
            },
            "headers": {
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/XRateLimitLimit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/XRateLimitRemaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/XRateLimitReset"
              },
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "403": {
            "$ref": "#/components/responses/Forbidden",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "404": {
            "$ref": "#/components/responses/NotFound",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "409": {
            "$ref": "#/components/responses/Conflict",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "429": {
            "$ref": "#/components/responses/TooManyRequests",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "500": {
            "$ref": "#/components/responses/InternalServerError",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          }
        },
        "parameters": [
          {
            "$ref": "#/components/parameters/RequestId"
          },
          {
            "$ref": "#/components/parameters/Traceparent"
          },
          {
            "$ref": "#/components/parameters/Tracestate"
          },
          {
            "$ref": "#/components/parameters/AcceptLanguage"
          }
        ],
        "x-codeSamples": [
          {
            "lang": "cURL",
            "label": "cURL",
            "source": "curl -X POST \"https://api.kangopenbanking.com/v1/woocommerce/validate-install\" \\\n  -H \"Authorization: Bearer $KOB_ACCESS_TOKEN\" \\\n  -H \"Content-Type: application/json\" \\\n  -d '{}'"
          },
          {
            "lang": "JavaScript",
            "label": "Node.js",
            "source": "import { KangOpenBanking } from \"@kangopenbanking/sdk\";\n\nconst kob = new KangOpenBanking({ apiKey: process.env.KOB_API_KEY });\nconst res = await kob.request(\"POST\", \"/v1/woocommerce/validate-install\", { /* payload */ });\nconsole.log(res);"
          },
          {
            "lang": "Python",
            "label": "Python",
            "source": "from kangopenbanking import KangOpenBanking\n\nkob = KangOpenBanking(api_key=os.environ[\"KOB_API_KEY\"])\nres = kob.request(\"POST\", \"/v1/woocommerce/validate-install\", json={})\nprint(res)"
          },
          {
            "lang": "PHP",
            "label": "PHP",
            "source": "<?php\n$kob = new KangOpenBanking\\KangOpenBanking(getenv('KOB_API_KEY'));\n$res = $kob->request('POST', '/v1/woocommerce/validate-install', []);\nprint_r($res);"
          }
        ]
      }
    },
    "/v1/woocommerce/plugin/download": {
      "get": {
        "tags": [
          "WooCommerce"
        ],
        "summary": "Download WooCommerce plugin ZIP",
        "description": "Downloads the complete Woo for Kang WordPress plugin as a ZIP file ready for installation. Authentication required. A developer account or merchant account bearer token must be provided.",
        "operationId": "woocommerceDownloadPlugin",
        "security": [
          {
            "bearerAuth": []
          }
        ],
        "responses": {
          "200": {
            "description": "Plugin ZIP file",
            "content": {
              "application/zip": {
                "schema": {
                  "type": "string",
                  "format": "binary"
                }
              }
            },
            "headers": {
              "x-fapi-interaction-id": {
                "$ref": "#/components/headers/XFapiInteractionIdResponse"
              },
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/XRateLimitLimit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/XRateLimitRemaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/XRateLimitReset"
              },
              "Cache-Control": {
                "$ref": "#/components/headers/CacheControl"
              },
              "ETag": {
                "$ref": "#/components/headers/ETag"
              },
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              },
              "traceparent": {
                "$ref": "#/components/headers/Traceparent"
              },
              "Content-Language": {
                "$ref": "#/components/headers/Content-Language"
              }
            }
          },
          "400": {
            "description": "Bad request",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              },
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                },
                "examples": {
                  "error": {
                    "$ref": "#/components/examples/ErrorBadRequest"
                  }
                }
              }
            },
            "headers": {
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/XRateLimitLimit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/XRateLimitRemaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/XRateLimitReset"
              },
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "403": {
            "$ref": "#/components/responses/Forbidden",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "404": {
            "$ref": "#/components/responses/NotFound",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "409": {
            "$ref": "#/components/responses/Conflict",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "429": {
            "$ref": "#/components/responses/TooManyRequests",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "500": {
            "$ref": "#/components/responses/InternalServerError",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          }
        },
        "parameters": [
          {
            "$ref": "#/components/parameters/RequestId"
          },
          {
            "$ref": "#/components/parameters/Traceparent"
          },
          {
            "$ref": "#/components/parameters/Tracestate"
          },
          {
            "$ref": "#/components/parameters/AcceptLanguage"
          }
        ],
        "x-codeSamples": [
          {
            "lang": "cURL",
            "label": "cURL",
            "source": "curl -X GET \"https://api.kangopenbanking.com/v1/woocommerce/plugin/download\" \\\n  -H \"Authorization: Bearer $KOB_ACCESS_TOKEN\" \\\n  -H \"Content-Type: application/json\""
          },
          {
            "lang": "JavaScript",
            "label": "Node.js",
            "source": "import { KangOpenBanking } from \"@kangopenbanking/sdk\";\n\nconst kob = new KangOpenBanking({ apiKey: process.env.KOB_API_KEY });\nconst res = await kob.request(\"GET\", \"/v1/woocommerce/plugin/download\");\nconsole.log(res);"
          },
          {
            "lang": "Python",
            "label": "Python",
            "source": "from kangopenbanking import KangOpenBanking\n\nkob = KangOpenBanking(api_key=os.environ[\"KOB_API_KEY\"])\nres = kob.request(\"GET\", \"/v1/woocommerce/plugin/download\")\nprint(res)"
          },
          {
            "lang": "PHP",
            "label": "PHP",
            "source": "<?php\n$kob = new KangOpenBanking\\KangOpenBanking(getenv('KOB_API_KEY'));\n$res = $kob->request('GET', '/v1/woocommerce/plugin/download');\nprint_r($res);"
          }
        ]
      }
    },
    "/v1/woocommerce/process-payment": {
      "post": {
        "tags": [
          "WooCommerce"
        ],
        "summary": "Process WooCommerce payment",
        "description": "Initiates a payment for a WooCommerce order. Called by the WordPress plugin during checkout.",
        "operationId": "woocommerceProcessPayment",
        "security": [
          {
            "bearerAuth": []
          }
        ],
        "parameters": [
          {
            "name": "Idempotency-Key",
            "in": "header",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid"
            },
            "description": "Required on all POST/PUT endpoints. Unique key for idempotent request processing (UUID v4 recommended). Keys expire after 24 hours."
          },
          {
            "$ref": "#/components/parameters/RequestId"
          },
          {
            "$ref": "#/components/parameters/Traceparent"
          },
          {
            "$ref": "#/components/parameters/Tracestate"
          },
          {
            "$ref": "#/components/parameters/AcceptLanguage"
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "required": [
                  "amount",
                  "currency",
                  "woocommerce_order_id",
                  "customer_email"
                ],
                "properties": {
                  "amount": {
                    "type": "string",
                    "example": "25000",
                    "pattern": "^[0-9]{1,15}$",
                    "description": "Represented as a string integer in the currency's minor unit (XAF has no subunits). Must be consistent with the currency field."
                  },
                  "currency": {
                    "type": "string",
                    "default": "XAF",
                    "enum": [
                      "XAF",
                      "XOF",
                      "USD",
                      "EUR",
                      "GBP",
                      "CNY",
                      "NGN",
                      "GHS",
                      "KES",
                      "ZAR"
                    ],
                    "description": "ISO 4217 currency code. Default is XAF (Central African CFA Franc)."
                  },
                  "woocommerce_order_id": {
                    "type": "integer",
                    "example": 1234
                  },
                  "customer_email": {
                    "type": "string",
                    "format": "email"
                  },
                  "customer_name": {
                    "type": "string"
                  },
                  "customer_phone": {
                    "type": "string"
                  },
                  "payment_methods": {
                    "type": "array",
                    "items": {
                      "type": "string",
                      "enum": [
                        "mobile_money",
                        "card",
                        "bank_transfer"
                      ]
                    }
                  },
                  "return_url": {
                    "type": "string",
                    "format": "uri"
                  },
                  "cancel_url": {
                    "type": "string",
                    "format": "uri"
                  },
                  "webhook_url": {
                    "type": "string",
                    "format": "uri"
                  },
                  "metadata": {
                    "type": "object"
                  }
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Payment initiated",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "transaction_ref": {
                      "type": "string"
                    },
                    "payment_url": {
                      "type": "string",
                      "format": "uri"
                    },
                    "status": {
                      "type": "string",
                      "enum": [
                        "pending",
                        "processing"
                      ]
                    },
                    "expires_at": {
                      "type": "string",
                      "format": "date-time"
                    }
                  }
                },
                "example": {
                  "transaction_ref": "string",
                  "payment_url": "https://api.kangopenbanking.com",
                  "status": "pending",
                  "expires_at": "2026-01-01T00:00:00Z"
                }
              }
            },
            "headers": {
              "x-fapi-interaction-id": {
                "$ref": "#/components/headers/XFapiInteractionIdResponse"
              },
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/XRateLimitLimit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/XRateLimitRemaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/XRateLimitReset"
              },
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              },
              "traceparent": {
                "$ref": "#/components/headers/Traceparent"
              },
              "Content-Language": {
                "$ref": "#/components/headers/Content-Language"
              }
            }
          },
          "400": {
            "description": "Bad request",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              },
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                },
                "examples": {
                  "error": {
                    "$ref": "#/components/examples/ErrorBadRequest"
                  }
                }
              }
            },
            "headers": {
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/XRateLimitLimit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/XRateLimitRemaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/XRateLimitReset"
              },
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "403": {
            "$ref": "#/components/responses/Forbidden",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "404": {
            "$ref": "#/components/responses/NotFound",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "409": {
            "$ref": "#/components/responses/Conflict",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "429": {
            "$ref": "#/components/responses/TooManyRequests",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "500": {
            "$ref": "#/components/responses/InternalServerError",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          }
        },
        "x-codeSamples": [
          {
            "lang": "cURL",
            "label": "cURL",
            "source": "curl -X POST \"https://api.kangopenbanking.com/v1/woocommerce/process-payment\" \\\n  -H \"Authorization: Bearer $KOB_ACCESS_TOKEN\" \\\n  -H \"Content-Type: application/json\" \\\n  -d '{}'"
          },
          {
            "lang": "JavaScript",
            "label": "Node.js",
            "source": "import { KangOpenBanking } from \"@kangopenbanking/sdk\";\n\nconst kob = new KangOpenBanking({ apiKey: process.env.KOB_API_KEY });\nconst res = await kob.request(\"POST\", \"/v1/woocommerce/process-payment\", { /* payload */ });\nconsole.log(res);"
          },
          {
            "lang": "Python",
            "label": "Python",
            "source": "from kangopenbanking import KangOpenBanking\n\nkob = KangOpenBanking(api_key=os.environ[\"KOB_API_KEY\"])\nres = kob.request(\"POST\", \"/v1/woocommerce/process-payment\", json={})\nprint(res)"
          },
          {
            "lang": "PHP",
            "label": "PHP",
            "source": "<?php\n$kob = new KangOpenBanking\\KangOpenBanking(getenv('KOB_API_KEY'));\n$res = $kob->request('POST', '/v1/woocommerce/process-payment', []);\nprint_r($res);"
          }
        ]
      }
    },
    "/v1/woocommerce/transactions": {
      "get": {
        "tags": [
          "WooCommerce"
        ],
        "summary": "Sync WooCommerce transactions",
        "description": "Retrieve transaction history for a WooCommerce merchant. Used by the plugin for transaction synchronization.",
        "operationId": "woocommerceListTransactions",
        "security": [
          {
            "bearerAuth": []
          }
        ],
        "parameters": [
          {
            "name": "start_date",
            "in": "query",
            "schema": {
              "type": "string",
              "format": "date"
            }
          },
          {
            "name": "end_date",
            "in": "query",
            "schema": {
              "type": "string",
              "format": "date"
            }
          },
          {
            "name": "status",
            "in": "query",
            "schema": {
              "type": "string",
              "enum": [
                "pending",
                "completed",
                "failed",
                "refunded"
              ]
            }
          },
          {
            "name": "payment_method",
            "in": "query",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "limit",
            "in": "query",
            "schema": {
              "type": "integer",
              "default": 25,
              "maximum": 100
            },
            "description": "Items per page"
          },
          {
            "name": "offset",
            "in": "query",
            "schema": {
              "type": "integer",
              "default": 0
            },
            "description": "Items to skip"
          },
          {
            "name": "sort_by",
            "in": "query",
            "schema": {
              "type": "string",
              "default": "created_at"
            },
            "description": "Sort field"
          },
          {
            "name": "sort_order",
            "in": "query",
            "schema": {
              "type": "string",
              "enum": [
                "asc",
                "desc"
              ],
              "default": "desc"
            },
            "description": "Sort direction"
          },
          {
            "$ref": "#/components/parameters/StartingAfter"
          },
          {
            "$ref": "#/components/parameters/EndingBefore"
          },
          {
            "$ref": "#/components/parameters/RequestId"
          },
          {
            "$ref": "#/components/parameters/Traceparent"
          },
          {
            "$ref": "#/components/parameters/Tracestate"
          },
          {
            "$ref": "#/components/parameters/AcceptLanguage"
          }
        ],
        "responses": {
          "200": {
            "description": "Transaction list",
            "content": {
              "application/json": {
                "schema": {
                  "allOf": [
                    {
                      "$ref": "#/components/schemas/PaginatedResponse"
                    },
                    {
                      "type": "object",
                      "properties": {
                        "data": {
                          "type": "array",
                          "items": {
                            "$ref": "#/components/schemas/WooCommerceTransaction"
                          }
                        }
                      }
                    }
                  ]
                },
                "example": {
                  "data": [
                    {
                      "id": "f1d6f4a0-1d4e-4a3a-9e0a-1a2b3c4d5e6f",
                      "transaction_ref": "XAF",
                      "woocommerce_order_id": 1,
                      "amount": "1000",
                      "currency": "XAF",
                      "status": "pending",
                      "payment_method": "XAF",
                      "customer_email": "XAF",
                      "fee_amount": "0",
                      "net_amount": "0",
                      "created_at": "2026-01-31T12:00:00Z",
                      "completed_at": "2026-01-31T12:00:00Z"
                    }
                  ],
                  "pagination": {
                    "page": 1,
                    "limit": 20,
                    "total": 150,
                    "has_next": true,
                    "next_cursor": "eyJpZCI6IjEyMyJ9"
                  },
                  "meta": {
                    "request_id": "550e8400-e29b-41d4-a716-446655440000",
                    "timestamp": "2025-03-27T12:00:00Z",
                    "api_version": "4.3.0"
                  }
                }
              }
            },
            "headers": {
              "x-fapi-interaction-id": {
                "$ref": "#/components/headers/XFapiInteractionIdResponse"
              },
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/XRateLimitLimit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/XRateLimitRemaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/XRateLimitReset"
              },
              "Cache-Control": {
                "$ref": "#/components/headers/CacheControl"
              },
              "ETag": {
                "$ref": "#/components/headers/ETag"
              },
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              },
              "traceparent": {
                "$ref": "#/components/headers/Traceparent"
              },
              "Content-Language": {
                "$ref": "#/components/headers/Content-Language"
              }
            }
          },
          "400": {
            "description": "Bad request",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              },
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                },
                "examples": {
                  "error": {
                    "$ref": "#/components/examples/ErrorBadRequest"
                  }
                }
              }
            },
            "headers": {
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/XRateLimitLimit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/XRateLimitRemaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/XRateLimitReset"
              },
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "403": {
            "$ref": "#/components/responses/Forbidden",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "404": {
            "$ref": "#/components/responses/NotFound",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "409": {
            "$ref": "#/components/responses/Conflict",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "429": {
            "$ref": "#/components/responses/TooManyRequests",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "500": {
            "$ref": "#/components/responses/InternalServerError",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          }
        },
        "x-codeSamples": [
          {
            "lang": "cURL",
            "label": "cURL",
            "source": "curl -X GET \"https://api.kangopenbanking.com/v1/woocommerce/transactions\" \\\n  -H \"Authorization: Bearer $KOB_ACCESS_TOKEN\" \\\n  -H \"Content-Type: application/json\""
          },
          {
            "lang": "JavaScript",
            "label": "Node.js",
            "source": "import { KangOpenBanking } from \"@kangopenbanking/sdk\";\n\nconst kob = new KangOpenBanking({ apiKey: process.env.KOB_API_KEY });\nconst res = await kob.request(\"GET\", \"/v1/woocommerce/transactions\");\nconsole.log(res);"
          },
          {
            "lang": "Python",
            "label": "Python",
            "source": "from kangopenbanking import KangOpenBanking\n\nkob = KangOpenBanking(api_key=os.environ[\"KOB_API_KEY\"])\nres = kob.request(\"GET\", \"/v1/woocommerce/transactions\")\nprint(res)"
          },
          {
            "lang": "PHP",
            "label": "PHP",
            "source": "<?php\n$kob = new KangOpenBanking\\KangOpenBanking(getenv('KOB_API_KEY'));\n$res = $kob->request('GET', '/v1/woocommerce/transactions');\nprint_r($res);"
          }
        ]
      }
    },
    "/v1/woocommerce/webhook": {
      "post": {
        "tags": [
          "WooCommerce"
        ],
        "summary": "WooCommerce payment webhook",
        "description": "Receives payment status updates and updates the corresponding WooCommerce order.",
        "operationId": "woocommercePaymentWebhook",
        "security": [],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "required": [
                  "event_type",
                  "transaction_ref",
                  "status"
                ],
                "properties": {
                  "event_type": {
                    "type": "string",
                    "enum": [
                      "payment.completed",
                      "payment.failed",
                      "payment.cancelled",
                      "payment.refunded"
                    ]
                  },
                  "transaction_ref": {
                    "type": "string"
                  },
                  "woocommerce_order_id": {
                    "type": "integer"
                  },
                  "status": {
                    "type": "string",
                    "enum": [
                      "completed",
                      "successful",
                      "failed",
                      "cancelled",
                      "refunded"
                    ]
                  },
                  "amount": {
                    "type": "string",
                    "pattern": "^[0-9]{1,15}$",
                    "description": "Represented as a string integer in the currency's minor unit (XAF has no subunits). Must be consistent with the currency field."
                  },
                  "currency": {
                    "type": "string",
                    "enum": [
                      "XAF",
                      "XOF",
                      "USD",
                      "EUR",
                      "GBP",
                      "CNY",
                      "NGN",
                      "GHS",
                      "KES",
                      "ZAR"
                    ],
                    "default": "XAF",
                    "description": "ISO 4217 currency code. Default is XAF (Central African CFA Franc)."
                  },
                  "payment_method": {
                    "type": "string"
                  },
                  "timestamp": {
                    "type": "string",
                    "format": "date-time"
                  }
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Webhook processed",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "success": {
                      "type": "boolean",
                      "example": true
                    },
                    "message": {
                      "type": "string"
                    }
                  }
                },
                "example": {
                  "success": true,
                  "message": "string"
                }
              }
            },
            "headers": {
              "x-fapi-interaction-id": {
                "$ref": "#/components/headers/XFapiInteractionIdResponse"
              },
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/XRateLimitLimit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/XRateLimitRemaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/XRateLimitReset"
              },
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              },
              "traceparent": {
                "$ref": "#/components/headers/Traceparent"
              },
              "Content-Language": {
                "$ref": "#/components/headers/Content-Language"
              }
            }
          },
          "400": {
            "description": "Bad request",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              },
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                },
                "examples": {
                  "error": {
                    "$ref": "#/components/examples/ErrorBadRequest"
                  }
                }
              }
            },
            "headers": {
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/XRateLimitLimit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/XRateLimitRemaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/XRateLimitReset"
              },
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "403": {
            "$ref": "#/components/responses/Forbidden",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "404": {
            "$ref": "#/components/responses/NotFound",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "409": {
            "$ref": "#/components/responses/Conflict",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "429": {
            "$ref": "#/components/responses/TooManyRequests",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "500": {
            "$ref": "#/components/responses/InternalServerError",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          }
        },
        "parameters": [
          {
            "$ref": "#/components/parameters/RequestId"
          },
          {
            "$ref": "#/components/parameters/Traceparent"
          },
          {
            "$ref": "#/components/parameters/Tracestate"
          },
          {
            "$ref": "#/components/parameters/AcceptLanguage"
          }
        ],
        "x-codeSamples": [
          {
            "lang": "cURL",
            "label": "cURL",
            "source": "curl -X POST \"https://api.kangopenbanking.com/v1/woocommerce/webhook\" \\\n  -H \"Authorization: Bearer $KOB_ACCESS_TOKEN\" \\\n  -H \"Content-Type: application/json\" \\\n  -d '{}'"
          },
          {
            "lang": "JavaScript",
            "label": "Node.js",
            "source": "import { KangOpenBanking } from \"@kangopenbanking/sdk\";\n\nconst kob = new KangOpenBanking({ apiKey: process.env.KOB_API_KEY });\nconst res = await kob.request(\"POST\", \"/v1/woocommerce/webhook\", { /* payload */ });\nconsole.log(res);"
          },
          {
            "lang": "Python",
            "label": "Python",
            "source": "from kangopenbanking import KangOpenBanking\n\nkob = KangOpenBanking(api_key=os.environ[\"KOB_API_KEY\"])\nres = kob.request(\"POST\", \"/v1/woocommerce/webhook\", json={})\nprint(res)"
          },
          {
            "lang": "PHP",
            "label": "PHP",
            "source": "<?php\n$kob = new KangOpenBanking\\KangOpenBanking(getenv('KOB_API_KEY'));\n$res = $kob->request('POST', '/v1/woocommerce/webhook', []);\nprint_r($res);"
          }
        ]
      }
    },
    "/v1/sandbox/accounts": {
      "post": {
        "tags": [
          "Sandbox"
        ],
        "summary": "Create sandbox account",
        "operationId": "sandboxCreateAccount",
        "security": [
          {
            "bearerAuth": []
          }
        ],
        "parameters": [
          {
            "name": "Idempotency-Key",
            "in": "header",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid"
            },
            "description": "Required on all POST/PUT endpoints. Unique key for idempotent request processing (UUID v4 recommended). Keys expire after 24 hours."
          },
          {
            "$ref": "#/components/parameters/RequestId"
          },
          {
            "$ref": "#/components/parameters/Traceparent"
          },
          {
            "$ref": "#/components/parameters/Tracestate"
          },
          {
            "$ref": "#/components/parameters/AcceptLanguage"
          }
        ],
        "responses": {
          "201": {
            "description": "Sandbox account created",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "success": {
                      "type": "boolean",
                      "example": true
                    },
                    "message": {
                      "type": "string"
                    }
                  }
                },
                "example": {
                  "success": true,
                  "message": "string"
                }
              }
            },
            "headers": {
              "x-fapi-interaction-id": {
                "$ref": "#/components/headers/XFapiInteractionIdResponse"
              },
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/XRateLimitLimit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/XRateLimitRemaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/XRateLimitReset"
              },
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              },
              "traceparent": {
                "$ref": "#/components/headers/Traceparent"
              },
              "Content-Language": {
                "$ref": "#/components/headers/Content-Language"
              }
            }
          },
          "400": {
            "description": "Bad request",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              },
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                },
                "examples": {
                  "error": {
                    "$ref": "#/components/examples/ErrorBadRequest"
                  }
                }
              }
            },
            "headers": {
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/XRateLimitLimit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/XRateLimitRemaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/XRateLimitReset"
              },
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "403": {
            "$ref": "#/components/responses/Forbidden",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "404": {
            "$ref": "#/components/responses/NotFound",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "409": {
            "$ref": "#/components/responses/Conflict",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "429": {
            "$ref": "#/components/responses/TooManyRequests",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "500": {
            "$ref": "#/components/responses/InternalServerError",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          }
        },
        "x-codeSamples": [
          {
            "lang": "cURL",
            "label": "cURL",
            "source": "curl -X POST \"https://api.kangopenbanking.com/v1/sandbox/accounts\" \\\n  -H \"Authorization: Bearer $KOB_ACCESS_TOKEN\" \\\n  -H \"Content-Type: application/json\""
          },
          {
            "lang": "JavaScript",
            "label": "Node.js",
            "source": "import { KangOpenBanking } from \"@kangopenbanking/sdk\";\n\nconst kob = new KangOpenBanking({ apiKey: process.env.KOB_API_KEY });\nconst res = await kob.request(\"POST\", \"/v1/sandbox/accounts\");\nconsole.log(res);"
          },
          {
            "lang": "Python",
            "label": "Python",
            "source": "from kangopenbanking import KangOpenBanking\n\nkob = KangOpenBanking(api_key=os.environ[\"KOB_API_KEY\"])\nres = kob.request(\"POST\", \"/v1/sandbox/accounts\")\nprint(res)"
          },
          {
            "lang": "PHP",
            "label": "PHP",
            "source": "<?php\n$kob = new KangOpenBanking\\KangOpenBanking(getenv('KOB_API_KEY'));\n$res = $kob->request('POST', '/v1/sandbox/accounts');\nprint_r($res);"
          }
        ]
      }
    },
    "/v1/sandbox/api-keys": {
      "post": {
        "tags": [
          "Sandbox"
        ],
        "summary": "Create sandbox API key",
        "operationId": "sandboxCreateApiKey",
        "security": [
          {
            "bearerAuth": []
          }
        ],
        "parameters": [
          {
            "name": "Idempotency-Key",
            "in": "header",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid"
            },
            "description": "Required on all POST/PUT endpoints. Unique key for idempotent request processing (UUID v4 recommended). Keys expire after 24 hours."
          },
          {
            "$ref": "#/components/parameters/RequestId"
          },
          {
            "$ref": "#/components/parameters/Traceparent"
          },
          {
            "$ref": "#/components/parameters/Tracestate"
          },
          {
            "$ref": "#/components/parameters/AcceptLanguage"
          }
        ],
        "responses": {
          "201": {
            "description": "API key created",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "api_key": {
                      "type": "string",
                      "pattern": "^sbx_[0-9a-f]{64}$",
                      "example": "sbx_aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
                    },
                    "secret": {
                      "type": "string"
                    },
                    "environment": {
                      "type": "string"
                    },
                    "tier": {
                      "type": "string",
                      "enum": [
                        "free",
                        "pro",
                        "enterprise"
                      ],
                      "default": "free"
                    }
                  }
                },
                "example": {
                  "api_key": "sbx_aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa",
                  "secret": "string",
                  "environment": "string",
                  "tier": "free"
                }
              }
            },
            "headers": {
              "x-fapi-interaction-id": {
                "$ref": "#/components/headers/XFapiInteractionIdResponse"
              },
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/XRateLimitLimit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/XRateLimitRemaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/XRateLimitReset"
              },
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              },
              "traceparent": {
                "$ref": "#/components/headers/Traceparent"
              },
              "Content-Language": {
                "$ref": "#/components/headers/Content-Language"
              }
            }
          },
          "400": {
            "description": "Bad request",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              },
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                },
                "examples": {
                  "error": {
                    "$ref": "#/components/examples/ErrorBadRequest"
                  }
                }
              }
            },
            "headers": {
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/XRateLimitLimit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/XRateLimitRemaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/XRateLimitReset"
              },
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "403": {
            "$ref": "#/components/responses/Forbidden",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "404": {
            "$ref": "#/components/responses/NotFound",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "409": {
            "$ref": "#/components/responses/Conflict",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "429": {
            "$ref": "#/components/responses/TooManyRequests",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "500": {
            "$ref": "#/components/responses/InternalServerError",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          }
        },
        "x-codeSamples": [
          {
            "lang": "cURL",
            "label": "cURL",
            "source": "curl -X POST \"https://api.kangopenbanking.com/v1/sandbox/api-keys\" \\\n  -H \"Authorization: Bearer $KOB_ACCESS_TOKEN\" \\\n  -H \"Content-Type: application/json\""
          },
          {
            "lang": "JavaScript",
            "label": "Node.js",
            "source": "import { KangOpenBanking } from \"@kangopenbanking/sdk\";\n\nconst kob = new KangOpenBanking({ apiKey: process.env.KOB_API_KEY });\nconst res = await kob.request(\"POST\", \"/v1/sandbox/api-keys\");\nconsole.log(res);"
          },
          {
            "lang": "Python",
            "label": "Python",
            "source": "from kangopenbanking import KangOpenBanking\n\nkob = KangOpenBanking(api_key=os.environ[\"KOB_API_KEY\"])\nres = kob.request(\"POST\", \"/v1/sandbox/api-keys\")\nprint(res)"
          },
          {
            "lang": "PHP",
            "label": "PHP",
            "source": "<?php\n$kob = new KangOpenBanking\\KangOpenBanking(getenv('KOB_API_KEY'));\n$res = $kob->request('POST', '/v1/sandbox/api-keys');\nprint_r($res);"
          }
        ]
      }
    },
    "/v1/sandbox/data/generate": {
      "post": {
        "tags": [
          "Sandbox"
        ],
        "summary": "Generate test data",
        "operationId": "sandboxGenerateData",
        "security": [
          {
            "bearerAuth": []
          }
        ],
        "responses": {
          "200": {
            "description": "Test data generated",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "success": {
                      "type": "boolean",
                      "example": true
                    },
                    "message": {
                      "type": "string"
                    }
                  }
                },
                "example": {
                  "success": true,
                  "message": "string"
                }
              }
            },
            "headers": {
              "x-fapi-interaction-id": {
                "$ref": "#/components/headers/XFapiInteractionIdResponse"
              },
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/XRateLimitLimit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/XRateLimitRemaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/XRateLimitReset"
              },
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              },
              "traceparent": {
                "$ref": "#/components/headers/Traceparent"
              },
              "Content-Language": {
                "$ref": "#/components/headers/Content-Language"
              }
            }
          },
          "400": {
            "description": "Bad request",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              },
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                },
                "examples": {
                  "error": {
                    "$ref": "#/components/examples/ErrorBadRequest"
                  }
                }
              }
            },
            "headers": {
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/XRateLimitLimit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/XRateLimitRemaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/XRateLimitReset"
              },
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "403": {
            "$ref": "#/components/responses/Forbidden",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "404": {
            "$ref": "#/components/responses/NotFound",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "409": {
            "$ref": "#/components/responses/Conflict",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "429": {
            "$ref": "#/components/responses/TooManyRequests",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "500": {
            "$ref": "#/components/responses/InternalServerError",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          }
        },
        "parameters": [
          {
            "$ref": "#/components/parameters/RequestId"
          },
          {
            "$ref": "#/components/parameters/Traceparent"
          },
          {
            "$ref": "#/components/parameters/Tracestate"
          },
          {
            "$ref": "#/components/parameters/AcceptLanguage"
          }
        ],
        "x-codeSamples": [
          {
            "lang": "cURL",
            "label": "cURL",
            "source": "curl -X POST \"https://api.kangopenbanking.com/v1/sandbox/data/generate\" \\\n  -H \"Authorization: Bearer $KOB_ACCESS_TOKEN\" \\\n  -H \"Content-Type: application/json\""
          },
          {
            "lang": "JavaScript",
            "label": "Node.js",
            "source": "import { KangOpenBanking } from \"@kangopenbanking/sdk\";\n\nconst kob = new KangOpenBanking({ apiKey: process.env.KOB_API_KEY });\nconst res = await kob.request(\"POST\", \"/v1/sandbox/data/generate\");\nconsole.log(res);"
          },
          {
            "lang": "Python",
            "label": "Python",
            "source": "from kangopenbanking import KangOpenBanking\n\nkob = KangOpenBanking(api_key=os.environ[\"KOB_API_KEY\"])\nres = kob.request(\"POST\", \"/v1/sandbox/data/generate\")\nprint(res)"
          },
          {
            "lang": "PHP",
            "label": "PHP",
            "source": "<?php\n$kob = new KangOpenBanking\\KangOpenBanking(getenv('KOB_API_KEY'));\n$res = $kob->request('POST', '/v1/sandbox/data/generate');\nprint_r($res);"
          }
        ]
      }
    },
    "/v1/sandbox/webhooks": {
      "post": {
        "tags": [
          "Sandbox"
        ],
        "summary": "Register sandbox webhook",
        "operationId": "sandboxRegisterWebhook",
        "security": [
          {
            "bearerAuth": []
          }
        ],
        "parameters": [
          {
            "name": "Idempotency-Key",
            "in": "header",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid"
            },
            "description": "Required on all POST/PUT endpoints. Unique key for idempotent request processing (UUID v4 recommended). Keys expire after 24 hours."
          },
          {
            "$ref": "#/components/parameters/RequestId"
          },
          {
            "$ref": "#/components/parameters/Traceparent"
          },
          {
            "$ref": "#/components/parameters/Tracestate"
          },
          {
            "$ref": "#/components/parameters/AcceptLanguage"
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "required": [
                  "url",
                  "events"
                ],
                "properties": {
                  "url": {
                    "type": "string"
                  },
                  "events": {
                    "type": "array",
                    "items": {
                      "type": "string"
                    }
                  }
                }
              }
            }
          }
        },
        "responses": {
          "201": {
            "description": "Webhook registered",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Webhook"
                },
                "example": {
                  "webhook_id": "00000000-0000-4000-8000-000000000000",
                  "url": "https://api.kangopenbanking.com",
                  "events": [
                    {
                      "id": "evt_a1b2c3d4-e5f6-7890-abcd-ef1234567890",
                      "event": "charge.created",
                      "created_at": "2025-03-27T14:32:00Z",
                      "api_version": "4.6.0",
                      "data": {}
                    }
                  ],
                  "is_active": true,
                  "secret": "string"
                }
              }
            },
            "headers": {
              "x-fapi-interaction-id": {
                "$ref": "#/components/headers/XFapiInteractionIdResponse"
              },
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/XRateLimitLimit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/XRateLimitRemaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/XRateLimitReset"
              },
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              },
              "traceparent": {
                "$ref": "#/components/headers/Traceparent"
              },
              "Content-Language": {
                "$ref": "#/components/headers/Content-Language"
              }
            }
          },
          "400": {
            "description": "Bad request",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              },
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                },
                "examples": {
                  "error": {
                    "$ref": "#/components/examples/ErrorBadRequest"
                  }
                }
              }
            },
            "headers": {
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/XRateLimitLimit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/XRateLimitRemaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/XRateLimitReset"
              },
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "403": {
            "$ref": "#/components/responses/Forbidden",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "404": {
            "$ref": "#/components/responses/NotFound",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "409": {
            "$ref": "#/components/responses/Conflict",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "429": {
            "$ref": "#/components/responses/TooManyRequests",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "500": {
            "$ref": "#/components/responses/InternalServerError",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          }
        },
        "x-codeSamples": [
          {
            "lang": "cURL",
            "label": "cURL",
            "source": "curl -X POST \"https://api.kangopenbanking.com/v1/sandbox/webhooks\" \\\n  -H \"Authorization: Bearer $KOB_ACCESS_TOKEN\" \\\n  -H \"Content-Type: application/json\" \\\n  -d '{}'"
          },
          {
            "lang": "JavaScript",
            "label": "Node.js",
            "source": "import { KangOpenBanking } from \"@kangopenbanking/sdk\";\n\nconst kob = new KangOpenBanking({ apiKey: process.env.KOB_API_KEY });\nconst res = await kob.request(\"POST\", \"/v1/sandbox/webhooks\", { /* payload */ });\nconsole.log(res);"
          },
          {
            "lang": "Python",
            "label": "Python",
            "source": "from kangopenbanking import KangOpenBanking\n\nkob = KangOpenBanking(api_key=os.environ[\"KOB_API_KEY\"])\nres = kob.request(\"POST\", \"/v1/sandbox/webhooks\", json={})\nprint(res)"
          },
          {
            "lang": "PHP",
            "label": "PHP",
            "source": "<?php\n$kob = new KangOpenBanking\\KangOpenBanking(getenv('KOB_API_KEY'));\n$res = $kob->request('POST', '/v1/sandbox/webhooks', []);\nprint_r($res);"
          }
        ]
      }
    },
    "/v1/developers/register": {
      "post": {
        "tags": [
          "Developer"
        ],
        "summary": "Register developer app",
        "operationId": "developerRegisterApp",
        "security": [
          {
            "bearerAuth": []
          }
        ],
        "parameters": [
          {
            "name": "Idempotency-Key",
            "in": "header",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid"
            },
            "description": "Required on all POST/PUT endpoints. Unique key for idempotent request processing (UUID v4 recommended). Keys expire after 24 hours."
          },
          {
            "$ref": "#/components/parameters/RequestId"
          },
          {
            "$ref": "#/components/parameters/Traceparent"
          },
          {
            "$ref": "#/components/parameters/Tracestate"
          },
          {
            "$ref": "#/components/parameters/AcceptLanguage"
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "required": [
                  "app_name",
                  "redirect_uris"
                ],
                "properties": {
                  "app_name": {
                    "type": "string"
                  },
                  "redirect_uris": {
                    "type": "array",
                    "items": {
                      "type": "string"
                    }
                  },
                  "use_case": {
                    "type": "string"
                  }
                }
              }
            }
          }
        },
        "responses": {
          "201": {
            "description": "App registered",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "client_id": {
                      "type": "string"
                    },
                    "client_secret": {
                      "type": "string",
                      "description": "Shown once"
                    },
                    "app_name": {
                      "type": "string"
                    },
                    "redirect_uris": {
                      "type": "array",
                      "items": {
                        "type": "string"
                      }
                    },
                    "created_at": {
                      "type": "string",
                      "format": "date-time"
                    }
                  }
                },
                "example": {
                  "client_id": "string",
                  "client_secret": "string",
                  "app_name": "string",
                  "redirect_uris": [
                    "string"
                  ],
                  "created_at": "2026-01-01T00:00:00Z"
                }
              }
            },
            "headers": {
              "x-fapi-interaction-id": {
                "$ref": "#/components/headers/XFapiInteractionIdResponse"
              },
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/XRateLimitLimit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/XRateLimitRemaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/XRateLimitReset"
              },
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              },
              "traceparent": {
                "$ref": "#/components/headers/Traceparent"
              },
              "Content-Language": {
                "$ref": "#/components/headers/Content-Language"
              }
            }
          },
          "400": {
            "description": "Bad request",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              },
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                },
                "examples": {
                  "error": {
                    "$ref": "#/components/examples/ErrorBadRequest"
                  }
                }
              }
            },
            "headers": {
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/XRateLimitLimit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/XRateLimitRemaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/XRateLimitReset"
              },
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "403": {
            "$ref": "#/components/responses/Forbidden",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "404": {
            "$ref": "#/components/responses/NotFound",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "409": {
            "$ref": "#/components/responses/Conflict",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "429": {
            "$ref": "#/components/responses/TooManyRequests",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "500": {
            "$ref": "#/components/responses/InternalServerError",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          }
        },
        "x-codeSamples": [
          {
            "lang": "cURL",
            "label": "cURL",
            "source": "curl -X POST \"https://api.kangopenbanking.com/v1/developers/register\" \\\n  -H \"Authorization: Bearer $KOB_ACCESS_TOKEN\" \\\n  -H \"Content-Type: application/json\" \\\n  -d '{}'"
          },
          {
            "lang": "JavaScript",
            "label": "Node.js",
            "source": "import { KangOpenBanking } from \"@kangopenbanking/sdk\";\n\nconst kob = new KangOpenBanking({ apiKey: process.env.KOB_API_KEY });\nconst res = await kob.request(\"POST\", \"/v1/developers/register\", { /* payload */ });\nconsole.log(res);"
          },
          {
            "lang": "Python",
            "label": "Python",
            "source": "from kangopenbanking import KangOpenBanking\n\nkob = KangOpenBanking(api_key=os.environ[\"KOB_API_KEY\"])\nres = kob.request(\"POST\", \"/v1/developers/register\", json={})\nprint(res)"
          },
          {
            "lang": "PHP",
            "label": "PHP",
            "source": "<?php\n$kob = new KangOpenBanking\\KangOpenBanking(getenv('KOB_API_KEY'));\n$res = $kob->request('POST', '/v1/developers/register', []);\nprint_r($res);"
          }
        ]
      }
    },
    "/v1/gateway/charges": {
      "post": {
        "tags": [
          "Payment Gateway"
        ],
        "summary": "Create a charge",
        "operationId": "gatewayCreateCharge",
        "security": [
          {
            "bearerAuth": []
          }
        ],
        "parameters": [
          {
            "name": "Idempotency-Key",
            "in": "header",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid"
            },
            "description": "Required on all POST/PUT endpoints. Unique key for idempotent request processing (UUID v4 recommended). Keys expire after 24 hours."
          },
          {
            "$ref": "#/components/parameters/XFapiInteractionId"
          },
          {
            "$ref": "#/components/parameters/XFapiCustomerIpAddress"
          },
          {
            "$ref": "#/components/parameters/XFapiAuthDate"
          },
          {
            "$ref": "#/components/parameters/RequestId"
          },
          {
            "$ref": "#/components/parameters/Traceparent"
          },
          {
            "$ref": "#/components/parameters/Tracestate"
          },
          {
            "$ref": "#/components/parameters/AcceptLanguage"
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "required": [
                  "merchant_id",
                  "amount",
                  "channel",
                  "tx_ref"
                ],
                "properties": {
                  "merchant_id": {
                    "type": "string",
                    "format": "uuid"
                  },
                  "amount": {
                    "type": "string",
                    "example": "5000",
                    "pattern": "^[0-9]{1,15}$",
                    "description": "Represented as a string integer in the currency's minor unit (XAF has no subunits). Must be consistent with the currency field."
                  },
                  "currency": {
                    "type": "string",
                    "default": "XAF",
                    "enum": [
                      "XAF",
                      "XOF",
                      "USD",
                      "EUR",
                      "GBP",
                      "CNY",
                      "NGN",
                      "GHS",
                      "KES",
                      "ZAR"
                    ],
                    "description": "ISO 4217 currency code. Default is XAF (Central African CFA Franc)."
                  },
                  "channel": {
                    "type": "string",
                    "enum": [
                      "mobile_money",
                      "card",
                      "bank_transfer",
                      "apple_pay",
                      "google_pay",
                      "ussd",
                      "paypal"
                    ]
                  },
                  "customer_phone": {
                    "type": "string"
                  },
                  "customer_email": {
                    "type": "string"
                  },
                  "tx_ref": {
                    "type": "string"
                  },
                  "metadata": {
                    "type": "object"
                  }
                }
              }
            }
          }
        },
        "responses": {
          "201": {
            "description": "Charge created",
            "content": {
              "application/json": {
                "schema": {
                  "allOf": [
                    {
                      "$ref": "#/components/schemas/StandardResponse"
                    },
                    {
                      "type": "object",
                      "properties": {
                        "data": {
                          "$ref": "#/components/schemas/GatewayCharge"
                        }
                      }
                    }
                  ]
                },
                "example": {
                  "data": {
                    "id": "00000000-0000-4000-8000-000000000000",
                    "merchant_id": "00000000-0000-4000-8000-000000000000",
                    "amount": "5000",
                    "currency": "XAF",
                    "channel": "mobile_money",
                    "status": "pending",
                    "provider": "flutterwave",
                    "provider_ref": "string",
                    "fee_amount": "200",
                    "net_amount": "4800",
                    "tx_ref": "string",
                    "customer_phone": "string",
                    "customer_email": "string",
                    "capture_mode": "auto",
                    "captured_amount": 0,
                    "fee_bearer": "merchant",
                    "created_at": "2026-01-01T00:00:00Z",
                    "updated_at": "2026-01-01T00:00:00Z",
                    "description": "string",
                    "metadata": {},
                    "customer_id": "string",
                    "dispute_id": "00000000-0000-4000-8000-000000000000",
                    "refunded_at": "2026-01-01T00:00:00Z",
                    "failure_reason": "string",
                    "failure_message": "string"
                  },
                  "meta": {
                    "request_id": "550e8400-e29b-41d4-a716-446655440000",
                    "timestamp": "2025-03-27T12:00:00Z",
                    "api_version": "4.3.0"
                  }
                }
              }
            },
            "headers": {
              "x-fapi-interaction-id": {
                "$ref": "#/components/headers/XFapiInteractionIdResponse"
              },
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/XRateLimitLimit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/XRateLimitRemaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/XRateLimitReset"
              },
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              },
              "X-Idempotent-Replay": {
                "$ref": "#/components/headers/X-Idempotent-Replay"
              },
              "X-Idempotency-Status": {
                "$ref": "#/components/headers/X-Idempotency-Status"
              },
              "traceparent": {
                "$ref": "#/components/headers/Traceparent"
              },
              "Content-Language": {
                "$ref": "#/components/headers/Content-Language"
              }
            }
          },
          "400": {
            "description": "Bad request",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              },
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                },
                "examples": {
                  "error": {
                    "$ref": "#/components/examples/ErrorBadRequest"
                  }
                }
              }
            },
            "headers": {
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/XRateLimitLimit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/XRateLimitRemaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/XRateLimitReset"
              },
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "403": {
            "$ref": "#/components/responses/Forbidden",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "404": {
            "$ref": "#/components/responses/NotFound",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "409": {
            "$ref": "#/components/responses/Conflict",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "429": {
            "$ref": "#/components/responses/TooManyRequests",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "500": {
            "$ref": "#/components/responses/InternalServerError",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          }
        },
        "description": " Responses will conform to the StandardResponse envelope in a future minor release.",
        "x-codeSamples": [
          {
            "lang": "cURL",
            "label": "cURL",
            "source": "curl -X POST \"https://api.kangopenbanking.com/v1/gateway/charges\" \\\n  -H \"Authorization: Bearer $KOB_ACCESS_TOKEN\" \\\n  -H \"Content-Type: application/json\" \\\n  -d '{}'"
          },
          {
            "lang": "JavaScript",
            "label": "Node.js",
            "source": "import { KangOpenBanking } from \"@kangopenbanking/sdk\";\n\nconst kob = new KangOpenBanking({ apiKey: process.env.KOB_API_KEY });\nconst res = await kob.request(\"POST\", \"/v1/gateway/charges\", { /* payload */ });\nconsole.log(res);"
          },
          {
            "lang": "Python",
            "label": "Python",
            "source": "from kangopenbanking import KangOpenBanking\n\nkob = KangOpenBanking(api_key=os.environ[\"KOB_API_KEY\"])\nres = kob.request(\"POST\", \"/v1/gateway/charges\", json={})\nprint(res)"
          },
          {
            "lang": "PHP",
            "label": "PHP",
            "source": "<?php\n$kob = new KangOpenBanking\\KangOpenBanking(getenv('KOB_API_KEY'));\n$res = $kob->request('POST', '/v1/gateway/charges', []);\nprint_r($res);"
          }
        ]
      },
      "get": {
        "tags": [
          "Payment Gateway"
        ],
        "summary": "List charges",
        "operationId": "gatewayListCharges",
        "security": [
          {
            "bearerAuth": []
          }
        ],
        "parameters": [
          {
            "name": "merchant_id",
            "in": "query",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "status",
            "in": "query",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "channel",
            "in": "query",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "from",
            "in": "query",
            "schema": {
              "type": "string",
              "format": "date"
            }
          },
          {
            "name": "to",
            "in": "query",
            "schema": {
              "type": "string",
              "format": "date"
            }
          },
          {
            "name": "sort_by",
            "in": "query",
            "schema": {
              "type": "string",
              "default": "created_at"
            },
            "description": "Sort field"
          },
          {
            "name": "sort_order",
            "in": "query",
            "schema": {
              "type": "string",
              "enum": [
                "asc",
                "desc"
              ],
              "default": "desc"
            },
            "description": "Sort direction"
          },
          {
            "$ref": "#/components/parameters/PageParam"
          },
          {
            "$ref": "#/components/parameters/LimitParam"
          },
          {
            "$ref": "#/components/parameters/CursorParam"
          },
          {
            "$ref": "#/components/parameters/RequestId"
          },
          {
            "$ref": "#/components/parameters/Traceparent"
          },
          {
            "$ref": "#/components/parameters/Tracestate"
          },
          {
            "$ref": "#/components/parameters/AcceptLanguage"
          }
        ],
        "responses": {
          "200": {
            "description": "Charges list",
            "content": {
              "application/json": {
                "schema": {
                  "allOf": [
                    {
                      "$ref": "#/components/schemas/PaginatedResponse"
                    },
                    {
                      "type": "object",
                      "properties": {
                        "data": {
                          "type": "array",
                          "items": {
                            "$ref": "#/components/schemas/GatewayCharge"
                          }
                        }
                      }
                    }
                  ]
                },
                "example": {
                  "data": [
                    {
                      "id": "f1d6f4a0-1d4e-4a3a-9e0a-1a2b3c4d5e6f",
                      "merchant_id": "f1d6f4a0-1d4e-4a3a-9e0a-1a2b3c4d5e6f",
                      "amount": "5000",
                      "currency": "XAF",
                      "channel": "mobile_money",
                      "status": "pending",
                      "provider": "flutterwave",
                      "provider_ref": "XAF",
                      "fee_amount": "200",
                      "net_amount": "4800",
                      "tx_ref": "XAF",
                      "customer_phone": "XAF",
                      "customer_email": "XAF",
                      "capture_mode": "auto",
                      "captured_amount": 0,
                      "fee_bearer": "merchant",
                      "created_at": "2026-01-31T12:00:00Z",
                      "updated_at": "2026-01-31T12:00:00Z",
                      "description": "XAF",
                      "metadata": {},
                      "customer_id": "XAF",
                      "dispute_id": "f1d6f4a0-1d4e-4a3a-9e0a-1a2b3c4d5e6f",
                      "refunded_at": "2026-01-31T12:00:00Z",
                      "failure_reason": "XAF",
                      "failure_message": "XAF"
                    }
                  ],
                  "pagination": {
                    "page": 1,
                    "limit": 20,
                    "total": 150,
                    "has_next": true,
                    "next_cursor": "eyJpZCI6IjEyMyJ9"
                  },
                  "meta": {
                    "request_id": "550e8400-e29b-41d4-a716-446655440000",
                    "timestamp": "2025-03-27T12:00:00Z",
                    "api_version": "4.3.0"
                  }
                }
              }
            },
            "headers": {
              "x-fapi-interaction-id": {
                "$ref": "#/components/headers/XFapiInteractionIdResponse"
              },
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/XRateLimitLimit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/XRateLimitRemaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/XRateLimitReset"
              },
              "Cache-Control": {
                "$ref": "#/components/headers/CacheControl"
              },
              "ETag": {
                "$ref": "#/components/headers/ETag"
              },
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              },
              "traceparent": {
                "$ref": "#/components/headers/Traceparent"
              },
              "Content-Language": {
                "$ref": "#/components/headers/Content-Language"
              }
            }
          },
          "400": {
            "description": "Bad request",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              },
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                },
                "examples": {
                  "error": {
                    "$ref": "#/components/examples/ErrorBadRequest"
                  }
                }
              }
            },
            "headers": {
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/XRateLimitLimit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/XRateLimitRemaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/XRateLimitReset"
              },
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "403": {
            "$ref": "#/components/responses/Forbidden",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "404": {
            "$ref": "#/components/responses/NotFound",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "409": {
            "$ref": "#/components/responses/Conflict",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "429": {
            "$ref": "#/components/responses/TooManyRequests",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "500": {
            "$ref": "#/components/responses/InternalServerError",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          }
        },
        "x-codeSamples": [
          {
            "lang": "cURL",
            "label": "cURL",
            "source": "curl -X GET \"https://api.kangopenbanking.com/v1/gateway/charges\" \\\n  -H \"Authorization: Bearer $KOB_ACCESS_TOKEN\" \\\n  -H \"Content-Type: application/json\""
          },
          {
            "lang": "JavaScript",
            "label": "Node.js",
            "source": "import { KangOpenBanking } from \"@kangopenbanking/sdk\";\n\nconst kob = new KangOpenBanking({ apiKey: process.env.KOB_API_KEY });\nconst res = await kob.request(\"GET\", \"/v1/gateway/charges\");\nconsole.log(res);"
          },
          {
            "lang": "Python",
            "label": "Python",
            "source": "from kangopenbanking import KangOpenBanking\n\nkob = KangOpenBanking(api_key=os.environ[\"KOB_API_KEY\"])\nres = kob.request(\"GET\", \"/v1/gateway/charges\")\nprint(res)"
          },
          {
            "lang": "PHP",
            "label": "PHP",
            "source": "<?php\n$kob = new KangOpenBanking\\KangOpenBanking(getenv('KOB_API_KEY'));\n$res = $kob->request('GET', '/v1/gateway/charges');\nprint_r($res);"
          }
        ]
      }
    },
    "/v1/gateway/charges/{chargeId}": {
      "get": {
        "tags": [
          "Payment Gateway"
        ],
        "summary": "Get charge",
        "operationId": "gatewayGetCharge",
        "security": [
          {
            "bearerAuth": []
          }
        ],
        "parameters": [
          {
            "name": "chargeId",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "$ref": "#/components/parameters/RequestId"
          },
          {
            "$ref": "#/components/parameters/Traceparent"
          },
          {
            "$ref": "#/components/parameters/Tracestate"
          },
          {
            "$ref": "#/components/parameters/AcceptLanguage"
          }
        ],
        "responses": {
          "200": {
            "description": "Charge details",
            "content": {
              "application/json": {
                "schema": {
                  "allOf": [
                    {
                      "$ref": "#/components/schemas/StandardResponse"
                    },
                    {
                      "type": "object",
                      "properties": {
                        "data": {
                          "$ref": "#/components/schemas/GatewayCharge"
                        }
                      }
                    }
                  ]
                },
                "example": {
                  "data": {
                    "id": "00000000-0000-4000-8000-000000000000",
                    "merchant_id": "00000000-0000-4000-8000-000000000000",
                    "amount": "5000",
                    "currency": "XAF",
                    "channel": "mobile_money",
                    "status": "pending",
                    "provider": "flutterwave",
                    "provider_ref": "string",
                    "fee_amount": "200",
                    "net_amount": "4800",
                    "tx_ref": "string",
                    "customer_phone": "string",
                    "customer_email": "string",
                    "capture_mode": "auto",
                    "captured_amount": 0,
                    "fee_bearer": "merchant",
                    "created_at": "2026-01-01T00:00:00Z",
                    "updated_at": "2026-01-01T00:00:00Z",
                    "description": "string",
                    "metadata": {},
                    "customer_id": "string",
                    "dispute_id": "00000000-0000-4000-8000-000000000000",
                    "refunded_at": "2026-01-01T00:00:00Z",
                    "failure_reason": "string",
                    "failure_message": "string"
                  },
                  "meta": {
                    "request_id": "550e8400-e29b-41d4-a716-446655440000",
                    "timestamp": "2025-03-27T12:00:00Z",
                    "api_version": "4.3.0"
                  }
                }
              }
            },
            "headers": {
              "x-fapi-interaction-id": {
                "$ref": "#/components/headers/XFapiInteractionIdResponse"
              },
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/XRateLimitLimit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/XRateLimitRemaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/XRateLimitReset"
              },
              "Cache-Control": {
                "$ref": "#/components/headers/CacheControl"
              },
              "ETag": {
                "$ref": "#/components/headers/ETag"
              },
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              },
              "traceparent": {
                "$ref": "#/components/headers/Traceparent"
              },
              "Content-Language": {
                "$ref": "#/components/headers/Content-Language"
              }
            }
          },
          "400": {
            "description": "Bad request",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              },
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                },
                "examples": {
                  "error": {
                    "$ref": "#/components/examples/ErrorBadRequest"
                  }
                }
              }
            },
            "headers": {
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/XRateLimitLimit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/XRateLimitRemaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/XRateLimitReset"
              },
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "403": {
            "$ref": "#/components/responses/Forbidden",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "404": {
            "$ref": "#/components/responses/NotFound",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "409": {
            "$ref": "#/components/responses/Conflict",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "429": {
            "$ref": "#/components/responses/TooManyRequests",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "500": {
            "$ref": "#/components/responses/InternalServerError",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          }
        },
        "x-codeSamples": [
          {
            "lang": "cURL",
            "label": "cURL",
            "source": "curl -X GET \"https://api.kangopenbanking.com/v1/gateway/charges/{chargeId}\" \\\n  -H \"Authorization: Bearer $KOB_ACCESS_TOKEN\" \\\n  -H \"Content-Type: application/json\""
          },
          {
            "lang": "JavaScript",
            "label": "Node.js",
            "source": "import { KangOpenBanking } from \"@kangopenbanking/sdk\";\n\nconst kob = new KangOpenBanking({ apiKey: process.env.KOB_API_KEY });\nconst res = await kob.request(\"GET\", \"/v1/gateway/charges/{chargeId}\");\nconsole.log(res);"
          },
          {
            "lang": "Python",
            "label": "Python",
            "source": "from kangopenbanking import KangOpenBanking\n\nkob = KangOpenBanking(api_key=os.environ[\"KOB_API_KEY\"])\nres = kob.request(\"GET\", \"/v1/gateway/charges/{chargeId}\")\nprint(res)"
          },
          {
            "lang": "PHP",
            "label": "PHP",
            "source": "<?php\n$kob = new KangOpenBanking\\KangOpenBanking(getenv('KOB_API_KEY'));\n$res = $kob->request('GET', '/v1/gateway/charges/{chargeId}');\nprint_r($res);"
          }
        ]
      }
    },
    "/v1/gateway/charges/{chargeId}/verify": {
      "post": {
        "tags": [
          "Payment Gateway"
        ],
        "summary": "Verify charge with provider",
        "operationId": "gatewayVerifyCharge",
        "security": [
          {
            "bearerAuth": []
          }
        ],
        "parameters": [
          {
            "name": "chargeId",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "Idempotency-Key",
            "in": "header",
            "required": false,
            "description": "Client-generated UUID for idempotent request deduplication. If the same key is submitted twice, the server returns the original response without re-processing.",
            "schema": {
              "type": "string",
              "format": "uuid",
              "example": "b4a2f391-9a41-4d8b-a123-3c6f0e8b9d12"
            }
          },
          {
            "$ref": "#/components/parameters/RequestId"
          },
          {
            "$ref": "#/components/parameters/Traceparent"
          },
          {
            "$ref": "#/components/parameters/Tracestate"
          },
          {
            "$ref": "#/components/parameters/AcceptLanguage"
          }
        ],
        "responses": {
          "200": {
            "description": "Verified charge status",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/GatewayCharge"
                },
                "example": {
                  "id": "00000000-0000-4000-8000-000000000000",
                  "merchant_id": "00000000-0000-4000-8000-000000000000",
                  "amount": "5000",
                  "currency": "XAF",
                  "channel": "mobile_money",
                  "status": "pending",
                  "provider": "flutterwave",
                  "provider_ref": "string",
                  "fee_amount": "200",
                  "net_amount": "4800",
                  "tx_ref": "string",
                  "customer_phone": "string",
                  "customer_email": "string",
                  "capture_mode": "auto",
                  "captured_amount": 0,
                  "fee_bearer": "merchant",
                  "created_at": "2026-01-01T00:00:00Z",
                  "updated_at": "2026-01-01T00:00:00Z",
                  "description": "string",
                  "metadata": {},
                  "customer_id": "string",
                  "dispute_id": "00000000-0000-4000-8000-000000000000",
                  "refunded_at": "2026-01-01T00:00:00Z",
                  "failure_reason": "string",
                  "failure_message": "string"
                }
              }
            },
            "headers": {
              "x-fapi-interaction-id": {
                "$ref": "#/components/headers/XFapiInteractionIdResponse"
              },
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/XRateLimitLimit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/XRateLimitRemaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/XRateLimitReset"
              },
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              },
              "X-Idempotent-Replay": {
                "$ref": "#/components/headers/X-Idempotent-Replay"
              },
              "X-Idempotency-Status": {
                "$ref": "#/components/headers/X-Idempotency-Status"
              },
              "traceparent": {
                "$ref": "#/components/headers/Traceparent"
              },
              "Content-Language": {
                "$ref": "#/components/headers/Content-Language"
              }
            }
          },
          "400": {
            "description": "Bad request",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              },
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                },
                "examples": {
                  "error": {
                    "$ref": "#/components/examples/ErrorBadRequest"
                  }
                }
              }
            },
            "headers": {
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/XRateLimitLimit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/XRateLimitRemaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/XRateLimitReset"
              },
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "403": {
            "$ref": "#/components/responses/Forbidden",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "404": {
            "$ref": "#/components/responses/NotFound",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "409": {
            "$ref": "#/components/responses/Conflict",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "429": {
            "$ref": "#/components/responses/TooManyRequests",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "500": {
            "$ref": "#/components/responses/InternalServerError",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          }
        },
        "x-codeSamples": [
          {
            "lang": "cURL",
            "label": "cURL",
            "source": "curl -X POST \"https://api.kangopenbanking.com/v1/gateway/charges/{chargeId}/verify\" \\\n  -H \"Authorization: Bearer $KOB_ACCESS_TOKEN\" \\\n  -H \"Content-Type: application/json\""
          },
          {
            "lang": "JavaScript",
            "label": "Node.js",
            "source": "import { KangOpenBanking } from \"@kangopenbanking/sdk\";\n\nconst kob = new KangOpenBanking({ apiKey: process.env.KOB_API_KEY });\nconst res = await kob.request(\"POST\", \"/v1/gateway/charges/{chargeId}/verify\");\nconsole.log(res);"
          },
          {
            "lang": "Python",
            "label": "Python",
            "source": "from kangopenbanking import KangOpenBanking\n\nkob = KangOpenBanking(api_key=os.environ[\"KOB_API_KEY\"])\nres = kob.request(\"POST\", \"/v1/gateway/charges/{chargeId}/verify\")\nprint(res)"
          },
          {
            "lang": "PHP",
            "label": "PHP",
            "source": "<?php\n$kob = new KangOpenBanking\\KangOpenBanking(getenv('KOB_API_KEY'));\n$res = $kob->request('POST', '/v1/gateway/charges/{chargeId}/verify');\nprint_r($res);"
          }
        ]
      }
    },
    "/v1/gateway/charges/{chargeId}/cancel": {
      "post": {
        "tags": [
          "Payment Gateway"
        ],
        "summary": "Cancel pending charge",
        "operationId": "gatewayCancelCharge",
        "security": [
          {
            "bearerAuth": []
          }
        ],
        "parameters": [
          {
            "name": "chargeId",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "Idempotency-Key",
            "in": "header",
            "required": false,
            "description": "Client-generated UUID for idempotent request deduplication. If the same key is submitted twice, the server returns the original response without re-processing.",
            "schema": {
              "type": "string",
              "format": "uuid",
              "example": "b4a2f391-9a41-4d8b-a123-3c6f0e8b9d12"
            }
          },
          {
            "$ref": "#/components/parameters/RequestId"
          },
          {
            "$ref": "#/components/parameters/Traceparent"
          },
          {
            "$ref": "#/components/parameters/Tracestate"
          },
          {
            "$ref": "#/components/parameters/AcceptLanguage"
          }
        ],
        "responses": {
          "200": {
            "description": "Charge cancelled",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/GatewayCharge"
                },
                "example": {
                  "id": "00000000-0000-4000-8000-000000000000",
                  "merchant_id": "00000000-0000-4000-8000-000000000000",
                  "amount": "5000",
                  "currency": "XAF",
                  "channel": "mobile_money",
                  "status": "pending",
                  "provider": "flutterwave",
                  "provider_ref": "string",
                  "fee_amount": "200",
                  "net_amount": "4800",
                  "tx_ref": "string",
                  "customer_phone": "string",
                  "customer_email": "string",
                  "capture_mode": "auto",
                  "captured_amount": 0,
                  "fee_bearer": "merchant",
                  "created_at": "2026-01-01T00:00:00Z",
                  "updated_at": "2026-01-01T00:00:00Z",
                  "description": "string",
                  "metadata": {},
                  "customer_id": "string",
                  "dispute_id": "00000000-0000-4000-8000-000000000000",
                  "refunded_at": "2026-01-01T00:00:00Z",
                  "failure_reason": "string",
                  "failure_message": "string"
                }
              }
            },
            "headers": {
              "x-fapi-interaction-id": {
                "$ref": "#/components/headers/XFapiInteractionIdResponse"
              },
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/XRateLimitLimit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/XRateLimitRemaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/XRateLimitReset"
              },
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              },
              "X-Idempotent-Replay": {
                "$ref": "#/components/headers/X-Idempotent-Replay"
              },
              "X-Idempotency-Status": {
                "$ref": "#/components/headers/X-Idempotency-Status"
              },
              "traceparent": {
                "$ref": "#/components/headers/Traceparent"
              },
              "Content-Language": {
                "$ref": "#/components/headers/Content-Language"
              }
            }
          },
          "400": {
            "description": "Bad request",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              },
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                },
                "examples": {
                  "error": {
                    "$ref": "#/components/examples/ErrorBadRequest"
                  }
                }
              }
            },
            "headers": {
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/XRateLimitLimit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/XRateLimitRemaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/XRateLimitReset"
              },
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "403": {
            "$ref": "#/components/responses/Forbidden",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "404": {
            "$ref": "#/components/responses/NotFound",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "409": {
            "$ref": "#/components/responses/Conflict",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "429": {
            "$ref": "#/components/responses/TooManyRequests",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "500": {
            "$ref": "#/components/responses/InternalServerError",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          }
        },
        "x-codeSamples": [
          {
            "lang": "cURL",
            "label": "cURL",
            "source": "curl -X POST \"https://api.kangopenbanking.com/v1/gateway/charges/{chargeId}/cancel\" \\\n  -H \"Authorization: Bearer $KOB_ACCESS_TOKEN\" \\\n  -H \"Content-Type: application/json\""
          },
          {
            "lang": "JavaScript",
            "label": "Node.js",
            "source": "import { KangOpenBanking } from \"@kangopenbanking/sdk\";\n\nconst kob = new KangOpenBanking({ apiKey: process.env.KOB_API_KEY });\nconst res = await kob.request(\"POST\", \"/v1/gateway/charges/{chargeId}/cancel\");\nconsole.log(res);"
          },
          {
            "lang": "Python",
            "label": "Python",
            "source": "from kangopenbanking import KangOpenBanking\n\nkob = KangOpenBanking(api_key=os.environ[\"KOB_API_KEY\"])\nres = kob.request(\"POST\", \"/v1/gateway/charges/{chargeId}/cancel\")\nprint(res)"
          },
          {
            "lang": "PHP",
            "label": "PHP",
            "source": "<?php\n$kob = new KangOpenBanking\\KangOpenBanking(getenv('KOB_API_KEY'));\n$res = $kob->request('POST', '/v1/gateway/charges/{chargeId}/cancel');\nprint_r($res);"
          }
        ]
      }
    },
    "/v1/gateway/fee-estimate": {
      "get": {
        "tags": [
          "Payment Gateway"
        ],
        "summary": "Estimate transaction fees",
        "operationId": "gatewayFeeEstimate",
        "security": [
          {
            "bearerAuth": []
          }
        ],
        "parameters": [
          {
            "name": "amount",
            "in": "query",
            "required": true,
            "schema": {
              "type": "number"
            }
          },
          {
            "name": "channel",
            "in": "query",
            "required": true,
            "schema": {
              "type": "string",
              "enum": [
                "mobile_money",
                "card",
                "bank_transfer",
                "apple_pay",
                "google_pay",
                "ussd",
                "account_funding",
                "paypal"
              ]
            }
          },
          {
            "name": "currency",
            "in": "query",
            "schema": {
              "type": "string",
              "default": "XAF"
            }
          },
          {
            "$ref": "#/components/parameters/RequestId"
          },
          {
            "$ref": "#/components/parameters/Traceparent"
          },
          {
            "$ref": "#/components/parameters/Tracestate"
          },
          {
            "$ref": "#/components/parameters/AcceptLanguage"
          }
        ],
        "responses": {
          "200": {
            "description": "Fee estimate",
            "content": {
              "application/json": {
                "schema": {
                  "allOf": [
                    {
                      "$ref": "#/components/schemas/StandardResponse"
                    },
                    {
                      "type": "object",
                      "properties": {
                        "data": {
                          "$ref": "#/components/schemas/GatewayFeeEstimate"
                        }
                      }
                    }
                  ]
                },
                "example": {
                  "data": {
                    "amount": "5000",
                    "currency": "XAF",
                    "channel": "string",
                    "fee_amount": "200",
                    "net_amount": "4800",
                    "fee_percentage": "3%",
                    "fixed_fee": "50"
                  },
                  "meta": {
                    "request_id": "550e8400-e29b-41d4-a716-446655440000",
                    "timestamp": "2025-03-27T12:00:00Z",
                    "api_version": "4.3.0"
                  }
                }
              }
            },
            "headers": {
              "x-fapi-interaction-id": {
                "$ref": "#/components/headers/XFapiInteractionIdResponse"
              },
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/XRateLimitLimit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/XRateLimitRemaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/XRateLimitReset"
              },
              "Cache-Control": {
                "$ref": "#/components/headers/CacheControl"
              },
              "ETag": {
                "$ref": "#/components/headers/ETag"
              },
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              },
              "traceparent": {
                "$ref": "#/components/headers/Traceparent"
              },
              "Content-Language": {
                "$ref": "#/components/headers/Content-Language"
              }
            }
          },
          "400": {
            "description": "Bad request",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              },
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                },
                "examples": {
                  "error": {
                    "$ref": "#/components/examples/ErrorBadRequest"
                  }
                }
              }
            },
            "headers": {
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/XRateLimitLimit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/XRateLimitRemaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/XRateLimitReset"
              },
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "403": {
            "$ref": "#/components/responses/Forbidden",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "404": {
            "$ref": "#/components/responses/NotFound",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "409": {
            "$ref": "#/components/responses/Conflict",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "429": {
            "$ref": "#/components/responses/TooManyRequests",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "500": {
            "$ref": "#/components/responses/InternalServerError",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          }
        },
        "x-codeSamples": [
          {
            "lang": "cURL",
            "label": "cURL",
            "source": "curl -X GET \"https://api.kangopenbanking.com/v1/gateway/fee-estimate\" \\\n  -H \"Authorization: Bearer $KOB_ACCESS_TOKEN\" \\\n  -H \"Content-Type: application/json\""
          },
          {
            "lang": "JavaScript",
            "label": "Node.js",
            "source": "import { KangOpenBanking } from \"@kangopenbanking/sdk\";\n\nconst kob = new KangOpenBanking({ apiKey: process.env.KOB_API_KEY });\nconst res = await kob.request(\"GET\", \"/v1/gateway/fee-estimate\");\nconsole.log(res);"
          },
          {
            "lang": "Python",
            "label": "Python",
            "source": "from kangopenbanking import KangOpenBanking\n\nkob = KangOpenBanking(api_key=os.environ[\"KOB_API_KEY\"])\nres = kob.request(\"GET\", \"/v1/gateway/fee-estimate\")\nprint(res)"
          },
          {
            "lang": "PHP",
            "label": "PHP",
            "source": "<?php\n$kob = new KangOpenBanking\\KangOpenBanking(getenv('KOB_API_KEY'));\n$res = $kob->request('GET', '/v1/gateway/fee-estimate');\nprint_r($res);"
          }
        ]
      }
    },
    "/v1/gateway/refunds": {
      "post": {
        "tags": [
          "Payment Gateway"
        ],
        "summary": "Create refund",
        "operationId": "gatewayCreateRefund",
        "security": [
          {
            "bearerAuth": []
          }
        ],
        "parameters": [
          {
            "name": "Idempotency-Key",
            "in": "header",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid"
            },
            "description": "Required on all POST/PUT endpoints. Unique key for idempotent request processing (UUID v4 recommended). Keys expire after 24 hours."
          },
          {
            "$ref": "#/components/parameters/XFapiInteractionId"
          },
          {
            "$ref": "#/components/parameters/XFapiCustomerIpAddress"
          },
          {
            "$ref": "#/components/parameters/XFapiAuthDate"
          },
          {
            "$ref": "#/components/parameters/RequestId"
          },
          {
            "$ref": "#/components/parameters/Traceparent"
          },
          {
            "$ref": "#/components/parameters/Tracestate"
          },
          {
            "$ref": "#/components/parameters/AcceptLanguage"
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "required": [
                  "charge_id"
                ],
                "properties": {
                  "charge_id": {
                    "type": "string",
                    "format": "uuid"
                  },
                  "amount": {
                    "type": "string",
                    "pattern": "^[0-9]{1,15}$",
                    "description": "Represented as a string integer in the currency's minor unit (XAF has no subunits)."
                  },
                  "reason": {
                    "type": "string"
                  }
                }
              }
            }
          }
        },
        "responses": {
          "201": {
            "description": "Refund created",
            "content": {
              "application/json": {
                "schema": {
                  "allOf": [
                    {
                      "$ref": "#/components/schemas/StandardResponse"
                    },
                    {
                      "type": "object",
                      "properties": {
                        "data": {
                          "$ref": "#/components/schemas/GatewayRefund"
                        }
                      }
                    }
                  ]
                },
                "example": {
                  "data": {
                    "id": "00000000-0000-4000-8000-000000000000",
                    "charge_id": "00000000-0000-4000-8000-000000000000",
                    "amount": "5000",
                    "currency": "XAF",
                    "status": "pending",
                    "provider": "string",
                    "reason": "string",
                    "created_at": "2026-01-01T00:00:00Z"
                  },
                  "meta": {
                    "request_id": "550e8400-e29b-41d4-a716-446655440000",
                    "timestamp": "2025-03-27T12:00:00Z",
                    "api_version": "4.3.0"
                  }
                }
              }
            },
            "headers": {
              "x-fapi-interaction-id": {
                "$ref": "#/components/headers/XFapiInteractionIdResponse"
              },
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/XRateLimitLimit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/XRateLimitRemaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/XRateLimitReset"
              },
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              },
              "X-Idempotent-Replay": {
                "$ref": "#/components/headers/X-Idempotent-Replay"
              },
              "X-Idempotency-Status": {
                "$ref": "#/components/headers/X-Idempotency-Status"
              },
              "traceparent": {
                "$ref": "#/components/headers/Traceparent"
              },
              "Content-Language": {
                "$ref": "#/components/headers/Content-Language"
              }
            }
          },
          "400": {
            "description": "Bad request",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              },
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                },
                "examples": {
                  "error": {
                    "$ref": "#/components/examples/ErrorBadRequest"
                  }
                }
              }
            },
            "headers": {
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/XRateLimitLimit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/XRateLimitRemaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/XRateLimitReset"
              },
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "403": {
            "$ref": "#/components/responses/Forbidden",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "404": {
            "$ref": "#/components/responses/NotFound",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "409": {
            "$ref": "#/components/responses/Conflict",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "429": {
            "$ref": "#/components/responses/TooManyRequests",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "500": {
            "$ref": "#/components/responses/InternalServerError",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          }
        },
        "x-codeSamples": [
          {
            "lang": "cURL",
            "label": "cURL",
            "source": "curl -X POST \"https://api.kangopenbanking.com/v1/gateway/refunds\" \\\n  -H \"Authorization: Bearer $KOB_ACCESS_TOKEN\" \\\n  -H \"Content-Type: application/json\" \\\n  -d '{}'"
          },
          {
            "lang": "JavaScript",
            "label": "Node.js",
            "source": "import { KangOpenBanking } from \"@kangopenbanking/sdk\";\n\nconst kob = new KangOpenBanking({ apiKey: process.env.KOB_API_KEY });\nconst res = await kob.request(\"POST\", \"/v1/gateway/refunds\", { /* payload */ });\nconsole.log(res);"
          },
          {
            "lang": "Python",
            "label": "Python",
            "source": "from kangopenbanking import KangOpenBanking\n\nkob = KangOpenBanking(api_key=os.environ[\"KOB_API_KEY\"])\nres = kob.request(\"POST\", \"/v1/gateway/refunds\", json={})\nprint(res)"
          },
          {
            "lang": "PHP",
            "label": "PHP",
            "source": "<?php\n$kob = new KangOpenBanking\\KangOpenBanking(getenv('KOB_API_KEY'));\n$res = $kob->request('POST', '/v1/gateway/refunds', []);\nprint_r($res);"
          }
        ]
      },
      "get": {
        "tags": [
          "Payment Gateway"
        ],
        "summary": "List refunds",
        "operationId": "gatewayListRefunds",
        "security": [
          {
            "bearerAuth": []
          }
        ],
        "parameters": [
          {
            "name": "sort_by",
            "in": "query",
            "schema": {
              "type": "string",
              "default": "created_at"
            },
            "description": "Sort field"
          },
          {
            "name": "sort_order",
            "in": "query",
            "schema": {
              "type": "string",
              "enum": [
                "asc",
                "desc"
              ],
              "default": "desc"
            },
            "description": "Sort direction"
          },
          {
            "$ref": "#/components/parameters/PageParam"
          },
          {
            "$ref": "#/components/parameters/LimitParam"
          },
          {
            "$ref": "#/components/parameters/CursorParam"
          },
          {
            "$ref": "#/components/parameters/RequestId"
          },
          {
            "$ref": "#/components/parameters/Traceparent"
          },
          {
            "$ref": "#/components/parameters/Tracestate"
          },
          {
            "$ref": "#/components/parameters/AcceptLanguage"
          }
        ],
        "responses": {
          "200": {
            "description": "Refunds list",
            "content": {
              "application/json": {
                "schema": {
                  "allOf": [
                    {
                      "$ref": "#/components/schemas/PaginatedResponse"
                    },
                    {
                      "type": "object",
                      "properties": {
                        "data": {
                          "type": "array",
                          "items": {
                            "$ref": "#/components/schemas/GatewayRefund"
                          }
                        }
                      }
                    }
                  ]
                },
                "example": {
                  "data": [
                    {
                      "id": "f1d6f4a0-1d4e-4a3a-9e0a-1a2b3c4d5e6f",
                      "charge_id": "f1d6f4a0-1d4e-4a3a-9e0a-1a2b3c4d5e6f",
                      "amount": "5000",
                      "currency": "XAF",
                      "status": "pending",
                      "provider": "XAF",
                      "reason": "XAF",
                      "created_at": "2026-01-31T12:00:00Z"
                    }
                  ],
                  "pagination": {
                    "page": 1,
                    "limit": 20,
                    "total": 150,
                    "has_next": true,
                    "next_cursor": "eyJpZCI6IjEyMyJ9"
                  },
                  "meta": {
                    "request_id": "550e8400-e29b-41d4-a716-446655440000",
                    "timestamp": "2025-03-27T12:00:00Z",
                    "api_version": "4.3.0"
                  }
                }
              }
            },
            "headers": {
              "x-fapi-interaction-id": {
                "$ref": "#/components/headers/XFapiInteractionIdResponse"
              },
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/XRateLimitLimit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/XRateLimitRemaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/XRateLimitReset"
              },
              "Cache-Control": {
                "$ref": "#/components/headers/CacheControl"
              },
              "ETag": {
                "$ref": "#/components/headers/ETag"
              },
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              },
              "traceparent": {
                "$ref": "#/components/headers/Traceparent"
              },
              "Content-Language": {
                "$ref": "#/components/headers/Content-Language"
              }
            }
          },
          "400": {
            "description": "Bad request",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              },
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                },
                "examples": {
                  "error": {
                    "$ref": "#/components/examples/ErrorBadRequest"
                  }
                }
              }
            },
            "headers": {
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/XRateLimitLimit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/XRateLimitRemaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/XRateLimitReset"
              },
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "403": {
            "$ref": "#/components/responses/Forbidden",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "404": {
            "$ref": "#/components/responses/NotFound",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "409": {
            "$ref": "#/components/responses/Conflict",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "429": {
            "$ref": "#/components/responses/TooManyRequests",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "500": {
            "$ref": "#/components/responses/InternalServerError",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          }
        },
        "x-codeSamples": [
          {
            "lang": "cURL",
            "label": "cURL",
            "source": "curl -X GET \"https://api.kangopenbanking.com/v1/gateway/refunds\" \\\n  -H \"Authorization: Bearer $KOB_ACCESS_TOKEN\" \\\n  -H \"Content-Type: application/json\""
          },
          {
            "lang": "JavaScript",
            "label": "Node.js",
            "source": "import { KangOpenBanking } from \"@kangopenbanking/sdk\";\n\nconst kob = new KangOpenBanking({ apiKey: process.env.KOB_API_KEY });\nconst res = await kob.request(\"GET\", \"/v1/gateway/refunds\");\nconsole.log(res);"
          },
          {
            "lang": "Python",
            "label": "Python",
            "source": "from kangopenbanking import KangOpenBanking\n\nkob = KangOpenBanking(api_key=os.environ[\"KOB_API_KEY\"])\nres = kob.request(\"GET\", \"/v1/gateway/refunds\")\nprint(res)"
          },
          {
            "lang": "PHP",
            "label": "PHP",
            "source": "<?php\n$kob = new KangOpenBanking\\KangOpenBanking(getenv('KOB_API_KEY'));\n$res = $kob->request('GET', '/v1/gateway/refunds');\nprint_r($res);"
          }
        ]
      }
    },
    "/v1/gateway/refunds/{refundId}": {
      "get": {
        "tags": [
          "Payment Gateway"
        ],
        "summary": "Get refund",
        "operationId": "gatewayGetRefund",
        "security": [
          {
            "bearerAuth": []
          }
        ],
        "parameters": [
          {
            "name": "refundId",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "$ref": "#/components/parameters/RequestId"
          },
          {
            "$ref": "#/components/parameters/Traceparent"
          },
          {
            "$ref": "#/components/parameters/Tracestate"
          },
          {
            "$ref": "#/components/parameters/AcceptLanguage"
          }
        ],
        "responses": {
          "200": {
            "description": "Refund details",
            "content": {
              "application/json": {
                "schema": {
                  "allOf": [
                    {
                      "$ref": "#/components/schemas/StandardResponse"
                    },
                    {
                      "type": "object",
                      "properties": {
                        "data": {
                          "$ref": "#/components/schemas/GatewayRefund"
                        }
                      }
                    }
                  ]
                },
                "example": {
                  "data": {
                    "id": "00000000-0000-4000-8000-000000000000",
                    "charge_id": "00000000-0000-4000-8000-000000000000",
                    "amount": "5000",
                    "currency": "XAF",
                    "status": "pending",
                    "provider": "string",
                    "reason": "string",
                    "created_at": "2026-01-01T00:00:00Z"
                  },
                  "meta": {
                    "request_id": "550e8400-e29b-41d4-a716-446655440000",
                    "timestamp": "2025-03-27T12:00:00Z",
                    "api_version": "4.3.0"
                  }
                }
              }
            },
            "headers": {
              "x-fapi-interaction-id": {
                "$ref": "#/components/headers/XFapiInteractionIdResponse"
              },
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/XRateLimitLimit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/XRateLimitRemaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/XRateLimitReset"
              },
              "Cache-Control": {
                "$ref": "#/components/headers/CacheControl"
              },
              "ETag": {
                "$ref": "#/components/headers/ETag"
              },
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              },
              "traceparent": {
                "$ref": "#/components/headers/Traceparent"
              },
              "Content-Language": {
                "$ref": "#/components/headers/Content-Language"
              }
            }
          },
          "400": {
            "description": "Bad request",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              },
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                },
                "examples": {
                  "error": {
                    "$ref": "#/components/examples/ErrorBadRequest"
                  }
                }
              }
            },
            "headers": {
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/XRateLimitLimit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/XRateLimitRemaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/XRateLimitReset"
              },
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "403": {
            "$ref": "#/components/responses/Forbidden",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "404": {
            "$ref": "#/components/responses/NotFound",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "409": {
            "$ref": "#/components/responses/Conflict",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "429": {
            "$ref": "#/components/responses/TooManyRequests",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "500": {
            "$ref": "#/components/responses/InternalServerError",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          }
        },
        "x-codeSamples": [
          {
            "lang": "cURL",
            "label": "cURL",
            "source": "curl -X GET \"https://api.kangopenbanking.com/v1/gateway/refunds/{refundId}\" \\\n  -H \"Authorization: Bearer $KOB_ACCESS_TOKEN\" \\\n  -H \"Content-Type: application/json\""
          },
          {
            "lang": "JavaScript",
            "label": "Node.js",
            "source": "import { KangOpenBanking } from \"@kangopenbanking/sdk\";\n\nconst kob = new KangOpenBanking({ apiKey: process.env.KOB_API_KEY });\nconst res = await kob.request(\"GET\", \"/v1/gateway/refunds/{refundId}\");\nconsole.log(res);"
          },
          {
            "lang": "Python",
            "label": "Python",
            "source": "from kangopenbanking import KangOpenBanking\n\nkob = KangOpenBanking(api_key=os.environ[\"KOB_API_KEY\"])\nres = kob.request(\"GET\", \"/v1/gateway/refunds/{refundId}\")\nprint(res)"
          },
          {
            "lang": "PHP",
            "label": "PHP",
            "source": "<?php\n$kob = new KangOpenBanking\\KangOpenBanking(getenv('KOB_API_KEY'));\n$res = $kob->request('GET', '/v1/gateway/refunds/{refundId}');\nprint_r($res);"
          }
        ]
      }
    },
    "/v1/gateway/payouts": {
      "post": {
        "tags": [
          "Payment Gateway"
        ],
        "summary": "Create payout",
        "operationId": "gatewayCreatePayout",
        "security": [
          {
            "bearerAuth": []
          }
        ],
        "parameters": [
          {
            "name": "Idempotency-Key",
            "in": "header",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid"
            },
            "description": "Required on all POST/PUT endpoints. Unique key for idempotent request processing (UUID v4 recommended). Keys expire after 24 hours."
          },
          {
            "$ref": "#/components/parameters/XFapiInteractionId"
          },
          {
            "$ref": "#/components/parameters/XFapiCustomerIpAddress"
          },
          {
            "$ref": "#/components/parameters/XFapiAuthDate"
          },
          {
            "$ref": "#/components/parameters/RequestId"
          },
          {
            "$ref": "#/components/parameters/Traceparent"
          },
          {
            "$ref": "#/components/parameters/Tracestate"
          },
          {
            "$ref": "#/components/parameters/AcceptLanguage"
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "required": [
                  "merchant_id",
                  "amount",
                  "channel"
                ],
                "properties": {
                  "merchant_id": {
                    "type": "string",
                    "format": "uuid"
                  },
                  "amount": {
                    "type": "string",
                    "pattern": "^[0-9]{1,15}$",
                    "description": "Represented as a string integer in the currency's minor unit (XAF has no subunits). Must be consistent with the currency field."
                  },
                  "currency": {
                    "type": "string",
                    "enum": [
                      "XAF",
                      "XOF",
                      "USD",
                      "EUR",
                      "GBP",
                      "CNY",
                      "NGN",
                      "GHS",
                      "KES",
                      "ZAR"
                    ],
                    "default": "XAF",
                    "description": "ISO 4217 currency code. Default is XAF (Central African CFA Franc)."
                  },
                  "channel": {
                    "type": "string",
                    "enum": [
                      "mobile_money",
                      "bank_transfer"
                    ]
                  },
                  "beneficiary_phone": {
                    "type": "string"
                  },
                  "beneficiary_name": {
                    "type": "string"
                  },
                  "beneficiary_account": {
                    "type": "string"
                  },
                  "beneficiary_bank": {
                    "type": "string"
                  },
                  "narration": {
                    "type": "string"
                  },
                  "tx_ref": {
                    "type": "string"
                  }
                }
              }
            }
          }
        },
        "responses": {
          "201": {
            "description": "Payout created",
            "content": {
              "application/json": {
                "schema": {
                  "allOf": [
                    {
                      "$ref": "#/components/schemas/StandardResponse"
                    },
                    {
                      "type": "object",
                      "properties": {
                        "data": {
                          "$ref": "#/components/schemas/GatewayPayout"
                        }
                      }
                    }
                  ]
                },
                "example": {
                  "data": {
                    "id": "00000000-0000-4000-8000-000000000000",
                    "merchant_id": "00000000-0000-4000-8000-000000000000",
                    "amount": "10000",
                    "currency": "XAF",
                    "channel": "mobile_money",
                    "status": "pending",
                    "beneficiary_name": "string",
                    "beneficiary_phone": "string",
                    "tx_ref": "string",
                    "created_at": "2026-01-01T00:00:00Z"
                  },
                  "meta": {
                    "request_id": "550e8400-e29b-41d4-a716-446655440000",
                    "timestamp": "2025-03-27T12:00:00Z",
                    "api_version": "4.3.0"
                  }
                }
              }
            },
            "headers": {
              "x-fapi-interaction-id": {
                "$ref": "#/components/headers/XFapiInteractionIdResponse"
              },
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/XRateLimitLimit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/XRateLimitRemaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/XRateLimitReset"
              },
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              },
              "X-Idempotent-Replay": {
                "$ref": "#/components/headers/X-Idempotent-Replay"
              },
              "X-Idempotency-Status": {
                "$ref": "#/components/headers/X-Idempotency-Status"
              },
              "traceparent": {
                "$ref": "#/components/headers/Traceparent"
              },
              "Content-Language": {
                "$ref": "#/components/headers/Content-Language"
              }
            }
          },
          "400": {
            "description": "Bad request",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              },
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                },
                "examples": {
                  "error": {
                    "$ref": "#/components/examples/ErrorBadRequest"
                  }
                }
              }
            },
            "headers": {
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/XRateLimitLimit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/XRateLimitRemaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/XRateLimitReset"
              },
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "403": {
            "$ref": "#/components/responses/Forbidden",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "404": {
            "$ref": "#/components/responses/NotFound",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "409": {
            "$ref": "#/components/responses/Conflict",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "429": {
            "$ref": "#/components/responses/TooManyRequests",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "500": {
            "$ref": "#/components/responses/InternalServerError",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          }
        },
        "x-codeSamples": [
          {
            "lang": "cURL",
            "label": "cURL",
            "source": "curl -X POST \"https://api.kangopenbanking.com/v1/gateway/payouts\" \\\n  -H \"Authorization: Bearer $KOB_ACCESS_TOKEN\" \\\n  -H \"Content-Type: application/json\" \\\n  -d '{}'"
          },
          {
            "lang": "JavaScript",
            "label": "Node.js",
            "source": "import { KangOpenBanking } from \"@kangopenbanking/sdk\";\n\nconst kob = new KangOpenBanking({ apiKey: process.env.KOB_API_KEY });\nconst res = await kob.request(\"POST\", \"/v1/gateway/payouts\", { /* payload */ });\nconsole.log(res);"
          },
          {
            "lang": "Python",
            "label": "Python",
            "source": "from kangopenbanking import KangOpenBanking\n\nkob = KangOpenBanking(api_key=os.environ[\"KOB_API_KEY\"])\nres = kob.request(\"POST\", \"/v1/gateway/payouts\", json={})\nprint(res)"
          },
          {
            "lang": "PHP",
            "label": "PHP",
            "source": "<?php\n$kob = new KangOpenBanking\\KangOpenBanking(getenv('KOB_API_KEY'));\n$res = $kob->request('POST', '/v1/gateway/payouts', []);\nprint_r($res);"
          }
        ]
      },
      "get": {
        "tags": [
          "Payment Gateway"
        ],
        "summary": "List payouts",
        "operationId": "gatewayListPayouts",
        "security": [
          {
            "bearerAuth": []
          }
        ],
        "parameters": [
          {
            "name": "merchant_id",
            "in": "query",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "status",
            "in": "query",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "sort_by",
            "in": "query",
            "schema": {
              "type": "string",
              "default": "created_at"
            },
            "description": "Sort field"
          },
          {
            "name": "sort_order",
            "in": "query",
            "schema": {
              "type": "string",
              "enum": [
                "asc",
                "desc"
              ],
              "default": "desc"
            },
            "description": "Sort direction"
          },
          {
            "$ref": "#/components/parameters/PageParam"
          },
          {
            "$ref": "#/components/parameters/LimitParam"
          },
          {
            "$ref": "#/components/parameters/CursorParam"
          },
          {
            "$ref": "#/components/parameters/RequestId"
          },
          {
            "$ref": "#/components/parameters/Traceparent"
          },
          {
            "$ref": "#/components/parameters/Tracestate"
          },
          {
            "$ref": "#/components/parameters/AcceptLanguage"
          }
        ],
        "responses": {
          "200": {
            "description": "Payouts list",
            "content": {
              "application/json": {
                "schema": {
                  "allOf": [
                    {
                      "$ref": "#/components/schemas/PaginatedResponse"
                    },
                    {
                      "type": "object",
                      "properties": {
                        "data": {
                          "type": "array",
                          "items": {
                            "$ref": "#/components/schemas/GatewayPayout"
                          }
                        }
                      }
                    }
                  ]
                },
                "example": {
                  "data": [
                    {
                      "id": "f1d6f4a0-1d4e-4a3a-9e0a-1a2b3c4d5e6f",
                      "merchant_id": "f1d6f4a0-1d4e-4a3a-9e0a-1a2b3c4d5e6f",
                      "amount": "10000",
                      "currency": "XAF",
                      "channel": "mobile_money",
                      "status": "pending",
                      "beneficiary_name": "XAF",
                      "beneficiary_phone": "XAF",
                      "tx_ref": "XAF",
                      "created_at": "2026-01-31T12:00:00Z"
                    }
                  ],
                  "pagination": {
                    "page": 1,
                    "limit": 20,
                    "total": 150,
                    "has_next": true,
                    "next_cursor": "eyJpZCI6IjEyMyJ9"
                  },
                  "meta": {
                    "request_id": "550e8400-e29b-41d4-a716-446655440000",
                    "timestamp": "2025-03-27T12:00:00Z",
                    "api_version": "4.3.0"
                  }
                }
              }
            },
            "headers": {
              "x-fapi-interaction-id": {
                "$ref": "#/components/headers/XFapiInteractionIdResponse"
              },
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/XRateLimitLimit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/XRateLimitRemaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/XRateLimitReset"
              },
              "Cache-Control": {
                "$ref": "#/components/headers/CacheControl"
              },
              "ETag": {
                "$ref": "#/components/headers/ETag"
              },
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              },
              "traceparent": {
                "$ref": "#/components/headers/Traceparent"
              },
              "Content-Language": {
                "$ref": "#/components/headers/Content-Language"
              }
            }
          },
          "400": {
            "description": "Bad request",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              },
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                },
                "examples": {
                  "error": {
                    "$ref": "#/components/examples/ErrorBadRequest"
                  }
                }
              }
            },
            "headers": {
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/XRateLimitLimit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/XRateLimitRemaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/XRateLimitReset"
              },
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "403": {
            "$ref": "#/components/responses/Forbidden",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "404": {
            "$ref": "#/components/responses/NotFound",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "409": {
            "$ref": "#/components/responses/Conflict",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "429": {
            "$ref": "#/components/responses/TooManyRequests",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "500": {
            "$ref": "#/components/responses/InternalServerError",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          }
        },
        "x-codeSamples": [
          {
            "lang": "cURL",
            "label": "cURL",
            "source": "curl -X GET \"https://api.kangopenbanking.com/v1/gateway/payouts\" \\\n  -H \"Authorization: Bearer $KOB_ACCESS_TOKEN\" \\\n  -H \"Content-Type: application/json\""
          },
          {
            "lang": "JavaScript",
            "label": "Node.js",
            "source": "import { KangOpenBanking } from \"@kangopenbanking/sdk\";\n\nconst kob = new KangOpenBanking({ apiKey: process.env.KOB_API_KEY });\nconst res = await kob.request(\"GET\", \"/v1/gateway/payouts\");\nconsole.log(res);"
          },
          {
            "lang": "Python",
            "label": "Python",
            "source": "from kangopenbanking import KangOpenBanking\n\nkob = KangOpenBanking(api_key=os.environ[\"KOB_API_KEY\"])\nres = kob.request(\"GET\", \"/v1/gateway/payouts\")\nprint(res)"
          },
          {
            "lang": "PHP",
            "label": "PHP",
            "source": "<?php\n$kob = new KangOpenBanking\\KangOpenBanking(getenv('KOB_API_KEY'));\n$res = $kob->request('GET', '/v1/gateway/payouts');\nprint_r($res);"
          }
        ]
      }
    },
    "/v1/gateway/payouts/{payoutId}": {
      "get": {
        "tags": [
          "Payment Gateway"
        ],
        "summary": "Get payout",
        "operationId": "gatewayGetPayout",
        "security": [
          {
            "bearerAuth": []
          }
        ],
        "parameters": [
          {
            "name": "payoutId",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "$ref": "#/components/parameters/RequestId"
          },
          {
            "$ref": "#/components/parameters/Traceparent"
          },
          {
            "$ref": "#/components/parameters/Tracestate"
          },
          {
            "$ref": "#/components/parameters/AcceptLanguage"
          }
        ],
        "responses": {
          "200": {
            "description": "Payout details",
            "content": {
              "application/json": {
                "schema": {
                  "allOf": [
                    {
                      "$ref": "#/components/schemas/StandardResponse"
                    },
                    {
                      "type": "object",
                      "properties": {
                        "data": {
                          "$ref": "#/components/schemas/GatewayPayout"
                        }
                      }
                    }
                  ]
                },
                "example": {
                  "data": {
                    "id": "00000000-0000-4000-8000-000000000000",
                    "merchant_id": "00000000-0000-4000-8000-000000000000",
                    "amount": "10000",
                    "currency": "XAF",
                    "channel": "mobile_money",
                    "status": "pending",
                    "beneficiary_name": "string",
                    "beneficiary_phone": "string",
                    "tx_ref": "string",
                    "created_at": "2026-01-01T00:00:00Z"
                  },
                  "meta": {
                    "request_id": "550e8400-e29b-41d4-a716-446655440000",
                    "timestamp": "2025-03-27T12:00:00Z",
                    "api_version": "4.3.0"
                  }
                }
              }
            },
            "headers": {
              "x-fapi-interaction-id": {
                "$ref": "#/components/headers/XFapiInteractionIdResponse"
              },
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/XRateLimitLimit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/XRateLimitRemaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/XRateLimitReset"
              },
              "Cache-Control": {
                "$ref": "#/components/headers/CacheControl"
              },
              "ETag": {
                "$ref": "#/components/headers/ETag"
              },
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              },
              "traceparent": {
                "$ref": "#/components/headers/Traceparent"
              },
              "Content-Language": {
                "$ref": "#/components/headers/Content-Language"
              }
            }
          },
          "400": {
            "description": "Bad request",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              },
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                },
                "examples": {
                  "error": {
                    "$ref": "#/components/examples/ErrorBadRequest"
                  }
                }
              }
            },
            "headers": {
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/XRateLimitLimit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/XRateLimitRemaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/XRateLimitReset"
              },
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "403": {
            "$ref": "#/components/responses/Forbidden",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "404": {
            "$ref": "#/components/responses/NotFound",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "409": {
            "$ref": "#/components/responses/Conflict",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "429": {
            "$ref": "#/components/responses/TooManyRequests",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "500": {
            "$ref": "#/components/responses/InternalServerError",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          }
        },
        "x-codeSamples": [
          {
            "lang": "cURL",
            "label": "cURL",
            "source": "curl -X GET \"https://api.kangopenbanking.com/v1/gateway/payouts/{payoutId}\" \\\n  -H \"Authorization: Bearer $KOB_ACCESS_TOKEN\" \\\n  -H \"Content-Type: application/json\""
          },
          {
            "lang": "JavaScript",
            "label": "Node.js",
            "source": "import { KangOpenBanking } from \"@kangopenbanking/sdk\";\n\nconst kob = new KangOpenBanking({ apiKey: process.env.KOB_API_KEY });\nconst res = await kob.request(\"GET\", \"/v1/gateway/payouts/{payoutId}\");\nconsole.log(res);"
          },
          {
            "lang": "Python",
            "label": "Python",
            "source": "from kangopenbanking import KangOpenBanking\n\nkob = KangOpenBanking(api_key=os.environ[\"KOB_API_KEY\"])\nres = kob.request(\"GET\", \"/v1/gateway/payouts/{payoutId}\")\nprint(res)"
          },
          {
            "lang": "PHP",
            "label": "PHP",
            "source": "<?php\n$kob = new KangOpenBanking\\KangOpenBanking(getenv('KOB_API_KEY'));\n$res = $kob->request('GET', '/v1/gateway/payouts/{payoutId}');\nprint_r($res);"
          }
        ]
      }
    },
    "/v1/gateway/payout-batches": {
      "post": {
        "tags": [
          "Payment Gateway"
        ],
        "summary": "Create payout batch",
        "operationId": "gatewayCreatePayoutBatch",
        "security": [
          {
            "bearerAuth": []
          }
        ],
        "parameters": [
          {
            "name": "Idempotency-Key",
            "in": "header",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid"
            },
            "description": "Required on all POST/PUT endpoints. Unique key for idempotent request processing (UUID v4 recommended). Keys expire after 24 hours."
          },
          {
            "$ref": "#/components/parameters/RequestId"
          },
          {
            "$ref": "#/components/parameters/Traceparent"
          },
          {
            "$ref": "#/components/parameters/Tracestate"
          },
          {
            "$ref": "#/components/parameters/AcceptLanguage"
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "required": [
                  "merchant_id",
                  "currency",
                  "items"
                ],
                "properties": {
                  "merchant_id": {
                    "type": "string"
                  },
                  "currency": {
                    "type": "string",
                    "enum": [
                      "XAF",
                      "XOF",
                      "USD",
                      "EUR",
                      "GBP",
                      "CNY",
                      "NGN",
                      "GHS",
                      "KES",
                      "ZAR"
                    ],
                    "default": "XAF",
                    "description": "ISO 4217 currency code. Default is XAF (Central African CFA Franc)."
                  },
                  "items": {
                    "type": "array",
                    "items": {
                      "type": "object"
                    }
                  }
                }
              }
            }
          }
        },
        "responses": {
          "201": {
            "description": "Batch created",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "id": {
                      "type": "string",
                      "format": "uuid"
                    },
                    "status": {
                      "type": "string",
                      "example": "pending"
                    },
                    "items_count": {
                      "type": "integer"
                    },
                    "total_amount": {
                      "type": "string",
                      "pattern": "^[0-9]{1,15}$",
                      "description": "Represented as a string integer in the currency's minor unit (XAF has no subunits). Must be consistent with the currency field."
                    },
                    "currency": {
                      "type": "string",
                      "enum": [
                        "XAF",
                        "XOF",
                        "USD",
                        "EUR",
                        "GBP",
                        "CNY",
                        "NGN",
                        "GHS",
                        "KES",
                        "ZAR"
                      ],
                      "default": "XAF",
                      "description": "ISO 4217 currency code. Default is XAF (Central African CFA Franc)."
                    },
                    "created_at": {
                      "type": "string",
                      "format": "date-time"
                    }
                  }
                },
                "example": {
                  "id": "00000000-0000-4000-8000-000000000000",
                  "status": "pending",
                  "items_count": 0,
                  "total_amount": "1000",
                  "currency": "XAF",
                  "created_at": "2026-01-01T00:00:00Z"
                }
              }
            },
            "headers": {
              "x-fapi-interaction-id": {
                "$ref": "#/components/headers/XFapiInteractionIdResponse"
              },
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/XRateLimitLimit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/XRateLimitRemaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/XRateLimitReset"
              },
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              },
              "X-Idempotent-Replay": {
                "$ref": "#/components/headers/X-Idempotent-Replay"
              },
              "X-Idempotency-Status": {
                "$ref": "#/components/headers/X-Idempotency-Status"
              },
              "traceparent": {
                "$ref": "#/components/headers/Traceparent"
              },
              "Content-Language": {
                "$ref": "#/components/headers/Content-Language"
              }
            }
          },
          "400": {
            "description": "Bad request",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              },
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                },
                "examples": {
                  "error": {
                    "$ref": "#/components/examples/ErrorBadRequest"
                  }
                }
              }
            },
            "headers": {
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/XRateLimitLimit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/XRateLimitRemaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/XRateLimitReset"
              },
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "403": {
            "$ref": "#/components/responses/Forbidden",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "404": {
            "$ref": "#/components/responses/NotFound",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "409": {
            "$ref": "#/components/responses/Conflict",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "429": {
            "$ref": "#/components/responses/TooManyRequests",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "500": {
            "$ref": "#/components/responses/InternalServerError",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          }
        },
        "x-codeSamples": [
          {
            "lang": "cURL",
            "label": "cURL",
            "source": "curl -X POST \"https://api.kangopenbanking.com/v1/gateway/payout-batches\" \\\n  -H \"Authorization: Bearer $KOB_ACCESS_TOKEN\" \\\n  -H \"Content-Type: application/json\" \\\n  -d '{}'"
          },
          {
            "lang": "JavaScript",
            "label": "Node.js",
            "source": "import { KangOpenBanking } from \"@kangopenbanking/sdk\";\n\nconst kob = new KangOpenBanking({ apiKey: process.env.KOB_API_KEY });\nconst res = await kob.request(\"POST\", \"/v1/gateway/payout-batches\", { /* payload */ });\nconsole.log(res);"
          },
          {
            "lang": "Python",
            "label": "Python",
            "source": "from kangopenbanking import KangOpenBanking\n\nkob = KangOpenBanking(api_key=os.environ[\"KOB_API_KEY\"])\nres = kob.request(\"POST\", \"/v1/gateway/payout-batches\", json={})\nprint(res)"
          },
          {
            "lang": "PHP",
            "label": "PHP",
            "source": "<?php\n$kob = new KangOpenBanking\\KangOpenBanking(getenv('KOB_API_KEY'));\n$res = $kob->request('POST', '/v1/gateway/payout-batches', []);\nprint_r($res);"
          }
        ]
      }
    },
    "/v1/gateway/payout-batches/{batchId}": {
      "get": {
        "tags": [
          "Payment Gateway"
        ],
        "summary": "Get payout batch",
        "operationId": "gatewayGetPayoutBatch",
        "security": [
          {
            "bearerAuth": []
          }
        ],
        "parameters": [
          {
            "name": "batchId",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "$ref": "#/components/parameters/RequestId"
          },
          {
            "$ref": "#/components/parameters/Traceparent"
          },
          {
            "$ref": "#/components/parameters/Tracestate"
          },
          {
            "$ref": "#/components/parameters/AcceptLanguage"
          }
        ],
        "responses": {
          "200": {
            "description": "Batch details",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "id": {
                      "type": "string"
                    },
                    "status": {
                      "type": "string"
                    },
                    "total_amount": {
                      "type": "string",
                      "pattern": "^[0-9]{1,15}$",
                      "description": "Represented as a string integer in the currency's minor unit (XAF has no subunits)."
                    },
                    "items_count": {
                      "type": "integer"
                    }
                  }
                },
                "example": {
                  "id": "string",
                  "status": "string",
                  "total_amount": "1000",
                  "items_count": 0
                }
              }
            },
            "headers": {
              "x-fapi-interaction-id": {
                "$ref": "#/components/headers/XFapiInteractionIdResponse"
              },
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/XRateLimitLimit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/XRateLimitRemaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/XRateLimitReset"
              },
              "Cache-Control": {
                "$ref": "#/components/headers/CacheControl"
              },
              "ETag": {
                "$ref": "#/components/headers/ETag"
              },
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              },
              "traceparent": {
                "$ref": "#/components/headers/Traceparent"
              },
              "Content-Language": {
                "$ref": "#/components/headers/Content-Language"
              }
            }
          },
          "400": {
            "description": "Bad request",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              },
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                },
                "examples": {
                  "error": {
                    "$ref": "#/components/examples/ErrorBadRequest"
                  }
                }
              }
            },
            "headers": {
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/XRateLimitLimit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/XRateLimitRemaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/XRateLimitReset"
              },
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "403": {
            "$ref": "#/components/responses/Forbidden",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "404": {
            "$ref": "#/components/responses/NotFound",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "409": {
            "$ref": "#/components/responses/Conflict",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "429": {
            "$ref": "#/components/responses/TooManyRequests",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "500": {
            "$ref": "#/components/responses/InternalServerError",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          }
        },
        "x-codeSamples": [
          {
            "lang": "cURL",
            "label": "cURL",
            "source": "curl -X GET \"https://api.kangopenbanking.com/v1/gateway/payout-batches/{batchId}\" \\\n  -H \"Authorization: Bearer $KOB_ACCESS_TOKEN\" \\\n  -H \"Content-Type: application/json\""
          },
          {
            "lang": "JavaScript",
            "label": "Node.js",
            "source": "import { KangOpenBanking } from \"@kangopenbanking/sdk\";\n\nconst kob = new KangOpenBanking({ apiKey: process.env.KOB_API_KEY });\nconst res = await kob.request(\"GET\", \"/v1/gateway/payout-batches/{batchId}\");\nconsole.log(res);"
          },
          {
            "lang": "Python",
            "label": "Python",
            "source": "from kangopenbanking import KangOpenBanking\n\nkob = KangOpenBanking(api_key=os.environ[\"KOB_API_KEY\"])\nres = kob.request(\"GET\", \"/v1/gateway/payout-batches/{batchId}\")\nprint(res)"
          },
          {
            "lang": "PHP",
            "label": "PHP",
            "source": "<?php\n$kob = new KangOpenBanking\\KangOpenBanking(getenv('KOB_API_KEY'));\n$res = $kob->request('GET', '/v1/gateway/payout-batches/{batchId}');\nprint_r($res);"
          }
        ]
      }
    },
    "/v1/gateway/payouts/paypal": {
      "post": {
        "tags": [
          "Payment Gateway"
        ],
        "summary": "Create PayPal payout",
        "description": "Send money to a PayPal recipient via EMAIL, PHONE, or PAYPAL_ID. Currency must be PayPal-supported (USD, EUR, GBP).",
        "operationId": "gatewayCreatePayPalPayout",
        "security": [
          {
            "bearerAuth": []
          }
        ],
        "parameters": [
          {
            "name": "Idempotency-Key",
            "in": "header",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid"
            },
            "description": "Required on all POST/PUT endpoints. Unique key for idempotent request processing (UUID v4 recommended). Keys expire after 24 hours."
          },
          {
            "$ref": "#/components/parameters/RequestId"
          },
          {
            "$ref": "#/components/parameters/Traceparent"
          },
          {
            "$ref": "#/components/parameters/Tracestate"
          },
          {
            "$ref": "#/components/parameters/AcceptLanguage"
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "required": [
                  "merchant_id",
                  "amount",
                  "currency",
                  "recipient_type",
                  "receiver",
                  "tx_ref"
                ],
                "properties": {
                  "merchant_id": {
                    "type": "string",
                    "format": "uuid"
                  },
                  "amount": {
                    "type": "string",
                    "example": "5000",
                    "pattern": "^[0-9]{1,15}$",
                    "description": "Represented as a string integer in the currency's minor unit (XAF has no subunits). Must be consistent with the currency field."
                  },
                  "currency": {
                    "type": "string",
                    "example": "USD",
                    "description": "ISO 4217 currency code. Default is XAF (Central African CFA Franc).",
                    "enum": [
                      "XAF",
                      "XOF",
                      "USD",
                      "EUR",
                      "GBP",
                      "CNY",
                      "NGN",
                      "GHS",
                      "KES",
                      "ZAR"
                    ],
                    "default": "XAF"
                  },
                  "recipient_type": {
                    "type": "string",
                    "enum": [
                      "EMAIL",
                      "PHONE",
                      "PAYPAL_ID"
                    ]
                  },
                  "receiver": {
                    "type": "string",
                    "example": "recipient@example.com"
                  },
                  "note": {
                    "type": "string"
                  },
                  "tx_ref": {
                    "type": "string"
                  }
                }
              }
            }
          }
        },
        "responses": {
          "201": {
            "description": "PayPal payout created",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/GatewayPayout"
                },
                "example": {
                  "id": "00000000-0000-4000-8000-000000000000",
                  "merchant_id": "00000000-0000-4000-8000-000000000000",
                  "amount": "10000",
                  "currency": "XAF",
                  "channel": "mobile_money",
                  "status": "pending",
                  "beneficiary_name": "string",
                  "beneficiary_phone": "string",
                  "tx_ref": "string",
                  "created_at": "2026-01-01T00:00:00Z"
                }
              }
            },
            "headers": {
              "x-fapi-interaction-id": {
                "$ref": "#/components/headers/XFapiInteractionIdResponse"
              },
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/XRateLimitLimit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/XRateLimitRemaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/XRateLimitReset"
              },
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              },
              "X-Idempotent-Replay": {
                "$ref": "#/components/headers/X-Idempotent-Replay"
              },
              "X-Idempotency-Status": {
                "$ref": "#/components/headers/X-Idempotency-Status"
              },
              "traceparent": {
                "$ref": "#/components/headers/Traceparent"
              },
              "Content-Language": {
                "$ref": "#/components/headers/Content-Language"
              }
            }
          },
          "400": {
            "description": "Bad request",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              },
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                },
                "examples": {
                  "error": {
                    "$ref": "#/components/examples/ErrorBadRequest"
                  }
                }
              }
            },
            "headers": {
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/XRateLimitLimit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/XRateLimitRemaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/XRateLimitReset"
              },
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "403": {
            "$ref": "#/components/responses/Forbidden",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "404": {
            "$ref": "#/components/responses/NotFound",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "409": {
            "$ref": "#/components/responses/Conflict",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "429": {
            "$ref": "#/components/responses/TooManyRequests",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "500": {
            "$ref": "#/components/responses/InternalServerError",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          }
        },
        "x-codeSamples": [
          {
            "lang": "cURL",
            "label": "cURL",
            "source": "curl -X POST \"https://api.kangopenbanking.com/v1/gateway/payouts/paypal\" \\\n  -H \"Authorization: Bearer $KOB_ACCESS_TOKEN\" \\\n  -H \"Content-Type: application/json\" \\\n  -d '{}'"
          },
          {
            "lang": "JavaScript",
            "label": "Node.js",
            "source": "import { KangOpenBanking } from \"@kangopenbanking/sdk\";\n\nconst kob = new KangOpenBanking({ apiKey: process.env.KOB_API_KEY });\nconst res = await kob.request(\"POST\", \"/v1/gateway/payouts/paypal\", { /* payload */ });\nconsole.log(res);"
          },
          {
            "lang": "Python",
            "label": "Python",
            "source": "from kangopenbanking import KangOpenBanking\n\nkob = KangOpenBanking(api_key=os.environ[\"KOB_API_KEY\"])\nres = kob.request(\"POST\", \"/v1/gateway/payouts/paypal\", json={})\nprint(res)"
          },
          {
            "lang": "PHP",
            "label": "PHP",
            "source": "<?php\n$kob = new KangOpenBanking\\KangOpenBanking(getenv('KOB_API_KEY'));\n$res = $kob->request('POST', '/v1/gateway/payouts/paypal', []);\nprint_r($res);"
          }
        ]
      }
    },
    "/v1/gateway/withdraw-to-paypal": {
      "post": {
        "tags": [
          "Payment Gateway"
        ],
        "summary": "Withdraw to PayPal",
        "description": "Withdraw KOB account balance to a PayPal email. Account is debited immediately with automatic reversal on failure.",
        "operationId": "gatewayWithdrawToPayPal",
        "security": [
          {
            "bearerAuth": []
          }
        ],
        "parameters": [
          {
            "name": "Idempotency-Key",
            "in": "header",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid"
            },
            "description": "Required on all POST/PUT endpoints. Unique key for idempotent request processing (UUID v4 recommended). Keys expire after 24 hours."
          },
          {
            "$ref": "#/components/parameters/RequestId"
          },
          {
            "$ref": "#/components/parameters/Traceparent"
          },
          {
            "$ref": "#/components/parameters/Tracestate"
          },
          {
            "$ref": "#/components/parameters/AcceptLanguage"
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "required": [
                  "amount",
                  "account_id",
                  "paypal_email"
                ],
                "properties": {
                  "amount": {
                    "type": "string",
                    "example": "10000",
                    "pattern": "^[0-9]{1,15}$",
                    "description": "Represented as a string integer in the currency's minor unit (XAF has no subunits). Must be consistent with the currency field."
                  },
                  "account_id": {
                    "type": "string",
                    "format": "uuid"
                  },
                  "paypal_email": {
                    "type": "string",
                    "format": "email"
                  },
                  "currency": {
                    "type": "string",
                    "default": "USD",
                    "enum": [
                      "XAF",
                      "XOF",
                      "USD",
                      "EUR",
                      "GBP",
                      "CNY",
                      "NGN",
                      "GHS",
                      "KES",
                      "ZAR"
                    ],
                    "description": "ISO 4217 currency code. Default is XAF (Central African CFA Franc)."
                  },
                  "narration": {
                    "type": "string"
                  }
                }
              }
            }
          }
        },
        "responses": {
          "201": {
            "description": "Withdrawal initiated",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "id": {
                      "type": "string"
                    },
                    "amount": {
                      "type": "string",
                      "pattern": "^[0-9]{1,15}$",
                      "description": "Represented as a string integer in the currency's minor unit (XAF has no subunits). Must be consistent with the currency field."
                    },
                    "fee_amount": {
                      "type": "number"
                    },
                    "total_debited": {
                      "type": "number"
                    },
                    "currency": {
                      "type": "string",
                      "enum": [
                        "XAF",
                        "XOF",
                        "USD",
                        "EUR",
                        "GBP",
                        "CNY",
                        "NGN",
                        "GHS",
                        "KES",
                        "ZAR"
                      ],
                      "default": "XAF",
                      "description": "ISO 4217 currency code. Default is XAF (Central African CFA Franc)."
                    },
                    "status": {
                      "type": "string"
                    },
                    "paypal_email": {
                      "type": "string"
                    },
                    "batch_id": {
                      "type": "string"
                    },
                    "tx_ref": {
                      "type": "string"
                    }
                  }
                },
                "example": {
                  "id": "string",
                  "amount": "1000",
                  "fee_amount": 0,
                  "total_debited": 0,
                  "currency": "XAF",
                  "status": "string",
                  "paypal_email": "string",
                  "batch_id": "string",
                  "tx_ref": "string"
                }
              }
            },
            "headers": {
              "x-fapi-interaction-id": {
                "$ref": "#/components/headers/XFapiInteractionIdResponse"
              },
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/XRateLimitLimit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/XRateLimitRemaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/XRateLimitReset"
              },
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              },
              "X-Idempotent-Replay": {
                "$ref": "#/components/headers/X-Idempotent-Replay"
              },
              "X-Idempotency-Status": {
                "$ref": "#/components/headers/X-Idempotency-Status"
              },
              "traceparent": {
                "$ref": "#/components/headers/Traceparent"
              },
              "Content-Language": {
                "$ref": "#/components/headers/Content-Language"
              }
            }
          },
          "400": {
            "description": "Bad request",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              },
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                },
                "examples": {
                  "error": {
                    "$ref": "#/components/examples/ErrorBadRequest"
                  }
                }
              }
            },
            "headers": {
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/XRateLimitLimit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/XRateLimitRemaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/XRateLimitReset"
              },
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "403": {
            "$ref": "#/components/responses/Forbidden",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "404": {
            "$ref": "#/components/responses/NotFound",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "409": {
            "$ref": "#/components/responses/Conflict",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "429": {
            "$ref": "#/components/responses/TooManyRequests",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "500": {
            "$ref": "#/components/responses/InternalServerError",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          }
        },
        "x-codeSamples": [
          {
            "lang": "cURL",
            "label": "cURL",
            "source": "curl -X POST \"https://api.kangopenbanking.com/v1/gateway/withdraw-to-paypal\" \\\n  -H \"Authorization: Bearer $KOB_ACCESS_TOKEN\" \\\n  -H \"Content-Type: application/json\" \\\n  -d '{}'"
          },
          {
            "lang": "JavaScript",
            "label": "Node.js",
            "source": "import { KangOpenBanking } from \"@kangopenbanking/sdk\";\n\nconst kob = new KangOpenBanking({ apiKey: process.env.KOB_API_KEY });\nconst res = await kob.request(\"POST\", \"/v1/gateway/withdraw-to-paypal\", { /* payload */ });\nconsole.log(res);"
          },
          {
            "lang": "Python",
            "label": "Python",
            "source": "from kangopenbanking import KangOpenBanking\n\nkob = KangOpenBanking(api_key=os.environ[\"KOB_API_KEY\"])\nres = kob.request(\"POST\", \"/v1/gateway/withdraw-to-paypal\", json={})\nprint(res)"
          },
          {
            "lang": "PHP",
            "label": "PHP",
            "source": "<?php\n$kob = new KangOpenBanking\\KangOpenBanking(getenv('KOB_API_KEY'));\n$res = $kob->request('POST', '/v1/gateway/withdraw-to-paypal', []);\nprint_r($res);"
          }
        ]
      }
    },
    "/v1/gateway/disputes": {
      "get": {
        "tags": [
          "Payment Gateway"
        ],
        "summary": "List disputes",
        "operationId": "gatewayListDisputes",
        "security": [
          {
            "bearerAuth": []
          }
        ],
        "parameters": [
          {
            "name": "limit",
            "in": "query",
            "schema": {
              "type": "integer",
              "default": 25,
              "maximum": 100
            },
            "description": "Items per page"
          },
          {
            "name": "offset",
            "in": "query",
            "schema": {
              "type": "integer",
              "default": 0
            },
            "description": "Items to skip"
          },
          {
            "name": "sort_by",
            "in": "query",
            "schema": {
              "type": "string",
              "default": "created_at"
            },
            "description": "Sort field"
          },
          {
            "name": "sort_order",
            "in": "query",
            "schema": {
              "type": "string",
              "enum": [
                "asc",
                "desc"
              ],
              "default": "desc"
            },
            "description": "Sort direction"
          },
          {
            "$ref": "#/components/parameters/StartingAfter"
          },
          {
            "$ref": "#/components/parameters/EndingBefore"
          },
          {
            "$ref": "#/components/parameters/RequestId"
          },
          {
            "$ref": "#/components/parameters/Traceparent"
          },
          {
            "$ref": "#/components/parameters/Tracestate"
          },
          {
            "$ref": "#/components/parameters/AcceptLanguage"
          }
        ],
        "responses": {
          "200": {
            "description": "Disputes list",
            "content": {
              "application/json": {
                "schema": {
                  "allOf": [
                    {
                      "$ref": "#/components/schemas/PaginatedResponse"
                    },
                    {
                      "type": "object",
                      "properties": {
                        "data": {
                          "type": "array",
                          "items": {
                            "$ref": "#/components/schemas/GatewayDispute"
                          }
                        }
                      }
                    }
                  ]
                },
                "example": {
                  "data": [
                    {
                      "id": "f1d6f4a0-1d4e-4a3a-9e0a-1a2b3c4d5e6f",
                      "charge_id": "f1d6f4a0-1d4e-4a3a-9e0a-1a2b3c4d5e6f",
                      "amount": "5000",
                      "currency": "XAF",
                      "status": "open",
                      "reason": "XAF",
                      "evidence_due_by": "2026-01-31T12:00:00Z",
                      "provider": "XAF",
                      "created_at": "2026-01-31T12:00:00Z"
                    }
                  ],
                  "pagination": {
                    "page": 1,
                    "limit": 20,
                    "total": 150,
                    "has_next": true,
                    "next_cursor": "eyJpZCI6IjEyMyJ9"
                  },
                  "meta": {
                    "request_id": "550e8400-e29b-41d4-a716-446655440000",
                    "timestamp": "2025-03-27T12:00:00Z",
                    "api_version": "4.3.0"
                  }
                }
              }
            },
            "headers": {
              "x-fapi-interaction-id": {
                "$ref": "#/components/headers/XFapiInteractionIdResponse"
              },
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/XRateLimitLimit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/XRateLimitRemaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/XRateLimitReset"
              },
              "Cache-Control": {
                "$ref": "#/components/headers/CacheControl"
              },
              "ETag": {
                "$ref": "#/components/headers/ETag"
              },
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              },
              "traceparent": {
                "$ref": "#/components/headers/Traceparent"
              },
              "Content-Language": {
                "$ref": "#/components/headers/Content-Language"
              }
            }
          },
          "400": {
            "description": "Bad request",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              },
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                },
                "examples": {
                  "error": {
                    "$ref": "#/components/examples/ErrorBadRequest"
                  }
                }
              }
            },
            "headers": {
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/XRateLimitLimit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/XRateLimitRemaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/XRateLimitReset"
              },
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "403": {
            "$ref": "#/components/responses/Forbidden",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "404": {
            "$ref": "#/components/responses/NotFound",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "409": {
            "$ref": "#/components/responses/Conflict",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "429": {
            "$ref": "#/components/responses/TooManyRequests",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "500": {
            "$ref": "#/components/responses/InternalServerError",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          }
        },
        "x-codeSamples": [
          {
            "lang": "cURL",
            "label": "cURL",
            "source": "curl -X GET \"https://api.kangopenbanking.com/v1/gateway/disputes\" \\\n  -H \"Authorization: Bearer $KOB_ACCESS_TOKEN\" \\\n  -H \"Content-Type: application/json\""
          },
          {
            "lang": "JavaScript",
            "label": "Node.js",
            "source": "import { KangOpenBanking } from \"@kangopenbanking/sdk\";\n\nconst kob = new KangOpenBanking({ apiKey: process.env.KOB_API_KEY });\nconst res = await kob.request(\"GET\", \"/v1/gateway/disputes\");\nconsole.log(res);"
          },
          {
            "lang": "Python",
            "label": "Python",
            "source": "from kangopenbanking import KangOpenBanking\n\nkob = KangOpenBanking(api_key=os.environ[\"KOB_API_KEY\"])\nres = kob.request(\"GET\", \"/v1/gateway/disputes\")\nprint(res)"
          },
          {
            "lang": "PHP",
            "label": "PHP",
            "source": "<?php\n$kob = new KangOpenBanking\\KangOpenBanking(getenv('KOB_API_KEY'));\n$res = $kob->request('GET', '/v1/gateway/disputes');\nprint_r($res);"
          }
        ]
      }
    },
    "/v1/gateway/disputes/{disputeId}": {
      "get": {
        "tags": [
          "Payment Gateway"
        ],
        "summary": "Get dispute",
        "operationId": "gatewayGetDispute",
        "security": [
          {
            "bearerAuth": []
          }
        ],
        "parameters": [
          {
            "name": "disputeId",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "$ref": "#/components/parameters/RequestId"
          },
          {
            "$ref": "#/components/parameters/Traceparent"
          },
          {
            "$ref": "#/components/parameters/Tracestate"
          },
          {
            "$ref": "#/components/parameters/AcceptLanguage"
          }
        ],
        "responses": {
          "200": {
            "description": "Dispute details",
            "content": {
              "application/json": {
                "schema": {
                  "allOf": [
                    {
                      "$ref": "#/components/schemas/StandardResponse"
                    },
                    {
                      "type": "object",
                      "properties": {
                        "data": {
                          "$ref": "#/components/schemas/GatewayDispute"
                        }
                      }
                    }
                  ]
                },
                "example": {
                  "data": {
                    "id": "00000000-0000-4000-8000-000000000000",
                    "charge_id": "00000000-0000-4000-8000-000000000000",
                    "amount": "5000",
                    "currency": "XAF",
                    "status": "open",
                    "reason": "string",
                    "evidence_due_by": "2026-01-01T00:00:00Z",
                    "provider": "string",
                    "created_at": "2026-01-01T00:00:00Z"
                  },
                  "meta": {
                    "request_id": "550e8400-e29b-41d4-a716-446655440000",
                    "timestamp": "2025-03-27T12:00:00Z",
                    "api_version": "4.3.0"
                  }
                }
              }
            },
            "headers": {
              "x-fapi-interaction-id": {
                "$ref": "#/components/headers/XFapiInteractionIdResponse"
              },
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/XRateLimitLimit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/XRateLimitRemaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/XRateLimitReset"
              },
              "Cache-Control": {
                "$ref": "#/components/headers/CacheControl"
              },
              "ETag": {
                "$ref": "#/components/headers/ETag"
              },
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              },
              "traceparent": {
                "$ref": "#/components/headers/Traceparent"
              },
              "Content-Language": {
                "$ref": "#/components/headers/Content-Language"
              }
            }
          },
          "400": {
            "description": "Bad request",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              },
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                },
                "examples": {
                  "error": {
                    "$ref": "#/components/examples/ErrorBadRequest"
                  }
                }
              }
            },
            "headers": {
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/XRateLimitLimit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/XRateLimitRemaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/XRateLimitReset"
              },
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "403": {
            "$ref": "#/components/responses/Forbidden",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "404": {
            "$ref": "#/components/responses/NotFound",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "409": {
            "$ref": "#/components/responses/Conflict",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "429": {
            "$ref": "#/components/responses/TooManyRequests",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "500": {
            "$ref": "#/components/responses/InternalServerError",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          }
        },
        "x-codeSamples": [
          {
            "lang": "cURL",
            "label": "cURL",
            "source": "curl -X GET \"https://api.kangopenbanking.com/v1/gateway/disputes/{disputeId}\" \\\n  -H \"Authorization: Bearer $KOB_ACCESS_TOKEN\" \\\n  -H \"Content-Type: application/json\""
          },
          {
            "lang": "JavaScript",
            "label": "Node.js",
            "source": "import { KangOpenBanking } from \"@kangopenbanking/sdk\";\n\nconst kob = new KangOpenBanking({ apiKey: process.env.KOB_API_KEY });\nconst res = await kob.request(\"GET\", \"/v1/gateway/disputes/{disputeId}\");\nconsole.log(res);"
          },
          {
            "lang": "Python",
            "label": "Python",
            "source": "from kangopenbanking import KangOpenBanking\n\nkob = KangOpenBanking(api_key=os.environ[\"KOB_API_KEY\"])\nres = kob.request(\"GET\", \"/v1/gateway/disputes/{disputeId}\")\nprint(res)"
          },
          {
            "lang": "PHP",
            "label": "PHP",
            "source": "<?php\n$kob = new KangOpenBanking\\KangOpenBanking(getenv('KOB_API_KEY'));\n$res = $kob->request('GET', '/v1/gateway/disputes/{disputeId}');\nprint_r($res);"
          }
        ]
      }
    },
    "/v1/gateway/disputes/{disputeId}/evidence": {
      "post": {
        "tags": [
          "Payment Gateway"
        ],
        "summary": "Submit dispute evidence",
        "operationId": "gatewaySubmitDisputeEvidence",
        "security": [
          {
            "bearerAuth": []
          }
        ],
        "parameters": [
          {
            "name": "disputeId",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "Idempotency-Key",
            "in": "header",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid"
            },
            "description": "Required on all POST/PUT endpoints. Unique key for idempotent request processing (UUID v4 recommended). Keys expire after 24 hours."
          },
          {
            "$ref": "#/components/parameters/RequestId"
          },
          {
            "$ref": "#/components/parameters/Traceparent"
          },
          {
            "$ref": "#/components/parameters/Tracestate"
          },
          {
            "$ref": "#/components/parameters/AcceptLanguage"
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "required": [
                  "evidence_text"
                ],
                "properties": {
                  "evidence_text": {
                    "type": "string"
                  },
                  "evidence_type": {
                    "type": "string"
                  },
                  "file_url": {
                    "type": "string"
                  }
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Evidence submitted",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "success": {
                      "type": "boolean",
                      "example": true
                    },
                    "message": {
                      "type": "string"
                    }
                  }
                },
                "example": {
                  "success": true,
                  "message": "string"
                }
              }
            },
            "headers": {
              "x-fapi-interaction-id": {
                "$ref": "#/components/headers/XFapiInteractionIdResponse"
              },
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/XRateLimitLimit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/XRateLimitRemaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/XRateLimitReset"
              },
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              },
              "X-Idempotent-Replay": {
                "$ref": "#/components/headers/X-Idempotent-Replay"
              },
              "X-Idempotency-Status": {
                "$ref": "#/components/headers/X-Idempotency-Status"
              },
              "traceparent": {
                "$ref": "#/components/headers/Traceparent"
              },
              "Content-Language": {
                "$ref": "#/components/headers/Content-Language"
              }
            }
          },
          "400": {
            "description": "Bad request",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              },
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                },
                "examples": {
                  "error": {
                    "$ref": "#/components/examples/ErrorBadRequest"
                  }
                }
              }
            },
            "headers": {
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/XRateLimitLimit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/XRateLimitRemaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/XRateLimitReset"
              },
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "403": {
            "$ref": "#/components/responses/Forbidden",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "404": {
            "$ref": "#/components/responses/NotFound",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "409": {
            "$ref": "#/components/responses/Conflict",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "429": {
            "$ref": "#/components/responses/TooManyRequests",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "500": {
            "$ref": "#/components/responses/InternalServerError",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          }
        },
        "x-codeSamples": [
          {
            "lang": "cURL",
            "label": "cURL",
            "source": "curl -X POST \"https://api.kangopenbanking.com/v1/gateway/disputes/{disputeId}/evidence\" \\\n  -H \"Authorization: Bearer $KOB_ACCESS_TOKEN\" \\\n  -H \"Content-Type: application/json\" \\\n  -d '{}'"
          },
          {
            "lang": "JavaScript",
            "label": "Node.js",
            "source": "import { KangOpenBanking } from \"@kangopenbanking/sdk\";\n\nconst kob = new KangOpenBanking({ apiKey: process.env.KOB_API_KEY });\nconst res = await kob.request(\"POST\", \"/v1/gateway/disputes/{disputeId}/evidence\", { /* payload */ });\nconsole.log(res);"
          },
          {
            "lang": "Python",
            "label": "Python",
            "source": "from kangopenbanking import KangOpenBanking\n\nkob = KangOpenBanking(api_key=os.environ[\"KOB_API_KEY\"])\nres = kob.request(\"POST\", \"/v1/gateway/disputes/{disputeId}/evidence\", json={})\nprint(res)"
          },
          {
            "lang": "PHP",
            "label": "PHP",
            "source": "<?php\n$kob = new KangOpenBanking\\KangOpenBanking(getenv('KOB_API_KEY'));\n$res = $kob->request('POST', '/v1/gateway/disputes/{disputeId}/evidence', []);\nprint_r($res);"
          }
        ]
      }
    },
    "/v1/gateway/settlements": {
      "get": {
        "tags": [
          "Payment Gateway"
        ],
        "summary": "List settlements",
        "operationId": "gatewayListSettlements",
        "security": [
          {
            "bearerAuth": []
          }
        ],
        "parameters": [
          {
            "name": "merchant_id",
            "in": "query",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "limit",
            "in": "query",
            "schema": {
              "type": "integer",
              "default": 25,
              "maximum": 100
            },
            "description": "Items per page"
          },
          {
            "name": "offset",
            "in": "query",
            "schema": {
              "type": "integer",
              "default": 0
            },
            "description": "Items to skip"
          },
          {
            "name": "sort_by",
            "in": "query",
            "schema": {
              "type": "string",
              "default": "created_at"
            },
            "description": "Sort field"
          },
          {
            "name": "sort_order",
            "in": "query",
            "schema": {
              "type": "string",
              "enum": [
                "asc",
                "desc"
              ],
              "default": "desc"
            },
            "description": "Sort direction"
          },
          {
            "$ref": "#/components/parameters/StartingAfter"
          },
          {
            "$ref": "#/components/parameters/EndingBefore"
          },
          {
            "$ref": "#/components/parameters/RequestId"
          },
          {
            "$ref": "#/components/parameters/Traceparent"
          },
          {
            "$ref": "#/components/parameters/Tracestate"
          },
          {
            "$ref": "#/components/parameters/AcceptLanguage"
          }
        ],
        "responses": {
          "200": {
            "description": "Settlements list",
            "content": {
              "application/json": {
                "schema": {
                  "allOf": [
                    {
                      "$ref": "#/components/schemas/PaginatedResponse"
                    },
                    {
                      "type": "object",
                      "properties": {
                        "data": {
                          "type": "array",
                          "items": {
                            "$ref": "#/components/schemas/GatewaySettlement"
                          }
                        }
                      }
                    }
                  ]
                },
                "example": {
                  "data": [
                    {
                      "id": "f1d6f4a0-1d4e-4a3a-9e0a-1a2b3c4d5e6f",
                      "merchant_id": "f1d6f4a0-1d4e-4a3a-9e0a-1a2b3c4d5e6f",
                      "amount": "450000",
                      "currency": "XAF",
                      "status": "pending",
                      "period_start": "2026-01-31",
                      "period_end": "2026-01-31",
                      "charges_count": 1,
                      "fees_total": 1,
                      "net_amount": "0",
                      "settled_at": "2026-01-31T12:00:00Z"
                    }
                  ],
                  "pagination": {
                    "page": 1,
                    "limit": 20,
                    "total": 150,
                    "has_next": true,
                    "next_cursor": "eyJpZCI6IjEyMyJ9"
                  },
                  "meta": {
                    "request_id": "550e8400-e29b-41d4-a716-446655440000",
                    "timestamp": "2025-03-27T12:00:00Z",
                    "api_version": "4.3.0"
                  }
                }
              }
            },
            "headers": {
              "x-fapi-interaction-id": {
                "$ref": "#/components/headers/XFapiInteractionIdResponse"
              },
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/XRateLimitLimit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/XRateLimitRemaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/XRateLimitReset"
              },
              "Cache-Control": {
                "$ref": "#/components/headers/CacheControl"
              },
              "ETag": {
                "$ref": "#/components/headers/ETag"
              },
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              },
              "traceparent": {
                "$ref": "#/components/headers/Traceparent"
              },
              "Content-Language": {
                "$ref": "#/components/headers/Content-Language"
              }
            }
          },
          "400": {
            "description": "Bad request",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              },
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                },
                "examples": {
                  "error": {
                    "$ref": "#/components/examples/ErrorBadRequest"
                  }
                }
              }
            },
            "headers": {
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/XRateLimitLimit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/XRateLimitRemaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/XRateLimitReset"
              },
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "403": {
            "$ref": "#/components/responses/Forbidden",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "404": {
            "$ref": "#/components/responses/NotFound",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "409": {
            "$ref": "#/components/responses/Conflict",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "429": {
            "$ref": "#/components/responses/TooManyRequests",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "500": {
            "$ref": "#/components/responses/InternalServerError",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          }
        },
        "x-codeSamples": [
          {
            "lang": "cURL",
            "label": "cURL",
            "source": "curl -X GET \"https://api.kangopenbanking.com/v1/gateway/settlements\" \\\n  -H \"Authorization: Bearer $KOB_ACCESS_TOKEN\" \\\n  -H \"Content-Type: application/json\""
          },
          {
            "lang": "JavaScript",
            "label": "Node.js",
            "source": "import { KangOpenBanking } from \"@kangopenbanking/sdk\";\n\nconst kob = new KangOpenBanking({ apiKey: process.env.KOB_API_KEY });\nconst res = await kob.request(\"GET\", \"/v1/gateway/settlements\");\nconsole.log(res);"
          },
          {
            "lang": "Python",
            "label": "Python",
            "source": "from kangopenbanking import KangOpenBanking\n\nkob = KangOpenBanking(api_key=os.environ[\"KOB_API_KEY\"])\nres = kob.request(\"GET\", \"/v1/gateway/settlements\")\nprint(res)"
          },
          {
            "lang": "PHP",
            "label": "PHP",
            "source": "<?php\n$kob = new KangOpenBanking\\KangOpenBanking(getenv('KOB_API_KEY'));\n$res = $kob->request('GET', '/v1/gateway/settlements');\nprint_r($res);"
          }
        ]
      }
    },
    "/v1/gateway/settlements/{settlementId}": {
      "get": {
        "tags": [
          "Payment Gateway"
        ],
        "summary": "Get settlement",
        "operationId": "gatewayGetSettlement",
        "security": [
          {
            "bearerAuth": []
          }
        ],
        "parameters": [
          {
            "name": "settlementId",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "$ref": "#/components/parameters/RequestId"
          },
          {
            "$ref": "#/components/parameters/Traceparent"
          },
          {
            "$ref": "#/components/parameters/Tracestate"
          },
          {
            "$ref": "#/components/parameters/AcceptLanguage"
          }
        ],
        "responses": {
          "200": {
            "description": "Settlement details",
            "content": {
              "application/json": {
                "schema": {
                  "allOf": [
                    {
                      "$ref": "#/components/schemas/StandardResponse"
                    },
                    {
                      "type": "object",
                      "properties": {
                        "data": {
                          "$ref": "#/components/schemas/GatewaySettlement"
                        }
                      }
                    }
                  ]
                },
                "example": {
                  "data": {
                    "id": "00000000-0000-4000-8000-000000000000",
                    "merchant_id": "00000000-0000-4000-8000-000000000000",
                    "amount": "450000",
                    "currency": "XAF",
                    "status": "pending",
                    "period_start": "2026-01-01",
                    "period_end": "2026-01-01",
                    "charges_count": 0,
                    "fees_total": 0,
                    "net_amount": "0",
                    "settled_at": "2026-01-01T00:00:00Z"
                  },
                  "meta": {
                    "request_id": "550e8400-e29b-41d4-a716-446655440000",
                    "timestamp": "2025-03-27T12:00:00Z",
                    "api_version": "4.3.0"
                  }
                }
              }
            },
            "headers": {
              "x-fapi-interaction-id": {
                "$ref": "#/components/headers/XFapiInteractionIdResponse"
              },
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/XRateLimitLimit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/XRateLimitRemaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/XRateLimitReset"
              },
              "Cache-Control": {
                "$ref": "#/components/headers/CacheControl"
              },
              "ETag": {
                "$ref": "#/components/headers/ETag"
              },
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              },
              "traceparent": {
                "$ref": "#/components/headers/Traceparent"
              },
              "Content-Language": {
                "$ref": "#/components/headers/Content-Language"
              }
            }
          },
          "400": {
            "description": "Bad request",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              },
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                },
                "examples": {
                  "error": {
                    "$ref": "#/components/examples/ErrorBadRequest"
                  }
                }
              }
            },
            "headers": {
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/XRateLimitLimit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/XRateLimitRemaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/XRateLimitReset"
              },
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "403": {
            "$ref": "#/components/responses/Forbidden",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "404": {
            "$ref": "#/components/responses/NotFound",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "409": {
            "$ref": "#/components/responses/Conflict",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "429": {
            "$ref": "#/components/responses/TooManyRequests",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "500": {
            "$ref": "#/components/responses/InternalServerError",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          }
        },
        "x-codeSamples": [
          {
            "lang": "cURL",
            "label": "cURL",
            "source": "curl -X GET \"https://api.kangopenbanking.com/v1/gateway/settlements/{settlementId}\" \\\n  -H \"Authorization: Bearer $KOB_ACCESS_TOKEN\" \\\n  -H \"Content-Type: application/json\""
          },
          {
            "lang": "JavaScript",
            "label": "Node.js",
            "source": "import { KangOpenBanking } from \"@kangopenbanking/sdk\";\n\nconst kob = new KangOpenBanking({ apiKey: process.env.KOB_API_KEY });\nconst res = await kob.request(\"GET\", \"/v1/gateway/settlements/{settlementId}\");\nconsole.log(res);"
          },
          {
            "lang": "Python",
            "label": "Python",
            "source": "from kangopenbanking import KangOpenBanking\n\nkob = KangOpenBanking(api_key=os.environ[\"KOB_API_KEY\"])\nres = kob.request(\"GET\", \"/v1/gateway/settlements/{settlementId}\")\nprint(res)"
          },
          {
            "lang": "PHP",
            "label": "PHP",
            "source": "<?php\n$kob = new KangOpenBanking\\KangOpenBanking(getenv('KOB_API_KEY'));\n$res = $kob->request('GET', '/v1/gateway/settlements/{settlementId}');\nprint_r($res);"
          }
        ]
      }
    },
    "/v1/gateway/beneficiaries": {
      "post": {
        "tags": [
          "Payment Gateway"
        ],
        "summary": "Create beneficiary",
        "operationId": "gatewayCreateBeneficiary",
        "security": [
          {
            "bearerAuth": []
          }
        ],
        "parameters": [
          {
            "name": "Idempotency-Key",
            "in": "header",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid"
            },
            "description": "Required on all POST/PUT endpoints. Unique key for idempotent request processing (UUID v4 recommended). Keys expire after 24 hours."
          },
          {
            "$ref": "#/components/parameters/RequestId"
          },
          {
            "$ref": "#/components/parameters/Traceparent"
          },
          {
            "$ref": "#/components/parameters/Tracestate"
          },
          {
            "$ref": "#/components/parameters/AcceptLanguage"
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "required": [
                  "merchant_id",
                  "name",
                  "channel"
                ],
                "properties": {
                  "merchant_id": {
                    "type": "string"
                  },
                  "name": {
                    "type": "string"
                  },
                  "channel": {
                    "type": "string"
                  },
                  "phone": {
                    "type": "string"
                  },
                  "bank_account": {
                    "type": "string"
                  },
                  "bank_code": {
                    "type": "string"
                  }
                }
              }
            }
          }
        },
        "responses": {
          "201": {
            "description": "Beneficiary created",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/GatewayBeneficiary"
                },
                "example": {
                  "id": "00000000-0000-4000-8000-000000000000",
                  "merchant_id": "00000000-0000-4000-8000-000000000000",
                  "name": "string",
                  "channel": "mobile_money",
                  "phone": "string",
                  "bank_account": "string",
                  "bank_code": "string",
                  "created_at": "2026-01-01T00:00:00Z"
                }
              }
            },
            "headers": {
              "x-fapi-interaction-id": {
                "$ref": "#/components/headers/XFapiInteractionIdResponse"
              },
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/XRateLimitLimit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/XRateLimitRemaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/XRateLimitReset"
              },
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              },
              "X-Idempotent-Replay": {
                "$ref": "#/components/headers/X-Idempotent-Replay"
              },
              "X-Idempotency-Status": {
                "$ref": "#/components/headers/X-Idempotency-Status"
              },
              "traceparent": {
                "$ref": "#/components/headers/Traceparent"
              },
              "Content-Language": {
                "$ref": "#/components/headers/Content-Language"
              }
            }
          },
          "400": {
            "description": "Bad request",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              },
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                },
                "examples": {
                  "error": {
                    "$ref": "#/components/examples/ErrorBadRequest"
                  }
                }
              }
            },
            "headers": {
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/XRateLimitLimit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/XRateLimitRemaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/XRateLimitReset"
              },
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "403": {
            "$ref": "#/components/responses/Forbidden",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "404": {
            "$ref": "#/components/responses/NotFound",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "409": {
            "$ref": "#/components/responses/Conflict",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "429": {
            "$ref": "#/components/responses/TooManyRequests",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "500": {
            "$ref": "#/components/responses/InternalServerError",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          }
        },
        "x-codeSamples": [
          {
            "lang": "cURL",
            "label": "cURL",
            "source": "curl -X POST \"https://api.kangopenbanking.com/v1/gateway/beneficiaries\" \\\n  -H \"Authorization: Bearer $KOB_ACCESS_TOKEN\" \\\n  -H \"Content-Type: application/json\" \\\n  -d '{}'"
          },
          {
            "lang": "JavaScript",
            "label": "Node.js",
            "source": "import { KangOpenBanking } from \"@kangopenbanking/sdk\";\n\nconst kob = new KangOpenBanking({ apiKey: process.env.KOB_API_KEY });\nconst res = await kob.request(\"POST\", \"/v1/gateway/beneficiaries\", { /* payload */ });\nconsole.log(res);"
          },
          {
            "lang": "Python",
            "label": "Python",
            "source": "from kangopenbanking import KangOpenBanking\n\nkob = KangOpenBanking(api_key=os.environ[\"KOB_API_KEY\"])\nres = kob.request(\"POST\", \"/v1/gateway/beneficiaries\", json={})\nprint(res)"
          },
          {
            "lang": "PHP",
            "label": "PHP",
            "source": "<?php\n$kob = new KangOpenBanking\\KangOpenBanking(getenv('KOB_API_KEY'));\n$res = $kob->request('POST', '/v1/gateway/beneficiaries', []);\nprint_r($res);"
          }
        ]
      },
      "get": {
        "tags": [
          "Payment Gateway"
        ],
        "summary": "List beneficiaries",
        "operationId": "gatewayListBeneficiaries",
        "security": [
          {
            "bearerAuth": []
          }
        ],
        "parameters": [
          {
            "name": "merchant_id",
            "in": "query",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "limit",
            "in": "query",
            "schema": {
              "type": "integer",
              "default": 25,
              "maximum": 100
            },
            "description": "Items per page"
          },
          {
            "name": "offset",
            "in": "query",
            "schema": {
              "type": "integer",
              "default": 0
            },
            "description": "Items to skip"
          },
          {
            "name": "sort_by",
            "in": "query",
            "schema": {
              "type": "string",
              "default": "created_at"
            },
            "description": "Sort field"
          },
          {
            "name": "sort_order",
            "in": "query",
            "schema": {
              "type": "string",
              "enum": [
                "asc",
                "desc"
              ],
              "default": "desc"
            },
            "description": "Sort direction"
          },
          {
            "$ref": "#/components/parameters/StartingAfter"
          },
          {
            "$ref": "#/components/parameters/EndingBefore"
          },
          {
            "$ref": "#/components/parameters/RequestId"
          },
          {
            "$ref": "#/components/parameters/Traceparent"
          },
          {
            "$ref": "#/components/parameters/Tracestate"
          },
          {
            "$ref": "#/components/parameters/AcceptLanguage"
          }
        ],
        "responses": {
          "200": {
            "description": "Beneficiaries list",
            "content": {
              "application/json": {
                "schema": {
                  "allOf": [
                    {
                      "$ref": "#/components/schemas/PaginatedResponse"
                    },
                    {
                      "type": "object",
                      "properties": {
                        "data": {
                          "type": "array",
                          "items": {
                            "$ref": "#/components/schemas/GatewayBeneficiary"
                          }
                        }
                      }
                    }
                  ]
                },
                "example": {
                  "data": [
                    {
                      "id": "f1d6f4a0-1d4e-4a3a-9e0a-1a2b3c4d5e6f",
                      "merchant_id": "f1d6f4a0-1d4e-4a3a-9e0a-1a2b3c4d5e6f",
                      "name": "XAF",
                      "channel": "mobile_money",
                      "phone": "XAF",
                      "bank_account": "XAF",
                      "bank_code": "XAF",
                      "created_at": "2026-01-31T12:00:00Z"
                    }
                  ],
                  "pagination": {
                    "page": 1,
                    "limit": 20,
                    "total": 150,
                    "has_next": true,
                    "next_cursor": "eyJpZCI6IjEyMyJ9"
                  },
                  "meta": {
                    "request_id": "550e8400-e29b-41d4-a716-446655440000",
                    "timestamp": "2025-03-27T12:00:00Z",
                    "api_version": "4.3.0"
                  }
                }
              }
            },
            "headers": {
              "x-fapi-interaction-id": {
                "$ref": "#/components/headers/XFapiInteractionIdResponse"
              },
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/XRateLimitLimit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/XRateLimitRemaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/XRateLimitReset"
              },
              "Cache-Control": {
                "$ref": "#/components/headers/CacheControl"
              },
              "ETag": {
                "$ref": "#/components/headers/ETag"
              },
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              },
              "traceparent": {
                "$ref": "#/components/headers/Traceparent"
              },
              "Content-Language": {
                "$ref": "#/components/headers/Content-Language"
              }
            }
          },
          "400": {
            "description": "Bad request",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              },
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                },
                "examples": {
                  "error": {
                    "$ref": "#/components/examples/ErrorBadRequest"
                  }
                }
              }
            },
            "headers": {
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/XRateLimitLimit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/XRateLimitRemaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/XRateLimitReset"
              },
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "403": {
            "$ref": "#/components/responses/Forbidden",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "404": {
            "$ref": "#/components/responses/NotFound",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "409": {
            "$ref": "#/components/responses/Conflict",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "429": {
            "$ref": "#/components/responses/TooManyRequests",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "500": {
            "$ref": "#/components/responses/InternalServerError",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          }
        },
        "x-codeSamples": [
          {
            "lang": "cURL",
            "label": "cURL",
            "source": "curl -X GET \"https://api.kangopenbanking.com/v1/gateway/beneficiaries\" \\\n  -H \"Authorization: Bearer $KOB_ACCESS_TOKEN\" \\\n  -H \"Content-Type: application/json\""
          },
          {
            "lang": "JavaScript",
            "label": "Node.js",
            "source": "import { KangOpenBanking } from \"@kangopenbanking/sdk\";\n\nconst kob = new KangOpenBanking({ apiKey: process.env.KOB_API_KEY });\nconst res = await kob.request(\"GET\", \"/v1/gateway/beneficiaries\");\nconsole.log(res);"
          },
          {
            "lang": "Python",
            "label": "Python",
            "source": "from kangopenbanking import KangOpenBanking\n\nkob = KangOpenBanking(api_key=os.environ[\"KOB_API_KEY\"])\nres = kob.request(\"GET\", \"/v1/gateway/beneficiaries\")\nprint(res)"
          },
          {
            "lang": "PHP",
            "label": "PHP",
            "source": "<?php\n$kob = new KangOpenBanking\\KangOpenBanking(getenv('KOB_API_KEY'));\n$res = $kob->request('GET', '/v1/gateway/beneficiaries');\nprint_r($res);"
          }
        ]
      }
    },
    "/v1/gateway/beneficiaries/{beneficiaryId}": {
      "delete": {
        "tags": [
          "Payment Gateway"
        ],
        "summary": "Delete beneficiary",
        "operationId": "gatewayDeleteBeneficiary",
        "security": [
          {
            "bearerAuth": []
          }
        ],
        "parameters": [
          {
            "name": "beneficiaryId",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "$ref": "#/components/parameters/RequestId"
          },
          {
            "$ref": "#/components/parameters/Traceparent"
          },
          {
            "$ref": "#/components/parameters/Tracestate"
          },
          {
            "$ref": "#/components/parameters/AcceptLanguage"
          }
        ],
        "responses": {
          "204": {
            "description": "Beneficiary deleted",
            "headers": {
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/XRateLimitLimit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/XRateLimitRemaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/XRateLimitReset"
              },
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              },
              "traceparent": {
                "$ref": "#/components/headers/Traceparent"
              },
              "Content-Language": {
                "$ref": "#/components/headers/Content-Language"
              }
            }
          },
          "400": {
            "description": "Bad request",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              },
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                },
                "examples": {
                  "error": {
                    "$ref": "#/components/examples/ErrorBadRequest"
                  }
                }
              }
            },
            "headers": {
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/XRateLimitLimit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/XRateLimitRemaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/XRateLimitReset"
              },
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "403": {
            "$ref": "#/components/responses/Forbidden",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "404": {
            "$ref": "#/components/responses/NotFound",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "409": {
            "$ref": "#/components/responses/Conflict",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "429": {
            "$ref": "#/components/responses/TooManyRequests",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "500": {
            "$ref": "#/components/responses/InternalServerError",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          }
        },
        "x-codeSamples": [
          {
            "lang": "cURL",
            "label": "cURL",
            "source": "curl -X DELETE \"https://api.kangopenbanking.com/v1/gateway/beneficiaries/{beneficiaryId}\" \\\n  -H \"Authorization: Bearer $KOB_ACCESS_TOKEN\" \\\n  -H \"Content-Type: application/json\""
          },
          {
            "lang": "JavaScript",
            "label": "Node.js",
            "source": "import { KangOpenBanking } from \"@kangopenbanking/sdk\";\n\nconst kob = new KangOpenBanking({ apiKey: process.env.KOB_API_KEY });\nconst res = await kob.request(\"DELETE\", \"/v1/gateway/beneficiaries/{beneficiaryId}\");\nconsole.log(res);"
          },
          {
            "lang": "Python",
            "label": "Python",
            "source": "from kangopenbanking import KangOpenBanking\n\nkob = KangOpenBanking(api_key=os.environ[\"KOB_API_KEY\"])\nres = kob.request(\"DELETE\", \"/v1/gateway/beneficiaries/{beneficiaryId}\")\nprint(res)"
          },
          {
            "lang": "PHP",
            "label": "PHP",
            "source": "<?php\n$kob = new KangOpenBanking\\KangOpenBanking(getenv('KOB_API_KEY'));\n$res = $kob->request('DELETE', '/v1/gateway/beneficiaries/{beneficiaryId}');\nprint_r($res);"
          }
        ]
      }
    },
    "/v1/gateway/reports/transactions": {
      "get": {
        "tags": [
          "Payment Gateway"
        ],
        "summary": "Transaction report",
        "operationId": "gatewayReportTransactions",
        "security": [
          {
            "bearerAuth": []
          }
        ],
        "parameters": [
          {
            "name": "merchant_id",
            "in": "query",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "from",
            "in": "query",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "to",
            "in": "query",
            "schema": {
              "type": "string"
            }
          },
          {
            "$ref": "#/components/parameters/RequestId"
          },
          {
            "$ref": "#/components/parameters/Traceparent"
          },
          {
            "$ref": "#/components/parameters/Tracestate"
          },
          {
            "$ref": "#/components/parameters/AcceptLanguage"
          }
        ],
        "responses": {
          "200": {
            "description": "Transaction report with summary",
            "content": {
              "application/json": {
                "schema": {
                  "allOf": [
                    {
                      "$ref": "#/components/schemas/PaginatedResponse"
                    },
                    {
                      "type": "object",
                      "properties": {
                        "data": {
                          "type": "array",
                          "items": {
                            "$ref": "#/components/schemas/GatewayCharge"
                          }
                        }
                      }
                    }
                  ]
                },
                "example": {
                  "data": [
                    {
                      "id": "f1d6f4a0-1d4e-4a3a-9e0a-1a2b3c4d5e6f",
                      "merchant_id": "f1d6f4a0-1d4e-4a3a-9e0a-1a2b3c4d5e6f",
                      "amount": "5000",
                      "currency": "XAF",
                      "channel": "mobile_money",
                      "status": "pending",
                      "provider": "flutterwave",
                      "provider_ref": "XAF",
                      "fee_amount": "200",
                      "net_amount": "4800",
                      "tx_ref": "XAF",
                      "customer_phone": "XAF",
                      "customer_email": "XAF",
                      "capture_mode": "auto",
                      "captured_amount": 0,
                      "fee_bearer": "merchant",
                      "created_at": "2026-01-31T12:00:00Z",
                      "updated_at": "2026-01-31T12:00:00Z",
                      "description": "XAF",
                      "metadata": {},
                      "customer_id": "XAF",
                      "dispute_id": "f1d6f4a0-1d4e-4a3a-9e0a-1a2b3c4d5e6f",
                      "refunded_at": "2026-01-31T12:00:00Z",
                      "failure_reason": "XAF",
                      "failure_message": "XAF"
                    }
                  ],
                  "pagination": {
                    "page": 1,
                    "limit": 20,
                    "total": 150,
                    "has_next": true,
                    "next_cursor": "eyJpZCI6IjEyMyJ9"
                  },
                  "meta": {
                    "request_id": "550e8400-e29b-41d4-a716-446655440000",
                    "timestamp": "2025-03-27T12:00:00Z",
                    "api_version": "4.3.0"
                  }
                }
              }
            },
            "headers": {
              "x-fapi-interaction-id": {
                "$ref": "#/components/headers/XFapiInteractionIdResponse"
              },
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/XRateLimitLimit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/XRateLimitRemaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/XRateLimitReset"
              },
              "Cache-Control": {
                "$ref": "#/components/headers/CacheControl"
              },
              "ETag": {
                "$ref": "#/components/headers/ETag"
              },
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              },
              "traceparent": {
                "$ref": "#/components/headers/Traceparent"
              },
              "Content-Language": {
                "$ref": "#/components/headers/Content-Language"
              }
            }
          },
          "400": {
            "description": "Bad request",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              },
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                },
                "examples": {
                  "error": {
                    "$ref": "#/components/examples/ErrorBadRequest"
                  }
                }
              }
            },
            "headers": {
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/XRateLimitLimit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/XRateLimitRemaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/XRateLimitReset"
              },
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "403": {
            "$ref": "#/components/responses/Forbidden",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "404": {
            "$ref": "#/components/responses/NotFound",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "409": {
            "$ref": "#/components/responses/Conflict",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "429": {
            "$ref": "#/components/responses/TooManyRequests",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "500": {
            "$ref": "#/components/responses/InternalServerError",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          }
        },
        "x-codeSamples": [
          {
            "lang": "cURL",
            "label": "cURL",
            "source": "curl -X GET \"https://api.kangopenbanking.com/v1/gateway/reports/transactions\" \\\n  -H \"Authorization: Bearer $KOB_ACCESS_TOKEN\" \\\n  -H \"Content-Type: application/json\""
          },
          {
            "lang": "JavaScript",
            "label": "Node.js",
            "source": "import { KangOpenBanking } from \"@kangopenbanking/sdk\";\n\nconst kob = new KangOpenBanking({ apiKey: process.env.KOB_API_KEY });\nconst res = await kob.request(\"GET\", \"/v1/gateway/reports/transactions\");\nconsole.log(res);"
          },
          {
            "lang": "Python",
            "label": "Python",
            "source": "from kangopenbanking import KangOpenBanking\n\nkob = KangOpenBanking(api_key=os.environ[\"KOB_API_KEY\"])\nres = kob.request(\"GET\", \"/v1/gateway/reports/transactions\")\nprint(res)"
          },
          {
            "lang": "PHP",
            "label": "PHP",
            "source": "<?php\n$kob = new KangOpenBanking\\KangOpenBanking(getenv('KOB_API_KEY'));\n$res = $kob->request('GET', '/v1/gateway/reports/transactions');\nprint_r($res);"
          }
        ]
      }
    },
    "/v1/gateway/reports/settlements": {
      "get": {
        "tags": [
          "Payment Gateway"
        ],
        "summary": "Settlement report",
        "operationId": "gatewayReportSettlements",
        "security": [
          {
            "bearerAuth": []
          }
        ],
        "parameters": [
          {
            "name": "merchant_id",
            "in": "query",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "from",
            "in": "query",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "to",
            "in": "query",
            "schema": {
              "type": "string"
            }
          },
          {
            "$ref": "#/components/parameters/RequestId"
          },
          {
            "$ref": "#/components/parameters/Traceparent"
          },
          {
            "$ref": "#/components/parameters/Tracestate"
          },
          {
            "$ref": "#/components/parameters/AcceptLanguage"
          }
        ],
        "responses": {
          "200": {
            "description": "Settlement report with summary",
            "content": {
              "application/json": {
                "schema": {
                  "allOf": [
                    {
                      "$ref": "#/components/schemas/PaginatedResponse"
                    },
                    {
                      "type": "object",
                      "properties": {
                        "data": {
                          "type": "array",
                          "items": {
                            "$ref": "#/components/schemas/GatewaySettlement"
                          }
                        }
                      }
                    }
                  ]
                },
                "example": {
                  "data": [
                    {
                      "id": "f1d6f4a0-1d4e-4a3a-9e0a-1a2b3c4d5e6f",
                      "merchant_id": "f1d6f4a0-1d4e-4a3a-9e0a-1a2b3c4d5e6f",
                      "amount": "450000",
                      "currency": "XAF",
                      "status": "pending",
                      "period_start": "2026-01-31",
                      "period_end": "2026-01-31",
                      "charges_count": 1,
                      "fees_total": 1,
                      "net_amount": "0",
                      "settled_at": "2026-01-31T12:00:00Z"
                    }
                  ],
                  "pagination": {
                    "page": 1,
                    "limit": 20,
                    "total": 150,
                    "has_next": true,
                    "next_cursor": "eyJpZCI6IjEyMyJ9"
                  },
                  "meta": {
                    "request_id": "550e8400-e29b-41d4-a716-446655440000",
                    "timestamp": "2025-03-27T12:00:00Z",
                    "api_version": "4.3.0"
                  }
                }
              }
            },
            "headers": {
              "x-fapi-interaction-id": {
                "$ref": "#/components/headers/XFapiInteractionIdResponse"
              },
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/XRateLimitLimit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/XRateLimitRemaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/XRateLimitReset"
              },
              "Cache-Control": {
                "$ref": "#/components/headers/CacheControl"
              },
              "ETag": {
                "$ref": "#/components/headers/ETag"
              },
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              },
              "traceparent": {
                "$ref": "#/components/headers/Traceparent"
              },
              "Content-Language": {
                "$ref": "#/components/headers/Content-Language"
              }
            }
          },
          "400": {
            "description": "Bad request",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              },
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                },
                "examples": {
                  "error": {
                    "$ref": "#/components/examples/ErrorBadRequest"
                  }
                }
              }
            },
            "headers": {
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/XRateLimitLimit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/XRateLimitRemaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/XRateLimitReset"
              },
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "403": {
            "$ref": "#/components/responses/Forbidden",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "404": {
            "$ref": "#/components/responses/NotFound",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "409": {
            "$ref": "#/components/responses/Conflict",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "429": {
            "$ref": "#/components/responses/TooManyRequests",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "500": {
            "$ref": "#/components/responses/InternalServerError",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          }
        },
        "x-codeSamples": [
          {
            "lang": "cURL",
            "label": "cURL",
            "source": "curl -X GET \"https://api.kangopenbanking.com/v1/gateway/reports/settlements\" \\\n  -H \"Authorization: Bearer $KOB_ACCESS_TOKEN\" \\\n  -H \"Content-Type: application/json\""
          },
          {
            "lang": "JavaScript",
            "label": "Node.js",
            "source": "import { KangOpenBanking } from \"@kangopenbanking/sdk\";\n\nconst kob = new KangOpenBanking({ apiKey: process.env.KOB_API_KEY });\nconst res = await kob.request(\"GET\", \"/v1/gateway/reports/settlements\");\nconsole.log(res);"
          },
          {
            "lang": "Python",
            "label": "Python",
            "source": "from kangopenbanking import KangOpenBanking\n\nkob = KangOpenBanking(api_key=os.environ[\"KOB_API_KEY\"])\nres = kob.request(\"GET\", \"/v1/gateway/reports/settlements\")\nprint(res)"
          },
          {
            "lang": "PHP",
            "label": "PHP",
            "source": "<?php\n$kob = new KangOpenBanking\\KangOpenBanking(getenv('KOB_API_KEY'));\n$res = $kob->request('GET', '/v1/gateway/reports/settlements');\nprint_r($res);"
          }
        ]
      }
    },
    "/v1/gateway/export/transactions": {
      "get": {
        "tags": [
          "Payment Gateway"
        ],
        "summary": "Export transactions as CSV",
        "operationId": "gatewayExportTransactions",
        "security": [
          {
            "bearerAuth": []
          }
        ],
        "parameters": [
          {
            "name": "merchant_id",
            "in": "query",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "from",
            "in": "query",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "to",
            "in": "query",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "format",
            "in": "query",
            "schema": {
              "type": "string",
              "default": "csv"
            }
          },
          {
            "$ref": "#/components/parameters/RequestId"
          },
          {
            "$ref": "#/components/parameters/Traceparent"
          },
          {
            "$ref": "#/components/parameters/Tracestate"
          },
          {
            "$ref": "#/components/parameters/AcceptLanguage"
          }
        ],
        "responses": {
          "200": {
            "description": "CSV file download",
            "content": {
              "text/csv": {
                "schema": {
                  "type": "string"
                }
              },
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "download_url": {
                      "type": "string",
                      "format": "uri"
                    },
                    "expires_at": {
                      "type": "string",
                      "format": "date-time"
                    },
                    "row_count": {
                      "type": "integer"
                    }
                  }
                },
                "example": {
                  "download_url": "https://api.kangopenbanking.com",
                  "expires_at": "2026-01-01T00:00:00Z",
                  "row_count": 0
                }
              }
            },
            "headers": {
              "x-fapi-interaction-id": {
                "$ref": "#/components/headers/XFapiInteractionIdResponse"
              },
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/XRateLimitLimit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/XRateLimitRemaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/XRateLimitReset"
              },
              "Cache-Control": {
                "$ref": "#/components/headers/CacheControl"
              },
              "ETag": {
                "$ref": "#/components/headers/ETag"
              },
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              },
              "traceparent": {
                "$ref": "#/components/headers/Traceparent"
              },
              "Content-Language": {
                "$ref": "#/components/headers/Content-Language"
              }
            }
          },
          "400": {
            "description": "Bad request",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              },
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                },
                "examples": {
                  "error": {
                    "$ref": "#/components/examples/ErrorBadRequest"
                  }
                }
              }
            },
            "headers": {
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/XRateLimitLimit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/XRateLimitRemaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/XRateLimitReset"
              },
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "403": {
            "$ref": "#/components/responses/Forbidden",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "404": {
            "$ref": "#/components/responses/NotFound",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "409": {
            "$ref": "#/components/responses/Conflict",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "429": {
            "$ref": "#/components/responses/TooManyRequests",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "500": {
            "$ref": "#/components/responses/InternalServerError",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          }
        },
        "x-codeSamples": [
          {
            "lang": "cURL",
            "label": "cURL",
            "source": "curl -X GET \"https://api.kangopenbanking.com/v1/gateway/export/transactions\" \\\n  -H \"Authorization: Bearer $KOB_ACCESS_TOKEN\" \\\n  -H \"Content-Type: application/json\""
          },
          {
            "lang": "JavaScript",
            "label": "Node.js",
            "source": "import { KangOpenBanking } from \"@kangopenbanking/sdk\";\n\nconst kob = new KangOpenBanking({ apiKey: process.env.KOB_API_KEY });\nconst res = await kob.request(\"GET\", \"/v1/gateway/export/transactions\");\nconsole.log(res);"
          },
          {
            "lang": "Python",
            "label": "Python",
            "source": "from kangopenbanking import KangOpenBanking\n\nkob = KangOpenBanking(api_key=os.environ[\"KOB_API_KEY\"])\nres = kob.request(\"GET\", \"/v1/gateway/export/transactions\")\nprint(res)"
          },
          {
            "lang": "PHP",
            "label": "PHP",
            "source": "<?php\n$kob = new KangOpenBanking\\KangOpenBanking(getenv('KOB_API_KEY'));\n$res = $kob->request('GET', '/v1/gateway/export/transactions');\nprint_r($res);"
          }
        ]
      }
    },
    "/v1/gateway/charges/preauth": {
      "post": {
        "tags": [
          "Payment Gateway"
        ],
        "summary": "Create preauthorized charge",
        "description": "Hold funds on a card without immediately capturing. Uses Stripe PaymentIntent with capture_method=manual.",
        "operationId": "gatewayPreauthCharge",
        "security": [
          {
            "bearerAuth": []
          }
        ],
        "parameters": [
          {
            "name": "Idempotency-Key",
            "in": "header",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid"
            },
            "description": "Required on all POST/PUT endpoints. Unique key for idempotent request processing (UUID v4 recommended). Keys expire after 24 hours."
          },
          {
            "$ref": "#/components/parameters/RequestId"
          },
          {
            "$ref": "#/components/parameters/Traceparent"
          },
          {
            "$ref": "#/components/parameters/Tracestate"
          },
          {
            "$ref": "#/components/parameters/AcceptLanguage"
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "required": [
                  "merchant_id",
                  "amount",
                  "tx_ref"
                ],
                "properties": {
                  "merchant_id": {
                    "type": "string",
                    "format": "uuid"
                  },
                  "amount": {
                    "type": "string",
                    "example": "50000",
                    "pattern": "^[0-9]{1,15}$",
                    "description": "Represented as a string integer in the currency's minor unit (XAF has no subunits). Must be consistent with the currency field."
                  },
                  "currency": {
                    "type": "string",
                    "default": "USD",
                    "enum": [
                      "XAF",
                      "XOF",
                      "USD",
                      "EUR",
                      "GBP",
                      "CNY",
                      "NGN",
                      "GHS",
                      "KES",
                      "ZAR"
                    ],
                    "description": "ISO 4217 currency code. Default is XAF (Central African CFA Franc)."
                  },
                  "customer_email": {
                    "type": "string"
                  },
                  "customer_name": {
                    "type": "string"
                  },
                  "tx_ref": {
                    "type": "string"
                  },
                  "metadata": {
                    "type": "object"
                  }
                }
              }
            }
          }
        },
        "responses": {
          "201": {
            "description": "Preauthorized charge created",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/GatewayCharge"
                },
                "example": {
                  "id": "00000000-0000-4000-8000-000000000000",
                  "merchant_id": "00000000-0000-4000-8000-000000000000",
                  "amount": "5000",
                  "currency": "XAF",
                  "channel": "mobile_money",
                  "status": "pending",
                  "provider": "flutterwave",
                  "provider_ref": "string",
                  "fee_amount": "200",
                  "net_amount": "4800",
                  "tx_ref": "string",
                  "customer_phone": "string",
                  "customer_email": "string",
                  "capture_mode": "auto",
                  "captured_amount": 0,
                  "fee_bearer": "merchant",
                  "created_at": "2026-01-01T00:00:00Z",
                  "updated_at": "2026-01-01T00:00:00Z",
                  "description": "string",
                  "metadata": {},
                  "customer_id": "string",
                  "dispute_id": "00000000-0000-4000-8000-000000000000",
                  "refunded_at": "2026-01-01T00:00:00Z",
                  "failure_reason": "string",
                  "failure_message": "string"
                }
              }
            },
            "headers": {
              "x-fapi-interaction-id": {
                "$ref": "#/components/headers/XFapiInteractionIdResponse"
              },
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/XRateLimitLimit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/XRateLimitRemaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/XRateLimitReset"
              },
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              },
              "X-Idempotent-Replay": {
                "$ref": "#/components/headers/X-Idempotent-Replay"
              },
              "X-Idempotency-Status": {
                "$ref": "#/components/headers/X-Idempotency-Status"
              },
              "traceparent": {
                "$ref": "#/components/headers/Traceparent"
              },
              "Content-Language": {
                "$ref": "#/components/headers/Content-Language"
              }
            }
          },
          "400": {
            "description": "Bad request",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              },
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                },
                "examples": {
                  "error": {
                    "$ref": "#/components/examples/ErrorBadRequest"
                  }
                }
              }
            },
            "headers": {
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/XRateLimitLimit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/XRateLimitRemaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/XRateLimitReset"
              },
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "403": {
            "$ref": "#/components/responses/Forbidden",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "404": {
            "$ref": "#/components/responses/NotFound",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "409": {
            "$ref": "#/components/responses/Conflict",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "429": {
            "$ref": "#/components/responses/TooManyRequests",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "500": {
            "$ref": "#/components/responses/InternalServerError",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          }
        },
        "x-codeSamples": [
          {
            "lang": "cURL",
            "label": "cURL",
            "source": "curl -X POST \"https://api.kangopenbanking.com/v1/gateway/charges/preauth\" \\\n  -H \"Authorization: Bearer $KOB_ACCESS_TOKEN\" \\\n  -H \"Content-Type: application/json\" \\\n  -d '{}'"
          },
          {
            "lang": "JavaScript",
            "label": "Node.js",
            "source": "import { KangOpenBanking } from \"@kangopenbanking/sdk\";\n\nconst kob = new KangOpenBanking({ apiKey: process.env.KOB_API_KEY });\nconst res = await kob.request(\"POST\", \"/v1/gateway/charges/preauth\", { /* payload */ });\nconsole.log(res);"
          },
          {
            "lang": "Python",
            "label": "Python",
            "source": "from kangopenbanking import KangOpenBanking\n\nkob = KangOpenBanking(api_key=os.environ[\"KOB_API_KEY\"])\nres = kob.request(\"POST\", \"/v1/gateway/charges/preauth\", json={})\nprint(res)"
          },
          {
            "lang": "PHP",
            "label": "PHP",
            "source": "<?php\n$kob = new KangOpenBanking\\KangOpenBanking(getenv('KOB_API_KEY'));\n$res = $kob->request('POST', '/v1/gateway/charges/preauth', []);\nprint_r($res);"
          }
        ]
      }
    },
    "/v1/gateway/charges/{chargeId}/capture": {
      "post": {
        "tags": [
          "Payment Gateway"
        ],
        "summary": "Capture authorized charge",
        "description": "Capture a previously authorized charge (full or partial).",
        "operationId": "gatewayCaptureCharge",
        "security": [
          {
            "bearerAuth": []
          }
        ],
        "parameters": [
          {
            "name": "chargeId",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "Idempotency-Key",
            "in": "header",
            "required": false,
            "description": "Client-generated UUID for idempotent request deduplication. If the same key is submitted twice, the server returns the original response without re-processing.",
            "schema": {
              "type": "string",
              "format": "uuid",
              "example": "b4a2f391-9a41-4d8b-a123-3c6f0e8b9d12"
            }
          },
          {
            "$ref": "#/components/parameters/RequestId"
          },
          {
            "$ref": "#/components/parameters/Traceparent"
          },
          {
            "$ref": "#/components/parameters/Tracestate"
          },
          {
            "$ref": "#/components/parameters/AcceptLanguage"
          }
        ],
        "requestBody": {
          "required": false,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "amount": {
                    "type": "string",
                    "description": "Partial capture amount. Omit for full capture. Represented as a string integer in the currency's minor unit (XAF has no subunits).",
                    "pattern": "^[0-9]{1,15}$"
                  }
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Charge captured",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "id": {
                      "type": "string"
                    },
                    "status": {
                      "type": "string"
                    },
                    "captured_amount": {
                      "type": "number"
                    }
                  }
                },
                "example": {
                  "id": "string",
                  "status": "string",
                  "captured_amount": 0
                }
              }
            },
            "headers": {
              "x-fapi-interaction-id": {
                "$ref": "#/components/headers/XFapiInteractionIdResponse"
              },
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/XRateLimitLimit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/XRateLimitRemaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/XRateLimitReset"
              },
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              },
              "X-Idempotent-Replay": {
                "$ref": "#/components/headers/X-Idempotent-Replay"
              },
              "X-Idempotency-Status": {
                "$ref": "#/components/headers/X-Idempotency-Status"
              },
              "traceparent": {
                "$ref": "#/components/headers/Traceparent"
              },
              "Content-Language": {
                "$ref": "#/components/headers/Content-Language"
              }
            }
          },
          "400": {
            "description": "Bad request",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              },
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                },
                "examples": {
                  "error": {
                    "$ref": "#/components/examples/ErrorBadRequest"
                  }
                }
              }
            },
            "headers": {
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/XRateLimitLimit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/XRateLimitRemaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/XRateLimitReset"
              },
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "403": {
            "$ref": "#/components/responses/Forbidden",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "404": {
            "$ref": "#/components/responses/NotFound",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "409": {
            "$ref": "#/components/responses/Conflict",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "429": {
            "$ref": "#/components/responses/TooManyRequests",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "500": {
            "$ref": "#/components/responses/InternalServerError",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          }
        },
        "x-codeSamples": [
          {
            "lang": "cURL",
            "label": "cURL",
            "source": "curl -X POST \"https://api.kangopenbanking.com/v1/gateway/charges/{chargeId}/capture\" \\\n  -H \"Authorization: Bearer $KOB_ACCESS_TOKEN\" \\\n  -H \"Content-Type: application/json\" \\\n  -d '{}'"
          },
          {
            "lang": "JavaScript",
            "label": "Node.js",
            "source": "import { KangOpenBanking } from \"@kangopenbanking/sdk\";\n\nconst kob = new KangOpenBanking({ apiKey: process.env.KOB_API_KEY });\nconst res = await kob.request(\"POST\", \"/v1/gateway/charges/{chargeId}/capture\", { /* payload */ });\nconsole.log(res);"
          },
          {
            "lang": "Python",
            "label": "Python",
            "source": "from kangopenbanking import KangOpenBanking\n\nkob = KangOpenBanking(api_key=os.environ[\"KOB_API_KEY\"])\nres = kob.request(\"POST\", \"/v1/gateway/charges/{chargeId}/capture\", json={})\nprint(res)"
          },
          {
            "lang": "PHP",
            "label": "PHP",
            "source": "<?php\n$kob = new KangOpenBanking\\KangOpenBanking(getenv('KOB_API_KEY'));\n$res = $kob->request('POST', '/v1/gateway/charges/{chargeId}/capture', []);\nprint_r($res);"
          }
        ]
      }
    },
    "/v1/gateway/charges/{chargeId}/void": {
      "post": {
        "tags": [
          "Payment Gateway"
        ],
        "summary": "Void authorized charge",
        "description": "Release an authorized hold without capturing.",
        "operationId": "gatewayVoidCharge",
        "security": [
          {
            "bearerAuth": []
          }
        ],
        "parameters": [
          {
            "name": "chargeId",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "Idempotency-Key",
            "in": "header",
            "required": false,
            "description": "Client-generated UUID for idempotent request deduplication. If the same key is submitted twice, the server returns the original response without re-processing.",
            "schema": {
              "type": "string",
              "format": "uuid",
              "example": "b4a2f391-9a41-4d8b-a123-3c6f0e8b9d12"
            }
          },
          {
            "$ref": "#/components/parameters/RequestId"
          },
          {
            "$ref": "#/components/parameters/Traceparent"
          },
          {
            "$ref": "#/components/parameters/Tracestate"
          },
          {
            "$ref": "#/components/parameters/AcceptLanguage"
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "required": [
                  "charge_id"
                ],
                "properties": {
                  "charge_id": {
                    "type": "string"
                  }
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Charge voided",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "id": {
                      "type": "string"
                    },
                    "status": {
                      "type": "string",
                      "example": "voided"
                    }
                  }
                },
                "example": {
                  "id": "string",
                  "status": "voided"
                }
              }
            },
            "headers": {
              "x-fapi-interaction-id": {
                "$ref": "#/components/headers/XFapiInteractionIdResponse"
              },
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/XRateLimitLimit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/XRateLimitRemaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/XRateLimitReset"
              },
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              },
              "X-Idempotent-Replay": {
                "$ref": "#/components/headers/X-Idempotent-Replay"
              },
              "X-Idempotency-Status": {
                "$ref": "#/components/headers/X-Idempotency-Status"
              },
              "traceparent": {
                "$ref": "#/components/headers/Traceparent"
              },
              "Content-Language": {
                "$ref": "#/components/headers/Content-Language"
              }
            }
          },
          "400": {
            "description": "Bad request",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              },
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                },
                "examples": {
                  "error": {
                    "$ref": "#/components/examples/ErrorBadRequest"
                  }
                }
              }
            },
            "headers": {
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/XRateLimitLimit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/XRateLimitRemaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/XRateLimitReset"
              },
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "403": {
            "$ref": "#/components/responses/Forbidden",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "404": {
            "$ref": "#/components/responses/NotFound",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "409": {
            "$ref": "#/components/responses/Conflict",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "429": {
            "$ref": "#/components/responses/TooManyRequests",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "500": {
            "$ref": "#/components/responses/InternalServerError",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          }
        },
        "x-codeSamples": [
          {
            "lang": "cURL",
            "label": "cURL",
            "source": "curl -X POST \"https://api.kangopenbanking.com/v1/gateway/charges/{chargeId}/void\" \\\n  -H \"Authorization: Bearer $KOB_ACCESS_TOKEN\" \\\n  -H \"Content-Type: application/json\" \\\n  -d '{}'"
          },
          {
            "lang": "JavaScript",
            "label": "Node.js",
            "source": "import { KangOpenBanking } from \"@kangopenbanking/sdk\";\n\nconst kob = new KangOpenBanking({ apiKey: process.env.KOB_API_KEY });\nconst res = await kob.request(\"POST\", \"/v1/gateway/charges/{chargeId}/void\", { /* payload */ });\nconsole.log(res);"
          },
          {
            "lang": "Python",
            "label": "Python",
            "source": "from kangopenbanking import KangOpenBanking\n\nkob = KangOpenBanking(api_key=os.environ[\"KOB_API_KEY\"])\nres = kob.request(\"POST\", \"/v1/gateway/charges/{chargeId}/void\", json={})\nprint(res)"
          },
          {
            "lang": "PHP",
            "label": "PHP",
            "source": "<?php\n$kob = new KangOpenBanking\\KangOpenBanking(getenv('KOB_API_KEY'));\n$res = $kob->request('POST', '/v1/gateway/charges/{chargeId}/void', []);\nprint_r($res);"
          }
        ]
      }
    },
    "/v1/gateway/charges/validate": {
      "post": {
        "tags": [
          "Payment Gateway"
        ],
        "summary": "Validate charge with OTP",
        "description": "Submit an OTP to complete a pending mobile money or card charge that requires validation.",
        "operationId": "gatewayValidateCharge",
        "security": [
          {
            "bearerAuth": []
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "required": [
                  "charge_id",
                  "otp"
                ],
                "properties": {
                  "charge_id": {
                    "type": "string",
                    "format": "uuid"
                  },
                  "otp": {
                    "type": "string",
                    "example": "123456"
                  },
                  "flw_ref": {
                    "type": "string",
                    "description": "Flutterwave reference (optional, auto-resolved from charge)"
                  }
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Charge validation result",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "id": {
                      "type": "string"
                    },
                    "status": {
                      "type": "string",
                      "enum": [
                        "successful",
                        "failed"
                      ]
                    },
                    "message": {
                      "type": "string"
                    }
                  }
                },
                "example": {
                  "id": "string",
                  "status": "successful",
                  "message": "string"
                }
              }
            },
            "headers": {
              "x-fapi-interaction-id": {
                "$ref": "#/components/headers/XFapiInteractionIdResponse"
              },
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/XRateLimitLimit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/XRateLimitRemaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/XRateLimitReset"
              },
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              },
              "X-Idempotent-Replay": {
                "$ref": "#/components/headers/X-Idempotent-Replay"
              },
              "X-Idempotency-Status": {
                "$ref": "#/components/headers/X-Idempotency-Status"
              },
              "traceparent": {
                "$ref": "#/components/headers/Traceparent"
              },
              "Content-Language": {
                "$ref": "#/components/headers/Content-Language"
              }
            }
          },
          "400": {
            "description": "Bad request",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              },
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                },
                "examples": {
                  "error": {
                    "$ref": "#/components/examples/ErrorBadRequest"
                  }
                }
              }
            },
            "headers": {
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/XRateLimitLimit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/XRateLimitRemaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/XRateLimitReset"
              },
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "403": {
            "$ref": "#/components/responses/Forbidden",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "404": {
            "$ref": "#/components/responses/NotFound",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "409": {
            "$ref": "#/components/responses/Conflict",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "429": {
            "$ref": "#/components/responses/TooManyRequests",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "500": {
            "$ref": "#/components/responses/InternalServerError",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          }
        },
        "parameters": [
          {
            "$ref": "#/components/parameters/IdempotencyKey"
          },
          {
            "$ref": "#/components/parameters/RequestId"
          },
          {
            "$ref": "#/components/parameters/Traceparent"
          },
          {
            "$ref": "#/components/parameters/Tracestate"
          },
          {
            "$ref": "#/components/parameters/AcceptLanguage"
          }
        ],
        "x-codeSamples": [
          {
            "lang": "cURL",
            "label": "cURL",
            "source": "curl -X POST \"https://api.kangopenbanking.com/v1/gateway/charges/validate\" \\\n  -H \"Authorization: Bearer $KOB_ACCESS_TOKEN\" \\\n  -H \"Content-Type: application/json\" \\\n  -d '{}'"
          },
          {
            "lang": "JavaScript",
            "label": "Node.js",
            "source": "import { KangOpenBanking } from \"@kangopenbanking/sdk\";\n\nconst kob = new KangOpenBanking({ apiKey: process.env.KOB_API_KEY });\nconst res = await kob.request(\"POST\", \"/v1/gateway/charges/validate\", { /* payload */ });\nconsole.log(res);"
          },
          {
            "lang": "Python",
            "label": "Python",
            "source": "from kangopenbanking import KangOpenBanking\n\nkob = KangOpenBanking(api_key=os.environ[\"KOB_API_KEY\"])\nres = kob.request(\"POST\", \"/v1/gateway/charges/validate\", json={})\nprint(res)"
          },
          {
            "lang": "PHP",
            "label": "PHP",
            "source": "<?php\n$kob = new KangOpenBanking\\KangOpenBanking(getenv('KOB_API_KEY'));\n$res = $kob->request('POST', '/v1/gateway/charges/validate', []);\nprint_r($res);"
          }
        ]
      }
    },
    "/v1/gateway/virtual-accounts": {
      "post": {
        "tags": [
          "Payment Gateway"
        ],
        "summary": "Create virtual account",
        "description": "Provision a dedicated Nium virtual receiving account. Supports 17 source currencies (USD, EUR, GBP, AUD, CAD, SGD, AED, JPY, INR, ZAR, HKD, CHF, NZD, SEK, NOK, DKK, CNY) with XAF as the locked destination currency. `account_kind=\"global\"` returns IBAN/SWIFT details for cross-border collections.\n\n**Migration:** Replace with `createGlobalAccount`. Create a Nium global account for new integrations. Existing virtual accounts continue to receive funds until the sunset date.",
        "operationId": "gatewayCreateVirtualAccount",
        "security": [
          {
            "bearerAuth": []
          }
        ],
        "parameters": [
          {
            "name": "Idempotency-Key",
            "in": "header",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid"
            },
            "description": "Required on all POST/PUT endpoints. Unique key for idempotent request processing (UUID v4 recommended). Keys expire after 24 hours."
          },
          {
            "$ref": "#/components/parameters/RequestId"
          },
          {
            "$ref": "#/components/parameters/Traceparent"
          },
          {
            "$ref": "#/components/parameters/Tracestate"
          },
          {
            "$ref": "#/components/parameters/AcceptLanguage"
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "required": [
                  "merchant_id",
                  "email"
                ],
                "properties": {
                  "merchant_id": {
                    "type": "string",
                    "format": "uuid"
                  },
                  "email": {
                    "type": "string"
                  },
                  "bvn": {
                    "type": "string"
                  },
                  "currency": {
                    "type": "string",
                    "default": "NGN",
                    "enum": [
                      "XAF",
                      "XOF",
                      "USD",
                      "EUR",
                      "GBP",
                      "CNY",
                      "NGN",
                      "GHS",
                      "KES",
                      "ZAR"
                    ],
                    "description": "ISO 4217 currency code. Default is XAF (Central African CFA Franc)."
                  },
                  "is_permanent": {
                    "type": "boolean",
                    "default": false
                  },
                  "narration": {
                    "type": "string"
                  }
                }
              }
            }
          }
        },
        "responses": {
          "201": {
            "description": "Virtual account created",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/GatewayVirtualAccount"
                },
                "example": {
                  "id": "00000000-0000-4000-8000-000000000000",
                  "merchant_id": "00000000-0000-4000-8000-000000000000",
                  "account_number": "37001 23456 78901234567 89",
                  "bank_name": "Afriland First Bank",
                  "currency": "XAF",
                  "status": "active",
                  "email": "agent@example.cm",
                  "expiry": "2026-01-01T00:00:00Z",
                  "created_at": "2026-01-01T00:00:00Z",
                  "bank_country": "CM"
                }
              }
            },
            "headers": {
              "x-fapi-interaction-id": {
                "$ref": "#/components/headers/XFapiInteractionIdResponse"
              },
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/XRateLimitLimit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/XRateLimitRemaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/XRateLimitReset"
              },
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              },
              "X-Idempotent-Replay": {
                "$ref": "#/components/headers/X-Idempotent-Replay"
              },
              "X-Idempotency-Status": {
                "$ref": "#/components/headers/X-Idempotency-Status"
              },
              "traceparent": {
                "$ref": "#/components/headers/Traceparent"
              },
              "Content-Language": {
                "$ref": "#/components/headers/Content-Language"
              }
            }
          },
          "400": {
            "description": "Bad request",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              },
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                },
                "examples": {
                  "error": {
                    "$ref": "#/components/examples/ErrorBadRequest"
                  }
                }
              }
            },
            "headers": {
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/XRateLimitLimit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/XRateLimitRemaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/XRateLimitReset"
              },
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "403": {
            "$ref": "#/components/responses/Forbidden",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "404": {
            "$ref": "#/components/responses/NotFound",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "409": {
            "$ref": "#/components/responses/Conflict",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "429": {
            "$ref": "#/components/responses/TooManyRequests",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "500": {
            "$ref": "#/components/responses/InternalServerError",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          }
        },
        "deprecated": true,
        "x-sunset": "2027-01-01",
        "x-deprecation-notice": "Use /v1/gateway/global-accounts (Nium) for new integrations. This endpoint will be removed on 2027-01-01.",
        "x-codeSamples": [
          {
            "lang": "cURL",
            "label": "cURL",
            "source": "curl -X POST \"https://api.kangopenbanking.com/v1/gateway/virtual-accounts\" \\\n  -H \"Authorization: Bearer $KOB_ACCESS_TOKEN\" \\\n  -H \"Content-Type: application/json\" \\\n  -d '{}'"
          },
          {
            "lang": "JavaScript",
            "label": "Node.js",
            "source": "import { KangOpenBanking } from \"@kangopenbanking/sdk\";\n\nconst kob = new KangOpenBanking({ apiKey: process.env.KOB_API_KEY });\nconst res = await kob.request(\"POST\", \"/v1/gateway/virtual-accounts\", { /* payload */ });\nconsole.log(res);"
          },
          {
            "lang": "Python",
            "label": "Python",
            "source": "from kangopenbanking import KangOpenBanking\n\nkob = KangOpenBanking(api_key=os.environ[\"KOB_API_KEY\"])\nres = kob.request(\"POST\", \"/v1/gateway/virtual-accounts\", json={})\nprint(res)"
          },
          {
            "lang": "PHP",
            "label": "PHP",
            "source": "<?php\n$kob = new KangOpenBanking\\KangOpenBanking(getenv('KOB_API_KEY'));\n$res = $kob->request('POST', '/v1/gateway/virtual-accounts', []);\nprint_r($res);"
          }
        ],
        "x-replacement-operation-ids": [
          "createGlobalAccount"
        ],
        "x-migration-guide": "Create a Nium global account for new integrations. Existing virtual accounts continue to receive funds until the sunset date."
      },
      "get": {
        "tags": [
          "Payment Gateway"
        ],
        "summary": "List virtual accounts",
        "operationId": "gatewayListVirtualAccounts",
        "security": [
          {
            "bearerAuth": []
          }
        ],
        "parameters": [
          {
            "name": "merchant_id",
            "in": "query",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "$ref": "#/components/parameters/RequestId"
          },
          {
            "$ref": "#/components/parameters/Traceparent"
          },
          {
            "$ref": "#/components/parameters/Tracestate"
          },
          {
            "$ref": "#/components/parameters/AcceptLanguage"
          }
        ],
        "responses": {
          "200": {
            "description": "Virtual accounts list",
            "content": {
              "application/json": {
                "schema": {
                  "allOf": [
                    {
                      "$ref": "#/components/schemas/PaginatedResponse"
                    },
                    {
                      "type": "object",
                      "properties": {
                        "data": {
                          "type": "array",
                          "items": {
                            "$ref": "#/components/schemas/GatewayVirtualAccount"
                          }
                        }
                      }
                    }
                  ]
                },
                "example": {
                  "data": [
                    {
                      "id": "f1d6f4a0-1d4e-4a3a-9e0a-1a2b3c4d5e6f",
                      "merchant_id": "f1d6f4a0-1d4e-4a3a-9e0a-1a2b3c4d5e6f",
                      "account_number": "37001 23456 78901234567 89",
                      "bank_name": "Afriland First Bank",
                      "currency": "XAF",
                      "status": "active",
                      "email": "XAF",
                      "expiry": "2026-01-31T12:00:00Z",
                      "created_at": "2026-01-31T12:00:00Z",
                      "bank_country": "CM"
                    }
                  ],
                  "pagination": {
                    "page": 1,
                    "limit": 20,
                    "total": 150,
                    "has_next": true,
                    "next_cursor": "eyJpZCI6IjEyMyJ9"
                  },
                  "meta": {
                    "request_id": "550e8400-e29b-41d4-a716-446655440000",
                    "timestamp": "2025-03-27T12:00:00Z",
                    "api_version": "4.3.0"
                  }
                }
              }
            },
            "headers": {
              "x-fapi-interaction-id": {
                "$ref": "#/components/headers/XFapiInteractionIdResponse"
              },
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/XRateLimitLimit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/XRateLimitRemaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/XRateLimitReset"
              },
              "Cache-Control": {
                "$ref": "#/components/headers/CacheControl"
              },
              "ETag": {
                "$ref": "#/components/headers/ETag"
              },
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              },
              "traceparent": {
                "$ref": "#/components/headers/Traceparent"
              },
              "Content-Language": {
                "$ref": "#/components/headers/Content-Language"
              }
            }
          },
          "400": {
            "description": "Bad request",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              },
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                },
                "examples": {
                  "error": {
                    "$ref": "#/components/examples/ErrorBadRequest"
                  }
                }
              }
            },
            "headers": {
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/XRateLimitLimit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/XRateLimitRemaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/XRateLimitReset"
              },
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "403": {
            "$ref": "#/components/responses/Forbidden",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "404": {
            "$ref": "#/components/responses/NotFound",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "409": {
            "$ref": "#/components/responses/Conflict",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "429": {
            "$ref": "#/components/responses/TooManyRequests",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "500": {
            "$ref": "#/components/responses/InternalServerError",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          }
        },
        "deprecated": true,
        "x-sunset": "2027-01-01",
        "x-deprecation-notice": "Use /v1/gateway/global-accounts (Nium) for new integrations. This endpoint will be removed on 2027-01-01.",
        "x-codeSamples": [
          {
            "lang": "cURL",
            "label": "cURL",
            "source": "curl -X GET \"https://api.kangopenbanking.com/v1/gateway/virtual-accounts\" \\\n  -H \"Authorization: Bearer $KOB_ACCESS_TOKEN\" \\\n  -H \"Content-Type: application/json\""
          },
          {
            "lang": "JavaScript",
            "label": "Node.js",
            "source": "import { KangOpenBanking } from \"@kangopenbanking/sdk\";\n\nconst kob = new KangOpenBanking({ apiKey: process.env.KOB_API_KEY });\nconst res = await kob.request(\"GET\", \"/v1/gateway/virtual-accounts\");\nconsole.log(res);"
          },
          {
            "lang": "Python",
            "label": "Python",
            "source": "from kangopenbanking import KangOpenBanking\n\nkob = KangOpenBanking(api_key=os.environ[\"KOB_API_KEY\"])\nres = kob.request(\"GET\", \"/v1/gateway/virtual-accounts\")\nprint(res)"
          },
          {
            "lang": "PHP",
            "label": "PHP",
            "source": "<?php\n$kob = new KangOpenBanking\\KangOpenBanking(getenv('KOB_API_KEY'));\n$res = $kob->request('GET', '/v1/gateway/virtual-accounts');\nprint_r($res);"
          }
        ],
        "description": "List virtual accounts.\n\n**Tag:** Payment Gateway\n\nAuthenticate with a bearer token issued by `/v1/oauth/token`. All state-changing requests\n(POST, PUT, PATCH, DELETE) MUST include an `Idempotency-Key` header (UUID v4) to make\nretries safe — Kang will return the original response for any duplicate key within 24 hours.\n\nErrors follow [RFC 7807](https://datatracker.ietf.org/doc/html/rfc7807) and are returned with\n`Content-Type: application/problem+json`. The `code` field is stable and machine-readable.\nRate-limit headers (`X-RateLimit-Limit`, `X-RateLimit-Remaining`, `X-RateLimit-Reset`)\nare present on every response.\n\n**Migration:** Replace with `listGlobalAccounts`. List global accounts. Virtual accounts created before migration remain readable here until the sunset date.",
        "x-replacement-operation-ids": [
          "listGlobalAccounts"
        ],
        "x-migration-guide": "List global accounts. Virtual accounts created before migration remain readable here until the sunset date."
      }
    },
    "/v1/gateway/virtual-accounts/{accountId}": {
      "get": {
        "tags": [
          "Payment Gateway"
        ],
        "summary": "Get virtual account",
        "operationId": "gatewayGetVirtualAccount",
        "security": [
          {
            "bearerAuth": []
          }
        ],
        "parameters": [
          {
            "name": "accountId",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "$ref": "#/components/parameters/RequestId"
          },
          {
            "$ref": "#/components/parameters/Traceparent"
          },
          {
            "$ref": "#/components/parameters/Tracestate"
          },
          {
            "$ref": "#/components/parameters/AcceptLanguage"
          }
        ],
        "responses": {
          "200": {
            "description": "Virtual account details",
            "content": {
              "application/json": {
                "schema": {
                  "allOf": [
                    {
                      "$ref": "#/components/schemas/StandardResponse"
                    },
                    {
                      "type": "object",
                      "properties": {
                        "data": {
                          "$ref": "#/components/schemas/GatewayVirtualAccount"
                        }
                      }
                    }
                  ]
                },
                "example": {
                  "data": {
                    "id": "00000000-0000-4000-8000-000000000000",
                    "merchant_id": "00000000-0000-4000-8000-000000000000",
                    "account_number": "37001 23456 78901234567 89",
                    "bank_name": "Afriland First Bank",
                    "currency": "XAF",
                    "status": "active",
                    "email": "agent@example.cm",
                    "expiry": "2026-01-01T00:00:00Z",
                    "created_at": "2026-01-01T00:00:00Z",
                    "bank_country": "CM"
                  },
                  "meta": {
                    "request_id": "550e8400-e29b-41d4-a716-446655440000",
                    "timestamp": "2025-03-27T12:00:00Z",
                    "api_version": "4.3.0"
                  }
                }
              }
            },
            "headers": {
              "x-fapi-interaction-id": {
                "$ref": "#/components/headers/XFapiInteractionIdResponse"
              },
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/XRateLimitLimit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/XRateLimitRemaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/XRateLimitReset"
              },
              "Cache-Control": {
                "$ref": "#/components/headers/CacheControl"
              },
              "ETag": {
                "$ref": "#/components/headers/ETag"
              },
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              },
              "traceparent": {
                "$ref": "#/components/headers/Traceparent"
              },
              "Content-Language": {
                "$ref": "#/components/headers/Content-Language"
              }
            }
          },
          "400": {
            "description": "Bad request",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              },
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                },
                "examples": {
                  "error": {
                    "$ref": "#/components/examples/ErrorBadRequest"
                  }
                }
              }
            },
            "headers": {
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/XRateLimitLimit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/XRateLimitRemaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/XRateLimitReset"
              },
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "403": {
            "$ref": "#/components/responses/Forbidden",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "404": {
            "$ref": "#/components/responses/NotFound",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "409": {
            "$ref": "#/components/responses/Conflict",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "429": {
            "$ref": "#/components/responses/TooManyRequests",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "500": {
            "$ref": "#/components/responses/InternalServerError",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          }
        },
        "deprecated": true,
        "x-sunset": "2027-01-01",
        "x-deprecation-notice": "Use /v1/gateway/global-accounts (Nium) for new integrations. This endpoint will be removed on 2027-01-01.",
        "x-codeSamples": [
          {
            "lang": "cURL",
            "label": "cURL",
            "source": "curl -X GET \"https://api.kangopenbanking.com/v1/gateway/virtual-accounts/{accountId}\" \\\n  -H \"Authorization: Bearer $KOB_ACCESS_TOKEN\" \\\n  -H \"Content-Type: application/json\""
          },
          {
            "lang": "JavaScript",
            "label": "Node.js",
            "source": "import { KangOpenBanking } from \"@kangopenbanking/sdk\";\n\nconst kob = new KangOpenBanking({ apiKey: process.env.KOB_API_KEY });\nconst res = await kob.request(\"GET\", \"/v1/gateway/virtual-accounts/{accountId}\");\nconsole.log(res);"
          },
          {
            "lang": "Python",
            "label": "Python",
            "source": "from kangopenbanking import KangOpenBanking\n\nkob = KangOpenBanking(api_key=os.environ[\"KOB_API_KEY\"])\nres = kob.request(\"GET\", \"/v1/gateway/virtual-accounts/{accountId}\")\nprint(res)"
          },
          {
            "lang": "PHP",
            "label": "PHP",
            "source": "<?php\n$kob = new KangOpenBanking\\KangOpenBanking(getenv('KOB_API_KEY'));\n$res = $kob->request('GET', '/v1/gateway/virtual-accounts/{accountId}');\nprint_r($res);"
          }
        ],
        "description": "Get virtual account.\n\n**Tag:** Payment Gateway\n\nAuthenticate with a bearer token issued by `/v1/oauth/token`. All state-changing requests\n(POST, PUT, PATCH, DELETE) MUST include an `Idempotency-Key` header (UUID v4) to make\nretries safe — Kang will return the original response for any duplicate key within 24 hours.\n\nErrors follow [RFC 7807](https://datatracker.ietf.org/doc/html/rfc7807) and are returned with\n`Content-Type: application/problem+json`. The `code` field is stable and machine-readable.\nRate-limit headers (`X-RateLimit-Limit`, `X-RateLimit-Remaining`, `X-RateLimit-Reset`)\nare present on every response.\n\n**Migration:** Replace with `listGlobalAccounts`. No single-item global account read exists; filter `listGlobalAccounts` results by account identifier.",
        "x-replacement-operation-ids": [
          "listGlobalAccounts"
        ],
        "x-migration-guide": "No single-item global account read exists; filter `listGlobalAccounts` results by account identifier."
      }
    },
    "/v1/gateway/balances": {
      "get": {
        "tags": [
          "Payment Gateway"
        ],
        "summary": "Get merchant balances",
        "description": "Retrieve available, pending, and ledger balances across currencies.",
        "operationId": "gatewayGetMerchantBalance",
        "security": [
          {
            "bearerAuth": []
          }
        ],
        "parameters": [
          {
            "name": "merchant_id",
            "in": "query",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "$ref": "#/components/parameters/RequestId"
          },
          {
            "$ref": "#/components/parameters/Traceparent"
          },
          {
            "$ref": "#/components/parameters/Tracestate"
          },
          {
            "$ref": "#/components/parameters/AcceptLanguage"
          }
        ],
        "responses": {
          "200": {
            "description": "Merchant wallet balances",
            "content": {
              "application/json": {
                "schema": {
                  "allOf": [
                    {
                      "$ref": "#/components/schemas/PaginatedResponse"
                    },
                    {
                      "type": "object",
                      "properties": {
                        "data": {
                          "type": "array",
                          "items": {
                            "$ref": "#/components/schemas/GatewayMerchantWallet"
                          }
                        }
                      }
                    }
                  ]
                },
                "example": {
                  "data": [
                    {
                      "id": "f1d6f4a0-1d4e-4a3a-9e0a-1a2b3c4d5e6f",
                      "merchant_id": "f1d6f4a0-1d4e-4a3a-9e0a-1a2b3c4d5e6f",
                      "currency": "XAF",
                      "available_balance": "500000",
                      "pending_balance": 25000,
                      "ledger_balance": 525000,
                      "updated_at": "2026-01-31T12:00:00Z"
                    }
                  ],
                  "pagination": {
                    "page": 1,
                    "limit": 20,
                    "total": 150,
                    "has_next": true,
                    "next_cursor": "eyJpZCI6IjEyMyJ9"
                  },
                  "meta": {
                    "request_id": "550e8400-e29b-41d4-a716-446655440000",
                    "timestamp": "2025-03-27T12:00:00Z",
                    "api_version": "4.3.0"
                  }
                }
              }
            },
            "headers": {
              "x-fapi-interaction-id": {
                "$ref": "#/components/headers/XFapiInteractionIdResponse"
              },
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/XRateLimitLimit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/XRateLimitRemaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/XRateLimitReset"
              },
              "Cache-Control": {
                "$ref": "#/components/headers/CacheControl"
              },
              "ETag": {
                "$ref": "#/components/headers/ETag"
              },
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              },
              "traceparent": {
                "$ref": "#/components/headers/Traceparent"
              },
              "Content-Language": {
                "$ref": "#/components/headers/Content-Language"
              }
            }
          },
          "400": {
            "description": "Bad request",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              },
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                },
                "examples": {
                  "error": {
                    "$ref": "#/components/examples/ErrorBadRequest"
                  }
                }
              }
            },
            "headers": {
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/XRateLimitLimit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/XRateLimitRemaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/XRateLimitReset"
              },
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "403": {
            "$ref": "#/components/responses/Forbidden",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "404": {
            "$ref": "#/components/responses/NotFound",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "409": {
            "$ref": "#/components/responses/Conflict",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "429": {
            "$ref": "#/components/responses/TooManyRequests",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "500": {
            "$ref": "#/components/responses/InternalServerError",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          }
        },
        "x-codeSamples": [
          {
            "lang": "cURL",
            "label": "cURL",
            "source": "curl -X GET \"https://api.kangopenbanking.com/v1/gateway/balances\" \\\n  -H \"Authorization: Bearer $KOB_ACCESS_TOKEN\" \\\n  -H \"Content-Type: application/json\""
          },
          {
            "lang": "JavaScript",
            "label": "Node.js",
            "source": "import { KangOpenBanking } from \"@kangopenbanking/sdk\";\n\nconst kob = new KangOpenBanking({ apiKey: process.env.KOB_API_KEY });\nconst res = await kob.request(\"GET\", \"/v1/gateway/balances\");\nconsole.log(res);"
          },
          {
            "lang": "Python",
            "label": "Python",
            "source": "from kangopenbanking import KangOpenBanking\n\nkob = KangOpenBanking(api_key=os.environ[\"KOB_API_KEY\"])\nres = kob.request(\"GET\", \"/v1/gateway/balances\")\nprint(res)"
          },
          {
            "lang": "PHP",
            "label": "PHP",
            "source": "<?php\n$kob = new KangOpenBanking\\KangOpenBanking(getenv('KOB_API_KEY'));\n$res = $kob->request('GET', '/v1/gateway/balances');\nprint_r($res);"
          }
        ]
      }
    },
    "/v1/gateway/verify-bank-account": {
      "post": {
        "tags": [
          "Payment Gateway"
        ],
        "summary": "Verify bank account",
        "description": "Resolve a bank account number and retrieve the account holder name.",
        "operationId": "gatewayVerifyBankAccount",
        "security": [],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "required": [
                  "account_number",
                  "account_bank"
                ],
                "properties": {
                  "account_number": {
                    "type": "string",
                    "example": "1234567890"
                  },
                  "account_bank": {
                    "type": "string",
                    "example": "044",
                    "description": "Bank code"
                  }
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Account verification result",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/GatewayBankVerification"
                },
                "example": {
                  "account_name": "John Doe",
                  "account_number": "1234567890"
                }
              }
            },
            "headers": {
              "x-fapi-interaction-id": {
                "$ref": "#/components/headers/XFapiInteractionIdResponse"
              },
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/XRateLimitLimit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/XRateLimitRemaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/XRateLimitReset"
              },
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              },
              "traceparent": {
                "$ref": "#/components/headers/Traceparent"
              },
              "Content-Language": {
                "$ref": "#/components/headers/Content-Language"
              }
            }
          },
          "400": {
            "description": "Bad request",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              },
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                },
                "examples": {
                  "error": {
                    "$ref": "#/components/examples/ErrorBadRequest"
                  }
                }
              }
            },
            "headers": {
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/XRateLimitLimit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/XRateLimitRemaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/XRateLimitReset"
              },
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "403": {
            "$ref": "#/components/responses/Forbidden",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "404": {
            "$ref": "#/components/responses/NotFound",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "409": {
            "$ref": "#/components/responses/Conflict",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "429": {
            "$ref": "#/components/responses/TooManyRequests",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "500": {
            "$ref": "#/components/responses/InternalServerError",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          }
        },
        "parameters": [
          {
            "$ref": "#/components/parameters/RequestId"
          },
          {
            "$ref": "#/components/parameters/Traceparent"
          },
          {
            "$ref": "#/components/parameters/Tracestate"
          },
          {
            "$ref": "#/components/parameters/AcceptLanguage"
          }
        ],
        "x-codeSamples": [
          {
            "lang": "cURL",
            "label": "cURL",
            "source": "curl -X POST \"https://api.kangopenbanking.com/v1/gateway/verify-bank-account\" \\\n  -H \"Authorization: Bearer $KOB_ACCESS_TOKEN\" \\\n  -H \"Content-Type: application/json\" \\\n  -d '{}'"
          },
          {
            "lang": "JavaScript",
            "label": "Node.js",
            "source": "import { KangOpenBanking } from \"@kangopenbanking/sdk\";\n\nconst kob = new KangOpenBanking({ apiKey: process.env.KOB_API_KEY });\nconst res = await kob.request(\"POST\", \"/v1/gateway/verify-bank-account\", { /* payload */ });\nconsole.log(res);"
          },
          {
            "lang": "Python",
            "label": "Python",
            "source": "from kangopenbanking import KangOpenBanking\n\nkob = KangOpenBanking(api_key=os.environ[\"KOB_API_KEY\"])\nres = kob.request(\"POST\", \"/v1/gateway/verify-bank-account\", json={})\nprint(res)"
          },
          {
            "lang": "PHP",
            "label": "PHP",
            "source": "<?php\n$kob = new KangOpenBanking\\KangOpenBanking(getenv('KOB_API_KEY'));\n$res = $kob->request('POST', '/v1/gateway/verify-bank-account', []);\nprint_r($res);"
          }
        ]
      }
    },
    "/v1/gateway/resolve-bvn": {
      "post": {
        "tags": [
          "Payment Gateway"
        ],
        "summary": "Resolve BVN",
        "description": "Resolve a Bank Verification Number (BVN) to retrieve identity details.\n\n**CEMAC callers:** prefer `/v1/verify/nin` or `/v1/verify/cni`. The BVN endpoint targets the Nigerian Bank Verification Number registry and is retained for NG deployments only. Responses include `Link: <https://api.kangopenbanking.com/v1/verify/nin>; rel=\"successor-version\"` per RFC 8288 to aid client migration.",
        "operationId": "gatewayResolveBvn",
        "security": [
          {
            "bearerAuth": []
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "required": [
                  "bvn"
                ],
                "properties": {
                  "bvn": {
                    "type": "string",
                    "example": "12345678901"
                  }
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "BVN resolution result",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/GatewayBvnResolution"
                },
                "example": {
                  "bvn": "string",
                  "first_name": "string",
                  "last_name": "string",
                  "middle_name": "string",
                  "date_of_birth": "string",
                  "phone_number": "string"
                }
              }
            },
            "headers": {
              "x-fapi-interaction-id": {
                "$ref": "#/components/headers/XFapiInteractionIdResponse"
              },
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/XRateLimitLimit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/XRateLimitRemaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/XRateLimitReset"
              },
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              },
              "traceparent": {
                "$ref": "#/components/headers/Traceparent"
              },
              "Content-Language": {
                "$ref": "#/components/headers/Content-Language"
              },
              "Link": {
                "$ref": "#/components/headers/LinkSuccessor"
              },
              "Deprecation": {
                "$ref": "#/components/headers/Deprecation"
              }
            }
          },
          "400": {
            "description": "Bad request",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              },
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                },
                "examples": {
                  "error": {
                    "$ref": "#/components/examples/ErrorBadRequest"
                  }
                }
              }
            },
            "headers": {
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/XRateLimitLimit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/XRateLimitRemaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/XRateLimitReset"
              },
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              },
              "Link": {
                "$ref": "#/components/headers/LinkSuccessor"
              },
              "Deprecation": {
                "$ref": "#/components/headers/Deprecation"
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              },
              "Link": {
                "$ref": "#/components/headers/LinkSuccessor"
              },
              "Deprecation": {
                "$ref": "#/components/headers/Deprecation"
              }
            }
          },
          "403": {
            "$ref": "#/components/responses/Forbidden",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              },
              "Link": {
                "$ref": "#/components/headers/LinkSuccessor"
              },
              "Deprecation": {
                "$ref": "#/components/headers/Deprecation"
              }
            }
          },
          "404": {
            "$ref": "#/components/responses/NotFound",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              },
              "Link": {
                "$ref": "#/components/headers/LinkSuccessor"
              },
              "Deprecation": {
                "$ref": "#/components/headers/Deprecation"
              }
            }
          },
          "409": {
            "$ref": "#/components/responses/Conflict",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              },
              "Link": {
                "$ref": "#/components/headers/LinkSuccessor"
              },
              "Deprecation": {
                "$ref": "#/components/headers/Deprecation"
              }
            }
          },
          "429": {
            "$ref": "#/components/responses/TooManyRequests",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              },
              "Link": {
                "$ref": "#/components/headers/LinkSuccessor"
              },
              "Deprecation": {
                "$ref": "#/components/headers/Deprecation"
              }
            }
          },
          "500": {
            "$ref": "#/components/responses/InternalServerError",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              },
              "Link": {
                "$ref": "#/components/headers/LinkSuccessor"
              },
              "Deprecation": {
                "$ref": "#/components/headers/Deprecation"
              }
            }
          }
        },
        "parameters": [
          {
            "$ref": "#/components/parameters/RequestId"
          },
          {
            "$ref": "#/components/parameters/Traceparent"
          },
          {
            "$ref": "#/components/parameters/Tracestate"
          },
          {
            "$ref": "#/components/parameters/AcceptLanguage"
          }
        ],
        "deprecated": false,
        "x-deprecated-for-region": [
          "CEMAC"
        ],
        "x-codeSamples": [
          {
            "lang": "cURL",
            "label": "cURL",
            "source": "curl -X POST \"https://api.kangopenbanking.com/v1/gateway/resolve-bvn\" \\\n  -H \"Authorization: Bearer $KOB_ACCESS_TOKEN\" \\\n  -H \"Content-Type: application/json\" \\\n  -d '{}'"
          },
          {
            "lang": "JavaScript",
            "label": "Node.js",
            "source": "import { KangOpenBanking } from \"@kangopenbanking/sdk\";\n\nconst kob = new KangOpenBanking({ apiKey: process.env.KOB_API_KEY });\nconst res = await kob.request(\"POST\", \"/v1/gateway/resolve-bvn\", { /* payload */ });\nconsole.log(res);"
          },
          {
            "lang": "Python",
            "label": "Python",
            "source": "from kangopenbanking import KangOpenBanking\n\nkob = KangOpenBanking(api_key=os.environ[\"KOB_API_KEY\"])\nres = kob.request(\"POST\", \"/v1/gateway/resolve-bvn\", json={})\nprint(res)"
          },
          {
            "lang": "PHP",
            "label": "PHP",
            "source": "<?php\n$kob = new KangOpenBanking\\KangOpenBanking(getenv('KOB_API_KEY'));\n$res = $kob->request('POST', '/v1/gateway/resolve-bvn', []);\nprint_r($res);"
          }
        ]
      }
    },
    "/v1/gateway/fund-account": {
      "post": {
        "tags": [
          "Payment Gateway"
        ],
        "summary": "Fund a KOB account",
        "description": "Add funds to a user's KOB account via Mobile Money, Card, or Bank Transfer. On successful provider charge, the account balance is automatically credited.",
        "operationId": "gatewayFundAccount",
        "security": [
          {
            "bearerAuth": []
          }
        ],
        "parameters": [
          {
            "name": "Idempotency-Key",
            "in": "header",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid"
            },
            "description": "Required on all POST/PUT endpoints. Unique key for idempotent request processing (UUID v4 recommended). Keys expire after 24 hours."
          },
          {
            "$ref": "#/components/parameters/RequestId"
          },
          {
            "$ref": "#/components/parameters/Traceparent"
          },
          {
            "$ref": "#/components/parameters/Tracestate"
          },
          {
            "$ref": "#/components/parameters/AcceptLanguage"
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "required": [
                  "amount",
                  "channel",
                  "account_id"
                ],
                "properties": {
                  "amount": {
                    "type": "string",
                    "example": "50000",
                    "pattern": "^[0-9]{1,15}$",
                    "description": "Represented as a string integer in the currency's minor unit (XAF has no subunits). Must be consistent with the currency field."
                  },
                  "currency": {
                    "type": "string",
                    "default": "XAF",
                    "enum": [
                      "XAF",
                      "XOF",
                      "USD",
                      "EUR",
                      "GBP",
                      "CNY",
                      "NGN",
                      "GHS",
                      "KES",
                      "ZAR"
                    ],
                    "description": "ISO 4217 currency code. Default is XAF (Central African CFA Franc)."
                  },
                  "channel": {
                    "type": "string",
                    "enum": [
                      "mobile_money",
                      "card",
                      "bank_transfer"
                    ]
                  },
                  "account_id": {
                    "type": "string",
                    "format": "uuid",
                    "description": "Target KOB account to credit"
                  },
                  "source_phone": {
                    "type": "string",
                    "description": "Required for mobile_money"
                  },
                  "source_email": {
                    "type": "string",
                    "description": "Required for card"
                  },
                  "metadata": {
                    "type": "object"
                  }
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Funding charge initiated",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "id": {
                      "type": "string"
                    },
                    "account_id": {
                      "type": "string"
                    },
                    "amount": {
                      "type": "string",
                      "pattern": "^[0-9]{1,15}$",
                      "description": "Represented as a string integer in the currency's minor unit (XAF has no subunits). Must be consistent with the currency field."
                    },
                    "currency": {
                      "type": "string",
                      "enum": [
                        "XAF",
                        "XOF",
                        "USD",
                        "EUR",
                        "GBP",
                        "CNY",
                        "NGN",
                        "GHS",
                        "KES",
                        "ZAR"
                      ],
                      "default": "XAF",
                      "description": "ISO 4217 currency code. Default is XAF (Central African CFA Franc)."
                    },
                    "channel": {
                      "type": "string"
                    },
                    "provider": {
                      "type": "string"
                    },
                    "status": {
                      "type": "string"
                    },
                    "fee_amount": {
                      "type": "number"
                    },
                    "net_amount": {
                      "type": "number"
                    },
                    "tx_ref": {
                      "type": "string"
                    },
                    "redirect_url": {
                      "type": "string"
                    },
                    "created_at": {
                      "type": "string"
                    }
                  }
                },
                "example": {
                  "id": "string",
                  "account_id": "string",
                  "amount": "1000",
                  "currency": "XAF",
                  "channel": "string",
                  "provider": "string",
                  "status": "string",
                  "fee_amount": 0,
                  "net_amount": 0,
                  "tx_ref": "string",
                  "redirect_url": "string",
                  "created_at": "string"
                }
              }
            },
            "headers": {
              "x-fapi-interaction-id": {
                "$ref": "#/components/headers/XFapiInteractionIdResponse"
              },
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/XRateLimitLimit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/XRateLimitRemaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/XRateLimitReset"
              },
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              },
              "X-Idempotent-Replay": {
                "$ref": "#/components/headers/X-Idempotent-Replay"
              },
              "X-Idempotency-Status": {
                "$ref": "#/components/headers/X-Idempotency-Status"
              },
              "traceparent": {
                "$ref": "#/components/headers/Traceparent"
              },
              "Content-Language": {
                "$ref": "#/components/headers/Content-Language"
              }
            }
          },
          "400": {
            "description": "Bad request",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              },
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                },
                "examples": {
                  "error": {
                    "$ref": "#/components/examples/ErrorBadRequest"
                  }
                }
              }
            },
            "headers": {
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/XRateLimitLimit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/XRateLimitRemaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/XRateLimitReset"
              },
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "403": {
            "$ref": "#/components/responses/Forbidden",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "404": {
            "$ref": "#/components/responses/NotFound",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "409": {
            "$ref": "#/components/responses/Conflict",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "429": {
            "$ref": "#/components/responses/TooManyRequests",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "500": {
            "$ref": "#/components/responses/InternalServerError",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          }
        },
        "x-codeSamples": [
          {
            "lang": "cURL",
            "label": "cURL",
            "source": "curl -X POST \"https://api.kangopenbanking.com/v1/gateway/fund-account\" \\\n  -H \"Authorization: Bearer $KOB_ACCESS_TOKEN\" \\\n  -H \"Content-Type: application/json\" \\\n  -d '{}'"
          },
          {
            "lang": "JavaScript",
            "label": "Node.js",
            "source": "import { KangOpenBanking } from \"@kangopenbanking/sdk\";\n\nconst kob = new KangOpenBanking({ apiKey: process.env.KOB_API_KEY });\nconst res = await kob.request(\"POST\", \"/v1/gateway/fund-account\", { /* payload */ });\nconsole.log(res);"
          },
          {
            "lang": "Python",
            "label": "Python",
            "source": "from kangopenbanking import KangOpenBanking\n\nkob = KangOpenBanking(api_key=os.environ[\"KOB_API_KEY\"])\nres = kob.request(\"POST\", \"/v1/gateway/fund-account\", json={})\nprint(res)"
          },
          {
            "lang": "PHP",
            "label": "PHP",
            "source": "<?php\n$kob = new KangOpenBanking\\KangOpenBanking(getenv('KOB_API_KEY'));\n$res = $kob->request('POST', '/v1/gateway/fund-account', []);\nprint_r($res);"
          }
        ]
      }
    },
    "/v1/gateway/withdraw-to-bank": {
      "post": {
        "tags": [
          "Payment Gateway"
        ],
        "summary": "Withdraw to external bank",
        "description": "Withdraw funds from a user's KOB account to an external bank account via Flutterwave. Debits the account immediately; reverses if payout fails.",
        "operationId": "gatewayWithdrawToBank",
        "security": [
          {
            "bearerAuth": []
          }
        ],
        "parameters": [
          {
            "name": "Idempotency-Key",
            "in": "header",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid"
            },
            "description": "Required on all POST/PUT endpoints. Unique key for idempotent request processing (UUID v4 recommended). Keys expire after 24 hours."
          },
          {
            "$ref": "#/components/parameters/RequestId"
          },
          {
            "$ref": "#/components/parameters/Traceparent"
          },
          {
            "$ref": "#/components/parameters/Tracestate"
          },
          {
            "$ref": "#/components/parameters/AcceptLanguage"
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "required": [
                  "amount",
                  "account_id",
                  "account_number",
                  "beneficiary_name"
                ],
                "properties": {
                  "amount": {
                    "type": "string",
                    "example": "25000",
                    "pattern": "^[0-9]{1,15}$",
                    "description": "Represented as a string integer in the currency's minor unit (XAF has no subunits)."
                  },
                  "account_id": {
                    "type": "string",
                    "format": "uuid",
                    "description": "Source KOB account to debit"
                  },
                  "bank_code": {
                    "type": "string",
                    "example": "SGCM"
                  },
                  "account_number": {
                    "type": "string",
                    "example": "1234567890"
                  },
                  "beneficiary_name": {
                    "type": "string",
                    "example": "Jean Dupont"
                  },
                  "narration": {
                    "type": "string"
                  },
                  "channel": {
                    "type": "string",
                    "default": "bank_transfer"
                  }
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Withdrawal initiated",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "id": {
                      "type": "string"
                    },
                    "account_id": {
                      "type": "string"
                    },
                    "amount": {
                      "type": "string",
                      "pattern": "^[0-9]{1,15}$",
                      "description": "Represented as a string integer in the currency's minor unit (XAF has no subunits). Must be consistent with the currency field."
                    },
                    "fee_amount": {
                      "type": "number"
                    },
                    "total_debited": {
                      "type": "number"
                    },
                    "currency": {
                      "type": "string",
                      "enum": [
                        "XAF",
                        "XOF",
                        "USD",
                        "EUR",
                        "GBP",
                        "CNY",
                        "NGN",
                        "GHS",
                        "KES",
                        "ZAR"
                      ],
                      "default": "XAF",
                      "description": "ISO 4217 currency code. Default is XAF (Central African CFA Franc)."
                    },
                    "status": {
                      "type": "string"
                    },
                    "beneficiary_name": {
                      "type": "string"
                    },
                    "beneficiary_account": {
                      "type": "string"
                    },
                    "tx_ref": {
                      "type": "string"
                    },
                    "created_at": {
                      "type": "string"
                    }
                  }
                },
                "example": {
                  "id": "string",
                  "account_id": "string",
                  "amount": "1000",
                  "fee_amount": 0,
                  "total_debited": 0,
                  "currency": "XAF",
                  "status": "string",
                  "beneficiary_name": "string",
                  "beneficiary_account": "string",
                  "tx_ref": "string",
                  "created_at": "string"
                }
              }
            },
            "headers": {
              "x-fapi-interaction-id": {
                "$ref": "#/components/headers/XFapiInteractionIdResponse"
              },
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/XRateLimitLimit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/XRateLimitRemaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/XRateLimitReset"
              },
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              },
              "X-Idempotent-Replay": {
                "$ref": "#/components/headers/X-Idempotent-Replay"
              },
              "X-Idempotency-Status": {
                "$ref": "#/components/headers/X-Idempotency-Status"
              },
              "traceparent": {
                "$ref": "#/components/headers/Traceparent"
              },
              "Content-Language": {
                "$ref": "#/components/headers/Content-Language"
              }
            }
          },
          "400": {
            "description": "Bad request",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              },
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                },
                "examples": {
                  "error": {
                    "$ref": "#/components/examples/ErrorBadRequest"
                  }
                }
              }
            },
            "headers": {
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/XRateLimitLimit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/XRateLimitRemaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/XRateLimitReset"
              },
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "403": {
            "$ref": "#/components/responses/Forbidden",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "404": {
            "$ref": "#/components/responses/NotFound",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "409": {
            "$ref": "#/components/responses/Conflict",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "429": {
            "$ref": "#/components/responses/TooManyRequests",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "500": {
            "$ref": "#/components/responses/InternalServerError",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          }
        },
        "x-codeSamples": [
          {
            "lang": "cURL",
            "label": "cURL",
            "source": "curl -X POST \"https://api.kangopenbanking.com/v1/gateway/withdraw-to-bank\" \\\n  -H \"Authorization: Bearer $KOB_ACCESS_TOKEN\" \\\n  -H \"Content-Type: application/json\" \\\n  -d '{}'"
          },
          {
            "lang": "JavaScript",
            "label": "Node.js",
            "source": "import { KangOpenBanking } from \"@kangopenbanking/sdk\";\n\nconst kob = new KangOpenBanking({ apiKey: process.env.KOB_API_KEY });\nconst res = await kob.request(\"POST\", \"/v1/gateway/withdraw-to-bank\", { /* payload */ });\nconsole.log(res);"
          },
          {
            "lang": "Python",
            "label": "Python",
            "source": "from kangopenbanking import KangOpenBanking\n\nkob = KangOpenBanking(api_key=os.environ[\"KOB_API_KEY\"])\nres = kob.request(\"POST\", \"/v1/gateway/withdraw-to-bank\", json={})\nprint(res)"
          },
          {
            "lang": "PHP",
            "label": "PHP",
            "source": "<?php\n$kob = new KangOpenBanking\\KangOpenBanking(getenv('KOB_API_KEY'));\n$res = $kob->request('POST', '/v1/gateway/withdraw-to-bank', []);\nprint_r($res);"
          }
        ]
      }
    },
    "/v1/banking/internal-transfer": {
      "post": {
        "tags": [
          "Banking Operations"
        ],
        "summary": "Internal account-to-account transfer",
        "description": "Transfer funds between two accounts within KOB. Validates source ownership, checks balance, creates a Debit transaction, and updates balances atomically.",
        "operationId": "bankingInternalTransfer",
        "security": [
          {
            "bearerAuth": []
          }
        ],
        "parameters": [
          {
            "name": "Idempotency-Key",
            "in": "header",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid"
            },
            "description": "Required on all POST/PUT endpoints. Unique key for idempotent request processing (UUID v4 recommended). Keys expire after 24 hours."
          },
          {
            "$ref": "#/components/parameters/RequestId"
          },
          {
            "$ref": "#/components/parameters/Traceparent"
          },
          {
            "$ref": "#/components/parameters/Tracestate"
          },
          {
            "$ref": "#/components/parameters/AcceptLanguage"
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "required": [
                  "source_account_id",
                  "destination_account_id",
                  "amount"
                ],
                "properties": {
                  "source_account_id": {
                    "type": "string",
                    "format": "uuid",
                    "description": "Account to debit (must belong to authenticated user)"
                  },
                  "destination_account_id": {
                    "type": "string",
                    "format": "uuid",
                    "description": "Account to credit"
                  },
                  "amount": {
                    "type": "string",
                    "example": "25000",
                    "pattern": "^[0-9]{1,15}$",
                    "description": "Represented as a string integer in the currency's minor unit (XAF has no subunits). Must be consistent with the currency field."
                  },
                  "currency": {
                    "type": "string",
                    "default": "XAF",
                    "enum": [
                      "XAF",
                      "XOF",
                      "USD",
                      "EUR",
                      "GBP",
                      "CNY",
                      "NGN",
                      "GHS",
                      "KES",
                      "ZAR"
                    ],
                    "description": "ISO 4217 currency code. Default is XAF (Central African CFA Franc)."
                  },
                  "reference": {
                    "type": "string",
                    "description": "Custom reference (auto-generated if omitted)"
                  },
                  "description": {
                    "type": "string",
                    "description": "Transfer narration"
                  }
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Transfer completed",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "success": {
                      "type": "boolean"
                    },
                    "transaction_reference": {
                      "type": "string"
                    },
                    "transaction_id": {
                      "type": "string",
                      "format": "uuid"
                    },
                    "status": {
                      "type": "string",
                      "example": "Booked"
                    },
                    "amount": {
                      "type": "string",
                      "pattern": "^[0-9]{1,15}$",
                      "description": "Represented as a string integer in the currency's minor unit (XAF has no subunits). Must be consistent with the currency field."
                    },
                    "currency": {
                      "type": "string",
                      "enum": [
                        "XAF",
                        "XOF",
                        "USD",
                        "EUR",
                        "GBP",
                        "CNY",
                        "NGN",
                        "GHS",
                        "KES",
                        "ZAR"
                      ],
                      "default": "XAF",
                      "description": "ISO 4217 currency code. Default is XAF (Central African CFA Franc)."
                    }
                  }
                },
                "example": {
                  "success": true,
                  "transaction_reference": "string",
                  "transaction_id": "00000000-0000-4000-8000-000000000000",
                  "status": "Booked",
                  "amount": "1000",
                  "currency": "XAF"
                }
              }
            },
            "headers": {
              "x-fapi-interaction-id": {
                "$ref": "#/components/headers/XFapiInteractionIdResponse"
              },
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/XRateLimitLimit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/XRateLimitRemaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/XRateLimitReset"
              },
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              },
              "X-Idempotent-Replay": {
                "$ref": "#/components/headers/X-Idempotent-Replay"
              },
              "X-Idempotency-Status": {
                "$ref": "#/components/headers/X-Idempotency-Status"
              },
              "traceparent": {
                "$ref": "#/components/headers/Traceparent"
              },
              "Content-Language": {
                "$ref": "#/components/headers/Content-Language"
              }
            }
          },
          "400": {
            "description": "Bad request",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              },
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                },
                "examples": {
                  "error": {
                    "$ref": "#/components/examples/ErrorBadRequest"
                  }
                }
              }
            },
            "headers": {
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/XRateLimitLimit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/XRateLimitRemaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/XRateLimitReset"
              },
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "403": {
            "$ref": "#/components/responses/Forbidden",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "404": {
            "$ref": "#/components/responses/NotFound",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "409": {
            "$ref": "#/components/responses/Conflict",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "429": {
            "$ref": "#/components/responses/TooManyRequests",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "500": {
            "$ref": "#/components/responses/InternalServerError",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          }
        },
        "x-codeSamples": [
          {
            "lang": "cURL",
            "label": "cURL",
            "source": "curl -X POST \"https://api.kangopenbanking.com/v1/banking/internal-transfer\" \\\n  -H \"Authorization: Bearer $KOB_ACCESS_TOKEN\" \\\n  -H \"Content-Type: application/json\" \\\n  -d '{}'"
          },
          {
            "lang": "JavaScript",
            "label": "Node.js",
            "source": "import { KangOpenBanking } from \"@kangopenbanking/sdk\";\n\nconst kob = new KangOpenBanking({ apiKey: process.env.KOB_API_KEY });\nconst res = await kob.request(\"POST\", \"/v1/banking/internal-transfer\", { /* payload */ });\nconsole.log(res);"
          },
          {
            "lang": "Python",
            "label": "Python",
            "source": "from kangopenbanking import KangOpenBanking\n\nkob = KangOpenBanking(api_key=os.environ[\"KOB_API_KEY\"])\nres = kob.request(\"POST\", \"/v1/banking/internal-transfer\", json={})\nprint(res)"
          },
          {
            "lang": "PHP",
            "label": "PHP",
            "source": "<?php\n$kob = new KangOpenBanking\\KangOpenBanking(getenv('KOB_API_KEY'));\n$res = $kob->request('POST', '/v1/banking/internal-transfer', []);\nprint_r($res);"
          }
        ]
      }
    },
    "/v1/banking/facilitated-transfer": {
      "post": {
        "tags": [
          "Banking Operations"
        ],
        "summary": "Institution-facilitated bank transfer",
        "description": "Initiate a bank payout facilitated by a financial institution through the Flutterwave rail. Includes KOB fee calculation and settlement tracking. The institution_id determines fee structure and settlement bucket.",
        "operationId": "bankingFacilitatedTransfer",
        "security": [
          {
            "bearerAuth": []
          }
        ],
        "parameters": [
          {
            "name": "Idempotency-Key",
            "in": "header",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid"
            },
            "description": "Required on all POST/PUT endpoints. Unique key for idempotent request processing (UUID v4 recommended). Keys expire after 24 hours."
          },
          {
            "$ref": "#/components/parameters/RequestId"
          },
          {
            "$ref": "#/components/parameters/Traceparent"
          },
          {
            "$ref": "#/components/parameters/Tracestate"
          },
          {
            "$ref": "#/components/parameters/AcceptLanguage"
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "required": [
                  "account_number",
                  "bank_code",
                  "amount",
                  "institution_id"
                ],
                "properties": {
                  "account_number": {
                    "type": "string",
                    "example": "1234567890"
                  },
                  "bank_code": {
                    "type": "string",
                    "example": "SGCM"
                  },
                  "bank_name": {
                    "type": "string",
                    "example": "Société Générale Cameroun"
                  },
                  "amount": {
                    "type": "string",
                    "example": "100000",
                    "pattern": "^[0-9]{1,15}$",
                    "description": "Represented as a string integer in the currency's minor unit (XAF has no subunits). Must be consistent with the currency field."
                  },
                  "currency": {
                    "type": "string",
                    "default": "XAF",
                    "enum": [
                      "XAF",
                      "XOF",
                      "USD",
                      "EUR",
                      "GBP",
                      "CNY",
                      "NGN",
                      "GHS",
                      "KES",
                      "ZAR"
                    ],
                    "description": "ISO 4217 currency code. Default is XAF (Central African CFA Franc)."
                  },
                  "narration": {
                    "type": "string",
                    "example": "Salary payment"
                  },
                  "institution_id": {
                    "type": "string",
                    "format": "uuid",
                    "description": "Facilitating institution"
                  },
                  "account_name": {
                    "type": "string",
                    "example": "Jean Dupont"
                  }
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Facilitated transfer initiated",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "id": {
                      "type": "string",
                      "format": "uuid"
                    },
                    "transaction_ref": {
                      "type": "string"
                    },
                    "amount": {
                      "type": "string",
                      "pattern": "^[0-9]{1,15}$",
                      "description": "Represented as a string integer in the currency's minor unit (XAF has no subunits). Must be consistent with the currency field."
                    },
                    "kob_fee_amount": {
                      "type": "number"
                    },
                    "currency": {
                      "type": "string",
                      "enum": [
                        "XAF",
                        "XOF",
                        "USD",
                        "EUR",
                        "GBP",
                        "CNY",
                        "NGN",
                        "GHS",
                        "KES",
                        "ZAR"
                      ],
                      "default": "XAF",
                      "description": "ISO 4217 currency code. Default is XAF (Central African CFA Franc)."
                    },
                    "status": {
                      "type": "string",
                      "enum": [
                        "pending",
                        "completed",
                        "failed"
                      ]
                    },
                    "bank_name": {
                      "type": "string"
                    },
                    "account_number": {
                      "type": "string"
                    },
                    "flutterwave_ref": {
                      "type": "string"
                    },
                    "created_at": {
                      "type": "string",
                      "format": "date-time"
                    }
                  }
                },
                "example": {
                  "id": "00000000-0000-4000-8000-000000000000",
                  "transaction_ref": "string",
                  "amount": "1000",
                  "kob_fee_amount": 0,
                  "currency": "XAF",
                  "status": "pending",
                  "bank_name": "string",
                  "account_number": "string",
                  "flutterwave_ref": "string",
                  "created_at": "2026-01-01T00:00:00Z"
                }
              }
            },
            "headers": {
              "x-fapi-interaction-id": {
                "$ref": "#/components/headers/XFapiInteractionIdResponse"
              },
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/XRateLimitLimit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/XRateLimitRemaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/XRateLimitReset"
              },
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              },
              "X-Idempotent-Replay": {
                "$ref": "#/components/headers/X-Idempotent-Replay"
              },
              "X-Idempotency-Status": {
                "$ref": "#/components/headers/X-Idempotency-Status"
              },
              "traceparent": {
                "$ref": "#/components/headers/Traceparent"
              },
              "Content-Language": {
                "$ref": "#/components/headers/Content-Language"
              }
            }
          },
          "400": {
            "description": "Bad request",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              },
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                },
                "examples": {
                  "error": {
                    "$ref": "#/components/examples/ErrorBadRequest"
                  }
                }
              }
            },
            "headers": {
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/XRateLimitLimit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/XRateLimitRemaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/XRateLimitReset"
              },
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "403": {
            "$ref": "#/components/responses/Forbidden",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "404": {
            "$ref": "#/components/responses/NotFound",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "409": {
            "$ref": "#/components/responses/Conflict",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "429": {
            "$ref": "#/components/responses/TooManyRequests",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "500": {
            "$ref": "#/components/responses/InternalServerError",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          }
        },
        "x-codeSamples": [
          {
            "lang": "cURL",
            "label": "cURL",
            "source": "curl -X POST \"https://api.kangopenbanking.com/v1/banking/facilitated-transfer\" \\\n  -H \"Authorization: Bearer $KOB_ACCESS_TOKEN\" \\\n  -H \"Content-Type: application/json\" \\\n  -d '{}'"
          },
          {
            "lang": "JavaScript",
            "label": "Node.js",
            "source": "import { KangOpenBanking } from \"@kangopenbanking/sdk\";\n\nconst kob = new KangOpenBanking({ apiKey: process.env.KOB_API_KEY });\nconst res = await kob.request(\"POST\", \"/v1/banking/facilitated-transfer\", { /* payload */ });\nconsole.log(res);"
          },
          {
            "lang": "Python",
            "label": "Python",
            "source": "from kangopenbanking import KangOpenBanking\n\nkob = KangOpenBanking(api_key=os.environ[\"KOB_API_KEY\"])\nres = kob.request(\"POST\", \"/v1/banking/facilitated-transfer\", json={})\nprint(res)"
          },
          {
            "lang": "PHP",
            "label": "PHP",
            "source": "<?php\n$kob = new KangOpenBanking\\KangOpenBanking(getenv('KOB_API_KEY'));\n$res = $kob->request('POST', '/v1/banking/facilitated-transfer', []);\nprint_r($res);"
          }
        ]
      }
    },
    "/v1/banking/facilitated-mobile-money-charge": {
      "post": {
        "tags": [
          "Payment Facilitation"
        ],
        "summary": "Facilitated mobile money collection",
        "description": "Initiate a mobile money charge using KOB's pre-verified Flutterwave account. The institution must have use_kob_flutterwave enabled. KOB fee is automatically calculated and the transaction is tagged for settlement.",
        "operationId": "facilitatedMobileMoneyCharge",
        "security": [
          {
            "bearerAuth": []
          }
        ],
        "parameters": [
          {
            "name": "Idempotency-Key",
            "in": "header",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid"
            },
            "description": "Required on all POST/PUT endpoints. Unique key for idempotent request processing (UUID v4 recommended). Keys expire after 24 hours."
          },
          {
            "$ref": "#/components/parameters/RequestId"
          },
          {
            "$ref": "#/components/parameters/Traceparent"
          },
          {
            "$ref": "#/components/parameters/Tracestate"
          },
          {
            "$ref": "#/components/parameters/AcceptLanguage"
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "required": [
                  "phone_number",
                  "amount"
                ],
                "properties": {
                  "phone_number": {
                    "type": "string",
                    "example": "237677123456",
                    "description": "Customer phone number (E.164)"
                  },
                  "amount": {
                    "type": "string",
                    "example": "5000",
                    "pattern": "^[0-9]{1,15}$",
                    "description": "Represented as a string integer in the currency's minor unit (XAF has no subunits). Must be consistent with the currency field."
                  },
                  "currency": {
                    "type": "string",
                    "default": "XAF",
                    "enum": [
                      "XAF",
                      "XOF",
                      "USD",
                      "EUR",
                      "GBP",
                      "CNY",
                      "NGN",
                      "GHS",
                      "KES",
                      "ZAR"
                    ],
                    "description": "ISO 4217 currency code. Default is XAF (Central African CFA Franc)."
                  },
                  "email": {
                    "type": "string",
                    "example": "customer@example.com"
                  },
                  "redirect_url": {
                    "type": "string",
                    "example": "https://yoursite.com/callback"
                  },
                  "metadata": {
                    "type": "object",
                    "example": {
                      "order_id": "ORD-12345"
                    }
                  }
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Mobile money charge initiated",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "success": {
                      "type": "boolean"
                    },
                    "transaction_ref": {
                      "type": "string"
                    },
                    "transaction_id": {
                      "type": "string",
                      "format": "uuid"
                    },
                    "flutterwave_link": {
                      "type": "string",
                      "description": "Payment link for customer redirect"
                    },
                    "kob_fee_amount": {
                      "type": "number"
                    },
                    "net_amount": {
                      "type": "number"
                    }
                  }
                },
                "example": {
                  "success": true,
                  "transaction_ref": "string",
                  "transaction_id": "00000000-0000-4000-8000-000000000000",
                  "flutterwave_link": "string",
                  "kob_fee_amount": 0,
                  "net_amount": 0
                }
              }
            },
            "headers": {
              "x-fapi-interaction-id": {
                "$ref": "#/components/headers/XFapiInteractionIdResponse"
              },
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/XRateLimitLimit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/XRateLimitRemaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/XRateLimitReset"
              },
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              },
              "X-Idempotent-Replay": {
                "$ref": "#/components/headers/X-Idempotent-Replay"
              },
              "X-Idempotency-Status": {
                "$ref": "#/components/headers/X-Idempotency-Status"
              },
              "traceparent": {
                "$ref": "#/components/headers/Traceparent"
              },
              "Content-Language": {
                "$ref": "#/components/headers/Content-Language"
              }
            }
          },
          "400": {
            "description": "Bad request",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              },
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                },
                "examples": {
                  "error": {
                    "$ref": "#/components/examples/ErrorBadRequest"
                  }
                }
              }
            },
            "headers": {
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/XRateLimitLimit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/XRateLimitRemaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/XRateLimitReset"
              },
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "403": {
            "$ref": "#/components/responses/Forbidden",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "404": {
            "$ref": "#/components/responses/NotFound",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "409": {
            "$ref": "#/components/responses/Conflict",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "422": {
            "description": "Provider declined or upstream validation error (normalized).",
            "content": {
              "application/problem+json": {
                "schema": {
                  "allOf": [
                    {
                      "$ref": "#/components/schemas/ProblemDetails"
                    },
                    {
                      "type": "object",
                      "properties": {
                        "provider_error": {
                          "$ref": "#/components/schemas/MobileMoneyProviderError"
                        }
                      }
                    }
                  ]
                },
                "examples": {
                  "insufficient_funds": {
                    "$ref": "#/components/examples/MobileMoneyInsufficientFunds"
                  }
                }
              }
            },
            "headers": {
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/XRateLimitLimit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/XRateLimitRemaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/XRateLimitReset"
              }
            }
          },
          "429": {
            "$ref": "#/components/responses/TooManyRequests",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "500": {
            "$ref": "#/components/responses/InternalServerError",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          }
        },
        "x-codeSamples": [
          {
            "lang": "cURL",
            "label": "cURL",
            "source": "curl -X POST \"https://api.kangopenbanking.com/v1/banking/facilitated-mobile-money-charge\" \\\n  -H \"Authorization: Bearer $KOB_ACCESS_TOKEN\" \\\n  -H \"Content-Type: application/json\" \\\n  -d '{}'"
          },
          {
            "lang": "JavaScript",
            "label": "Node.js",
            "source": "import { KangOpenBanking } from \"@kangopenbanking/sdk\";\n\nconst kob = new KangOpenBanking({ apiKey: process.env.KOB_API_KEY });\nconst res = await kob.request(\"POST\", \"/v1/banking/facilitated-mobile-money-charge\", { /* payload */ });\nconsole.log(res);"
          },
          {
            "lang": "Python",
            "label": "Python",
            "source": "from kangopenbanking import KangOpenBanking\n\nkob = KangOpenBanking(api_key=os.environ[\"KOB_API_KEY\"])\nres = kob.request(\"POST\", \"/v1/banking/facilitated-mobile-money-charge\", json={})\nprint(res)"
          },
          {
            "lang": "PHP",
            "label": "PHP",
            "source": "<?php\n$kob = new KangOpenBanking\\KangOpenBanking(getenv('KOB_API_KEY'));\n$res = $kob->request('POST', '/v1/banking/facilitated-mobile-money-charge', []);\nprint_r($res);"
          }
        ]
      }
    },
    "/v1/settlement/calculate": {
      "post": {
        "tags": [
          "Payment Facilitation"
        ],
        "summary": "Calculate settlement balance",
        "description": "Calculate the settlement balance for the authenticated institution over a given period. Returns total inflows, outflows, KOB fees, and net settlement amount with a breakdown by payment method.",
        "operationId": "settlementCalculate",
        "security": [
          {
            "bearerAuth": []
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "period_start": {
                    "type": "string",
                    "format": "date-time",
                    "description": "Start of period (defaults to first day of current month)"
                  },
                  "period_end": {
                    "type": "string",
                    "format": "date-time",
                    "description": "End of period (defaults to now)"
                  }
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Settlement balance calculated",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "success": {
                      "type": "boolean"
                    },
                    "institution_id": {
                      "type": "string",
                      "format": "uuid"
                    },
                    "institution_name": {
                      "type": "string"
                    },
                    "period_start": {
                      "type": "string"
                    },
                    "period_end": {
                      "type": "string"
                    },
                    "total_inflows": {
                      "type": "number"
                    },
                    "total_outflows": {
                      "type": "number"
                    },
                    "total_kob_fees": {
                      "type": "number"
                    },
                    "net_settlement_amount": {
                      "type": "number"
                    },
                    "transaction_count": {
                      "type": "integer"
                    },
                    "meets_minimum_threshold": {
                      "type": "boolean"
                    },
                    "can_settle": {
                      "type": "boolean"
                    },
                    "breakdown": {
                      "type": "object"
                    }
                  }
                },
                "example": {
                  "success": true,
                  "institution_id": "00000000-0000-4000-8000-000000000000",
                  "institution_name": "string",
                  "period_start": "string",
                  "period_end": "string",
                  "total_inflows": 0,
                  "total_outflows": 0,
                  "total_kob_fees": 0,
                  "net_settlement_amount": 0,
                  "transaction_count": 0,
                  "meets_minimum_threshold": true,
                  "can_settle": true,
                  "breakdown": {}
                }
              }
            },
            "headers": {
              "x-fapi-interaction-id": {
                "$ref": "#/components/headers/XFapiInteractionIdResponse"
              },
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/XRateLimitLimit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/XRateLimitRemaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/XRateLimitReset"
              },
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              },
              "X-Idempotent-Replay": {
                "$ref": "#/components/headers/X-Idempotent-Replay"
              },
              "X-Idempotency-Status": {
                "$ref": "#/components/headers/X-Idempotency-Status"
              },
              "traceparent": {
                "$ref": "#/components/headers/Traceparent"
              },
              "Content-Language": {
                "$ref": "#/components/headers/Content-Language"
              }
            }
          },
          "400": {
            "description": "Bad request",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              },
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                },
                "examples": {
                  "error": {
                    "$ref": "#/components/examples/ErrorBadRequest"
                  }
                }
              }
            },
            "headers": {
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/XRateLimitLimit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/XRateLimitRemaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/XRateLimitReset"
              },
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "403": {
            "$ref": "#/components/responses/Forbidden",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "404": {
            "$ref": "#/components/responses/NotFound",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "409": {
            "$ref": "#/components/responses/Conflict",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "429": {
            "$ref": "#/components/responses/TooManyRequests",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "500": {
            "$ref": "#/components/responses/InternalServerError",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          }
        },
        "parameters": [
          {
            "$ref": "#/components/parameters/IdempotencyKey"
          },
          {
            "$ref": "#/components/parameters/RequestId"
          },
          {
            "$ref": "#/components/parameters/Traceparent"
          },
          {
            "$ref": "#/components/parameters/Tracestate"
          },
          {
            "$ref": "#/components/parameters/AcceptLanguage"
          }
        ],
        "x-codeSamples": [
          {
            "lang": "cURL",
            "label": "cURL",
            "source": "curl -X POST \"https://api.kangopenbanking.com/v1/settlement/calculate\" \\\n  -H \"Authorization: Bearer $KOB_ACCESS_TOKEN\" \\\n  -H \"Content-Type: application/json\" \\\n  -d '{}'"
          },
          {
            "lang": "JavaScript",
            "label": "Node.js",
            "source": "import { KangOpenBanking } from \"@kangopenbanking/sdk\";\n\nconst kob = new KangOpenBanking({ apiKey: process.env.KOB_API_KEY });\nconst res = await kob.request(\"POST\", \"/v1/settlement/calculate\", { /* payload */ });\nconsole.log(res);"
          },
          {
            "lang": "Python",
            "label": "Python",
            "source": "from kangopenbanking import KangOpenBanking\n\nkob = KangOpenBanking(api_key=os.environ[\"KOB_API_KEY\"])\nres = kob.request(\"POST\", \"/v1/settlement/calculate\", json={})\nprint(res)"
          },
          {
            "lang": "PHP",
            "label": "PHP",
            "source": "<?php\n$kob = new KangOpenBanking\\KangOpenBanking(getenv('KOB_API_KEY'));\n$res = $kob->request('POST', '/v1/settlement/calculate', []);\nprint_r($res);"
          }
        ]
      }
    },
    "/v1/settlement/process": {
      "post": {
        "tags": [
          "Payment Facilitation"
        ],
        "summary": "Process settlement payout",
        "description": "Process a settlement payout for a facilitated institution. Admin-only. Debits the net settlement amount and transfers to the institution's configured bank or mobile money account via Flutterwave.",
        "operationId": "settlementProcess",
        "security": [
          {
            "bearerAuth": []
          }
        ],
        "parameters": [
          {
            "name": "Idempotency-Key",
            "in": "header",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid"
            },
            "description": "Required on all POST/PUT endpoints. Unique key for idempotent request processing (UUID v4 recommended). Keys expire after 24 hours."
          },
          {
            "$ref": "#/components/parameters/RequestId"
          },
          {
            "$ref": "#/components/parameters/Traceparent"
          },
          {
            "$ref": "#/components/parameters/Tracestate"
          },
          {
            "$ref": "#/components/parameters/AcceptLanguage"
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "required": [
                  "institution_id",
                  "period_start",
                  "period_end"
                ],
                "properties": {
                  "institution_id": {
                    "type": "string",
                    "format": "uuid"
                  },
                  "period_start": {
                    "type": "string",
                    "format": "date-time"
                  },
                  "period_end": {
                    "type": "string",
                    "format": "date-time"
                  }
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Settlement processed",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "success": {
                      "type": "boolean"
                    },
                    "settlement_id": {
                      "type": "string",
                      "format": "uuid"
                    },
                    "settlement_ref": {
                      "type": "string"
                    },
                    "net_amount": {
                      "type": "number"
                    },
                    "flutterwave_transfer_id": {
                      "type": "integer"
                    },
                    "status": {
                      "type": "string",
                      "enum": [
                        "processing",
                        "completed",
                        "failed"
                      ]
                    }
                  }
                },
                "example": {
                  "success": true,
                  "settlement_id": "00000000-0000-4000-8000-000000000000",
                  "settlement_ref": "string",
                  "net_amount": 0,
                  "flutterwave_transfer_id": 0,
                  "status": "processing"
                }
              }
            },
            "headers": {
              "x-fapi-interaction-id": {
                "$ref": "#/components/headers/XFapiInteractionIdResponse"
              },
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/XRateLimitLimit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/XRateLimitRemaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/XRateLimitReset"
              },
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              },
              "X-Idempotent-Replay": {
                "$ref": "#/components/headers/X-Idempotent-Replay"
              },
              "X-Idempotency-Status": {
                "$ref": "#/components/headers/X-Idempotency-Status"
              },
              "traceparent": {
                "$ref": "#/components/headers/Traceparent"
              },
              "Content-Language": {
                "$ref": "#/components/headers/Content-Language"
              }
            }
          },
          "400": {
            "description": "Bad request",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              },
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                },
                "examples": {
                  "error": {
                    "$ref": "#/components/examples/ErrorBadRequest"
                  }
                }
              }
            },
            "headers": {
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/XRateLimitLimit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/XRateLimitRemaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/XRateLimitReset"
              },
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "403": {
            "$ref": "#/components/responses/Forbidden",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "404": {
            "$ref": "#/components/responses/NotFound",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "409": {
            "$ref": "#/components/responses/Conflict",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "429": {
            "$ref": "#/components/responses/TooManyRequests",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "500": {
            "$ref": "#/components/responses/InternalServerError",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          }
        },
        "x-codeSamples": [
          {
            "lang": "cURL",
            "label": "cURL",
            "source": "curl -X POST \"https://api.kangopenbanking.com/v1/settlement/process\" \\\n  -H \"Authorization: Bearer $KOB_ACCESS_TOKEN\" \\\n  -H \"Content-Type: application/json\" \\\n  -d '{}'"
          },
          {
            "lang": "JavaScript",
            "label": "Node.js",
            "source": "import { KangOpenBanking } from \"@kangopenbanking/sdk\";\n\nconst kob = new KangOpenBanking({ apiKey: process.env.KOB_API_KEY });\nconst res = await kob.request(\"POST\", \"/v1/settlement/process\", { /* payload */ });\nconsole.log(res);"
          },
          {
            "lang": "Python",
            "label": "Python",
            "source": "from kangopenbanking import KangOpenBanking\n\nkob = KangOpenBanking(api_key=os.environ[\"KOB_API_KEY\"])\nres = kob.request(\"POST\", \"/v1/settlement/process\", json={})\nprint(res)"
          },
          {
            "lang": "PHP",
            "label": "PHP",
            "source": "<?php\n$kob = new KangOpenBanking\\KangOpenBanking(getenv('KOB_API_KEY'));\n$res = $kob->request('POST', '/v1/settlement/process', []);\nprint_r($res);"
          }
        ]
      }
    },
    "/v1/gateway/risk/score": {
      "post": {
        "tags": [
          "Payment Gateway"
        ],
        "summary": "Score transaction risk",
        "description": "Run velocity, amount-threshold, and pattern-anomaly checks against a proposed transaction. Returns a 0–100 risk score, flags, and recommended action (allow | flag_for_review | block).",
        "operationId": "gatewayRiskScore",
        "security": [
          {
            "bearerAuth": []
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "required": [
                  "merchant_id",
                  "amount",
                  "channel"
                ],
                "properties": {
                  "merchant_id": {
                    "type": "string",
                    "format": "uuid"
                  },
                  "amount": {
                    "type": "string",
                    "example": "500000",
                    "pattern": "^[0-9]{1,15}$",
                    "description": "Represented as a string integer in the currency's minor unit (XAF has no subunits). Must be consistent with the currency field."
                  },
                  "currency": {
                    "type": "string",
                    "default": "XAF",
                    "enum": [
                      "XAF",
                      "XOF",
                      "USD",
                      "EUR",
                      "GBP",
                      "CNY",
                      "NGN",
                      "GHS",
                      "KES",
                      "ZAR"
                    ],
                    "description": "ISO 4217 currency code. Default is XAF (Central African CFA Franc)."
                  },
                  "channel": {
                    "type": "string",
                    "enum": [
                      "mobile_money",
                      "card",
                      "bank_transfer",
                      "ussd"
                    ]
                  },
                  "customer_email": {
                    "type": "string"
                  },
                  "customer_phone": {
                    "type": "string"
                  },
                  "customer_ip": {
                    "type": "string"
                  },
                  "metadata": {
                    "type": "object"
                  }
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Risk assessment result",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "risk_score": {
                      "type": "integer",
                      "minimum": 0,
                      "maximum": 100,
                      "example": 35
                    },
                    "risk_level": {
                      "type": "string",
                      "enum": [
                        "low",
                        "medium",
                        "high",
                        "critical"
                      ]
                    },
                    "flags": {
                      "type": "array",
                      "items": {
                        "type": "string"
                      },
                      "example": [
                        "high_amount"
                      ]
                    },
                    "recommended_action": {
                      "type": "string",
                      "enum": [
                        "allow",
                        "flag_for_review",
                        "block"
                      ]
                    },
                    "checks": {
                      "type": "object",
                      "properties": {
                        "velocity": {
                          "type": "object",
                          "properties": {
                            "passed": {
                              "type": "boolean"
                            },
                            "tx_count_1h": {
                              "type": "integer"
                            },
                            "limit": {
                              "type": "integer"
                            }
                          }
                        },
                        "amount_threshold": {
                          "type": "object",
                          "properties": {
                            "passed": {
                              "type": "boolean"
                            },
                            "threshold": {
                              "type": "number"
                            }
                          }
                        },
                        "pattern_anomaly": {
                          "type": "object",
                          "properties": {
                            "passed": {
                              "type": "boolean"
                            },
                            "anomaly_type": {
                              "type": "string"
                            }
                          }
                        }
                      }
                    },
                    "evaluated_at": {
                      "type": "string",
                      "format": "date-time"
                    }
                  }
                },
                "example": {
                  "risk_score": 35,
                  "risk_level": "low",
                  "flags": [
                    "high_amount"
                  ],
                  "recommended_action": "allow",
                  "checks": {
                    "velocity": {
                      "passed": true,
                      "tx_count_1h": 0,
                      "limit": 0
                    },
                    "amount_threshold": {
                      "passed": true,
                      "threshold": 0
                    },
                    "pattern_anomaly": {
                      "passed": true,
                      "anomaly_type": "string"
                    }
                  },
                  "evaluated_at": "2026-01-01T00:00:00Z"
                }
              }
            },
            "headers": {
              "x-fapi-interaction-id": {
                "$ref": "#/components/headers/XFapiInteractionIdResponse"
              },
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/XRateLimitLimit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/XRateLimitRemaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/XRateLimitReset"
              },
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              },
              "traceparent": {
                "$ref": "#/components/headers/Traceparent"
              },
              "Content-Language": {
                "$ref": "#/components/headers/Content-Language"
              }
            }
          },
          "400": {
            "description": "Bad request",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              },
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                },
                "examples": {
                  "error": {
                    "$ref": "#/components/examples/ErrorBadRequest"
                  }
                }
              }
            },
            "headers": {
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/XRateLimitLimit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/XRateLimitRemaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/XRateLimitReset"
              },
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "403": {
            "$ref": "#/components/responses/Forbidden",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "404": {
            "$ref": "#/components/responses/NotFound",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "409": {
            "$ref": "#/components/responses/Conflict",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "429": {
            "$ref": "#/components/responses/TooManyRequests",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "500": {
            "$ref": "#/components/responses/InternalServerError",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          }
        },
        "parameters": [
          {
            "$ref": "#/components/parameters/RequestId"
          },
          {
            "$ref": "#/components/parameters/Traceparent"
          },
          {
            "$ref": "#/components/parameters/Tracestate"
          },
          {
            "$ref": "#/components/parameters/AcceptLanguage"
          }
        ],
        "x-codeSamples": [
          {
            "lang": "cURL",
            "label": "cURL",
            "source": "curl -X POST \"https://api.kangopenbanking.com/v1/gateway/risk/score\" \\\n  -H \"Authorization: Bearer $KOB_ACCESS_TOKEN\" \\\n  -H \"Content-Type: application/json\" \\\n  -d '{}'"
          },
          {
            "lang": "JavaScript",
            "label": "Node.js",
            "source": "import { KangOpenBanking } from \"@kangopenbanking/sdk\";\n\nconst kob = new KangOpenBanking({ apiKey: process.env.KOB_API_KEY });\nconst res = await kob.request(\"POST\", \"/v1/gateway/risk/score\", { /* payload */ });\nconsole.log(res);"
          },
          {
            "lang": "Python",
            "label": "Python",
            "source": "from kangopenbanking import KangOpenBanking\n\nkob = KangOpenBanking(api_key=os.environ[\"KOB_API_KEY\"])\nres = kob.request(\"POST\", \"/v1/gateway/risk/score\", json={})\nprint(res)"
          },
          {
            "lang": "PHP",
            "label": "PHP",
            "source": "<?php\n$kob = new KangOpenBanking\\KangOpenBanking(getenv('KOB_API_KEY'));\n$res = $kob->request('POST', '/v1/gateway/risk/score', []);\nprint_r($res);"
          }
        ]
      }
    },
    "/v1/gateway/exchange-rate": {
      "get": {
        "tags": [
          "Payment Gateway"
        ],
        "summary": "Get exchange rate",
        "description": "Look up real-time exchange rates for multi-currency charges and settlements. Powered by Frankfurter API.",
        "operationId": "gatewayExchangeRate",
        "security": [],
        "parameters": [
          {
            "name": "from",
            "in": "query",
            "required": true,
            "schema": {
              "type": "string",
              "example": "XAF"
            },
            "description": "Source currency (ISO 4217)"
          },
          {
            "name": "to",
            "in": "query",
            "required": true,
            "schema": {
              "type": "string",
              "example": "USD"
            },
            "description": "Target currency (ISO 4217)"
          },
          {
            "name": "amount",
            "in": "query",
            "schema": {
              "type": "number",
              "default": 1
            },
            "description": "Amount to convert"
          },
          {
            "$ref": "#/components/parameters/RequestId"
          },
          {
            "$ref": "#/components/parameters/Traceparent"
          },
          {
            "$ref": "#/components/parameters/Tracestate"
          },
          {
            "$ref": "#/components/parameters/AcceptLanguage"
          }
        ],
        "responses": {
          "200": {
            "description": "Exchange rate result",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "from": {
                      "type": "string",
                      "example": "XAF"
                    },
                    "to": {
                      "type": "string",
                      "example": "USD"
                    },
                    "rate": {
                      "type": "number",
                      "example": 0.0016
                    },
                    "amount": {
                      "type": "string",
                      "example": "100000",
                      "pattern": "^[0-9]{1,15}$",
                      "description": "Represented as a string integer in the currency's minor unit (XAF has no subunits)."
                    },
                    "converted": {
                      "type": "number",
                      "example": 160
                    },
                    "timestamp": {
                      "type": "string",
                      "format": "date-time"
                    },
                    "source": {
                      "type": "string",
                      "example": "frankfurter"
                    }
                  }
                },
                "example": {
                  "from": "XAF",
                  "to": "USD",
                  "rate": 0.0016,
                  "amount": "100000",
                  "converted": 160,
                  "timestamp": "2026-01-01T00:00:00Z",
                  "source": "frankfurter"
                }
              }
            },
            "headers": {
              "x-fapi-interaction-id": {
                "$ref": "#/components/headers/XFapiInteractionIdResponse"
              },
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/XRateLimitLimit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/XRateLimitRemaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/XRateLimitReset"
              },
              "Cache-Control": {
                "$ref": "#/components/headers/CacheControl"
              },
              "ETag": {
                "$ref": "#/components/headers/ETag"
              },
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              },
              "traceparent": {
                "$ref": "#/components/headers/Traceparent"
              },
              "Content-Language": {
                "$ref": "#/components/headers/Content-Language"
              }
            }
          },
          "400": {
            "description": "Bad request",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              },
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                },
                "examples": {
                  "error": {
                    "$ref": "#/components/examples/ErrorBadRequest"
                  }
                }
              }
            },
            "headers": {
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/XRateLimitLimit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/XRateLimitRemaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/XRateLimitReset"
              },
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "403": {
            "$ref": "#/components/responses/Forbidden",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "404": {
            "$ref": "#/components/responses/NotFound",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "409": {
            "$ref": "#/components/responses/Conflict",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "429": {
            "$ref": "#/components/responses/TooManyRequests",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "500": {
            "$ref": "#/components/responses/InternalServerError",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          }
        },
        "x-codeSamples": [
          {
            "lang": "cURL",
            "label": "cURL",
            "source": "curl -X GET \"https://api.kangopenbanking.com/v1/gateway/exchange-rate\" \\\n  -H \"Authorization: Bearer $KOB_ACCESS_TOKEN\" \\\n  -H \"Content-Type: application/json\""
          },
          {
            "lang": "JavaScript",
            "label": "Node.js",
            "source": "import { KangOpenBanking } from \"@kangopenbanking/sdk\";\n\nconst kob = new KangOpenBanking({ apiKey: process.env.KOB_API_KEY });\nconst res = await kob.request(\"GET\", \"/v1/gateway/exchange-rate\");\nconsole.log(res);"
          },
          {
            "lang": "Python",
            "label": "Python",
            "source": "from kangopenbanking import KangOpenBanking\n\nkob = KangOpenBanking(api_key=os.environ[\"KOB_API_KEY\"])\nres = kob.request(\"GET\", \"/v1/gateway/exchange-rate\")\nprint(res)"
          },
          {
            "lang": "PHP",
            "label": "PHP",
            "source": "<?php\n$kob = new KangOpenBanking\\KangOpenBanking(getenv('KOB_API_KEY'));\n$res = $kob->request('GET', '/v1/gateway/exchange-rate');\nprint_r($res);"
          }
        ]
      }
    },
    "/v1/gateway/payment-links": {
      "post": {
        "tags": [
          "Payment Gateway"
        ],
        "summary": "Create payment link",
        "operationId": "gatewayCreatePaymentLink",
        "security": [
          {
            "bearerAuth": []
          }
        ],
        "parameters": [
          {
            "name": "Idempotency-Key",
            "in": "header",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid"
            },
            "description": "Required on all POST/PUT endpoints. Unique key for idempotent request processing (UUID v4 recommended). Keys expire after 24 hours."
          },
          {
            "$ref": "#/components/parameters/RequestId"
          },
          {
            "$ref": "#/components/parameters/Traceparent"
          },
          {
            "$ref": "#/components/parameters/Tracestate"
          },
          {
            "$ref": "#/components/parameters/AcceptLanguage"
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "required": [
                  "merchant_id",
                  "name",
                  "amount"
                ],
                "properties": {
                  "merchant_id": {
                    "type": "string",
                    "format": "uuid"
                  },
                  "name": {
                    "type": "string"
                  },
                  "amount": {
                    "type": "string",
                    "pattern": "^[0-9]{1,15}$",
                    "description": "Represented as a string integer in the currency's minor unit (XAF has no subunits). Must be consistent with the currency field."
                  },
                  "currency": {
                    "type": "string",
                    "default": "XAF",
                    "enum": [
                      "XAF",
                      "XOF",
                      "USD",
                      "EUR",
                      "GBP",
                      "CNY",
                      "NGN",
                      "GHS",
                      "KES",
                      "ZAR"
                    ],
                    "description": "ISO 4217 currency code. Default is XAF (Central African CFA Franc)."
                  },
                  "redirect_url": {
                    "type": "string"
                  },
                  "max_uses": {
                    "type": "integer"
                  },
                  "expires_at": {
                    "type": "string",
                    "format": "date-time"
                  }
                }
              }
            }
          }
        },
        "responses": {
          "201": {
            "description": "Payment link created",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/GatewayPaymentLink"
                },
                "example": {
                  "id": "00000000-0000-4000-8000-000000000000",
                  "merchant_id": "00000000-0000-4000-8000-000000000000",
                  "name": "Product Payment",
                  "slug": "product-payment-abc123",
                  "amount": "5000",
                  "currency": "XAF",
                  "status": "active",
                  "redirect_url": "string",
                  "max_uses": 0,
                  "use_count": 0,
                  "expires_at": "2026-01-01T00:00:00Z",
                  "created_at": "2026-01-01T00:00:00Z"
                }
              }
            },
            "headers": {
              "x-fapi-interaction-id": {
                "$ref": "#/components/headers/XFapiInteractionIdResponse"
              },
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/XRateLimitLimit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/XRateLimitRemaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/XRateLimitReset"
              },
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              },
              "X-Idempotent-Replay": {
                "$ref": "#/components/headers/X-Idempotent-Replay"
              },
              "X-Idempotency-Status": {
                "$ref": "#/components/headers/X-Idempotency-Status"
              },
              "traceparent": {
                "$ref": "#/components/headers/Traceparent"
              },
              "Content-Language": {
                "$ref": "#/components/headers/Content-Language"
              }
            }
          },
          "400": {
            "description": "Bad request",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              },
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                },
                "examples": {
                  "error": {
                    "$ref": "#/components/examples/ErrorBadRequest"
                  }
                }
              }
            },
            "headers": {
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/XRateLimitLimit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/XRateLimitRemaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/XRateLimitReset"
              },
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "403": {
            "$ref": "#/components/responses/Forbidden",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "404": {
            "$ref": "#/components/responses/NotFound",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "409": {
            "$ref": "#/components/responses/Conflict",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "429": {
            "$ref": "#/components/responses/TooManyRequests",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "500": {
            "$ref": "#/components/responses/InternalServerError",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          }
        },
        "x-codeSamples": [
          {
            "lang": "cURL",
            "label": "cURL",
            "source": "curl -X POST \"https://api.kangopenbanking.com/v1/gateway/payment-links\" \\\n  -H \"Authorization: Bearer $KOB_ACCESS_TOKEN\" \\\n  -H \"Content-Type: application/json\" \\\n  -d '{}'"
          },
          {
            "lang": "JavaScript",
            "label": "Node.js",
            "source": "import { KangOpenBanking } from \"@kangopenbanking/sdk\";\n\nconst kob = new KangOpenBanking({ apiKey: process.env.KOB_API_KEY });\nconst res = await kob.request(\"POST\", \"/v1/gateway/payment-links\", { /* payload */ });\nconsole.log(res);"
          },
          {
            "lang": "Python",
            "label": "Python",
            "source": "from kangopenbanking import KangOpenBanking\n\nkob = KangOpenBanking(api_key=os.environ[\"KOB_API_KEY\"])\nres = kob.request(\"POST\", \"/v1/gateway/payment-links\", json={})\nprint(res)"
          },
          {
            "lang": "PHP",
            "label": "PHP",
            "source": "<?php\n$kob = new KangOpenBanking\\KangOpenBanking(getenv('KOB_API_KEY'));\n$res = $kob->request('POST', '/v1/gateway/payment-links', []);\nprint_r($res);"
          }
        ]
      },
      "get": {
        "tags": [
          "Payment Gateway"
        ],
        "summary": "List payment links",
        "operationId": "gatewayListPaymentLinks",
        "security": [
          {
            "bearerAuth": []
          }
        ],
        "parameters": [
          {
            "name": "merchant_id",
            "in": "query",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "slug",
            "in": "query",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "limit",
            "in": "query",
            "schema": {
              "type": "integer",
              "default": 25,
              "maximum": 100
            },
            "description": "Items per page"
          },
          {
            "name": "offset",
            "in": "query",
            "schema": {
              "type": "integer",
              "default": 0
            },
            "description": "Items to skip"
          },
          {
            "name": "sort_by",
            "in": "query",
            "schema": {
              "type": "string",
              "default": "created_at"
            },
            "description": "Sort field"
          },
          {
            "name": "sort_order",
            "in": "query",
            "schema": {
              "type": "string",
              "enum": [
                "asc",
                "desc"
              ],
              "default": "desc"
            },
            "description": "Sort direction"
          },
          {
            "$ref": "#/components/parameters/StartingAfter"
          },
          {
            "$ref": "#/components/parameters/EndingBefore"
          },
          {
            "$ref": "#/components/parameters/RequestId"
          },
          {
            "$ref": "#/components/parameters/Traceparent"
          },
          {
            "$ref": "#/components/parameters/Tracestate"
          },
          {
            "$ref": "#/components/parameters/AcceptLanguage"
          }
        ],
        "responses": {
          "200": {
            "description": "Payment links",
            "content": {
              "application/json": {
                "schema": {
                  "allOf": [
                    {
                      "$ref": "#/components/schemas/PaginatedResponse"
                    },
                    {
                      "type": "object",
                      "properties": {
                        "data": {
                          "type": "array",
                          "items": {
                            "$ref": "#/components/schemas/GatewayPaymentLink"
                          }
                        }
                      }
                    }
                  ]
                },
                "example": {
                  "data": [
                    {
                      "id": "f1d6f4a0-1d4e-4a3a-9e0a-1a2b3c4d5e6f",
                      "merchant_id": "f1d6f4a0-1d4e-4a3a-9e0a-1a2b3c4d5e6f",
                      "name": "Product Payment",
                      "slug": "product-payment-abc123",
                      "amount": "5000",
                      "currency": "XAF",
                      "status": "active",
                      "redirect_url": "XAF",
                      "max_uses": 1,
                      "use_count": 1,
                      "expires_at": "2026-01-31T12:00:00Z",
                      "created_at": "2026-01-31T12:00:00Z"
                    }
                  ],
                  "pagination": {
                    "page": 1,
                    "limit": 20,
                    "total": 150,
                    "has_next": true,
                    "next_cursor": "eyJpZCI6IjEyMyJ9"
                  },
                  "meta": {
                    "request_id": "550e8400-e29b-41d4-a716-446655440000",
                    "timestamp": "2025-03-27T12:00:00Z",
                    "api_version": "4.3.0"
                  }
                }
              }
            },
            "headers": {
              "x-fapi-interaction-id": {
                "$ref": "#/components/headers/XFapiInteractionIdResponse"
              },
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/XRateLimitLimit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/XRateLimitRemaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/XRateLimitReset"
              },
              "Cache-Control": {
                "$ref": "#/components/headers/CacheControl"
              },
              "ETag": {
                "$ref": "#/components/headers/ETag"
              },
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              },
              "traceparent": {
                "$ref": "#/components/headers/Traceparent"
              },
              "Content-Language": {
                "$ref": "#/components/headers/Content-Language"
              }
            }
          },
          "400": {
            "description": "Bad request",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              },
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                },
                "examples": {
                  "error": {
                    "$ref": "#/components/examples/ErrorBadRequest"
                  }
                }
              }
            },
            "headers": {
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/XRateLimitLimit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/XRateLimitRemaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/XRateLimitReset"
              },
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "403": {
            "$ref": "#/components/responses/Forbidden",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "404": {
            "$ref": "#/components/responses/NotFound",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "409": {
            "$ref": "#/components/responses/Conflict",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "429": {
            "$ref": "#/components/responses/TooManyRequests",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "500": {
            "$ref": "#/components/responses/InternalServerError",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          }
        },
        "x-codeSamples": [
          {
            "lang": "cURL",
            "label": "cURL",
            "source": "curl -X GET \"https://api.kangopenbanking.com/v1/gateway/payment-links\" \\\n  -H \"Authorization: Bearer $KOB_ACCESS_TOKEN\" \\\n  -H \"Content-Type: application/json\""
          },
          {
            "lang": "JavaScript",
            "label": "Node.js",
            "source": "import { KangOpenBanking } from \"@kangopenbanking/sdk\";\n\nconst kob = new KangOpenBanking({ apiKey: process.env.KOB_API_KEY });\nconst res = await kob.request(\"GET\", \"/v1/gateway/payment-links\");\nconsole.log(res);"
          },
          {
            "lang": "Python",
            "label": "Python",
            "source": "from kangopenbanking import KangOpenBanking\n\nkob = KangOpenBanking(api_key=os.environ[\"KOB_API_KEY\"])\nres = kob.request(\"GET\", \"/v1/gateway/payment-links\")\nprint(res)"
          },
          {
            "lang": "PHP",
            "label": "PHP",
            "source": "<?php\n$kob = new KangOpenBanking\\KangOpenBanking(getenv('KOB_API_KEY'));\n$res = $kob->request('GET', '/v1/gateway/payment-links');\nprint_r($res);"
          }
        ]
      }
    },
    "/v1/gateway/payment-links/{linkId}": {
      "put": {
        "tags": [
          "Payment Gateway"
        ],
        "summary": "Update payment link",
        "operationId": "gatewayUpdatePaymentLink",
        "security": [
          {
            "bearerAuth": []
          }
        ],
        "parameters": [
          {
            "name": "linkId",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "$ref": "#/components/parameters/IdempotencyKey"
          },
          {
            "$ref": "#/components/parameters/RequestId"
          },
          {
            "$ref": "#/components/parameters/Traceparent"
          },
          {
            "$ref": "#/components/parameters/Tracestate"
          },
          {
            "$ref": "#/components/parameters/AcceptLanguage"
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "name": {
                    "type": "string"
                  },
                  "amount": {
                    "type": "string",
                    "pattern": "^[0-9]{1,15}$",
                    "description": "Represented as a string integer in the currency's minor unit (XAF has no subunits)."
                  },
                  "status": {
                    "type": "string"
                  },
                  "redirect_url": {
                    "type": "string"
                  }
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Payment link updated",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/GatewayPaymentLink"
                },
                "example": {
                  "id": "00000000-0000-4000-8000-000000000000",
                  "merchant_id": "00000000-0000-4000-8000-000000000000",
                  "name": "Product Payment",
                  "slug": "product-payment-abc123",
                  "amount": "5000",
                  "currency": "XAF",
                  "status": "active",
                  "redirect_url": "string",
                  "max_uses": 0,
                  "use_count": 0,
                  "expires_at": "2026-01-01T00:00:00Z",
                  "created_at": "2026-01-01T00:00:00Z"
                }
              }
            },
            "headers": {
              "x-fapi-interaction-id": {
                "$ref": "#/components/headers/XFapiInteractionIdResponse"
              },
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/XRateLimitLimit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/XRateLimitRemaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/XRateLimitReset"
              },
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              },
              "X-Idempotent-Replay": {
                "$ref": "#/components/headers/X-Idempotent-Replay"
              },
              "X-Idempotency-Status": {
                "$ref": "#/components/headers/X-Idempotency-Status"
              },
              "traceparent": {
                "$ref": "#/components/headers/Traceparent"
              },
              "Content-Language": {
                "$ref": "#/components/headers/Content-Language"
              }
            }
          },
          "400": {
            "description": "Bad request",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              },
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                },
                "examples": {
                  "error": {
                    "$ref": "#/components/examples/ErrorBadRequest"
                  }
                }
              }
            },
            "headers": {
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/XRateLimitLimit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/XRateLimitRemaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/XRateLimitReset"
              },
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "403": {
            "$ref": "#/components/responses/Forbidden",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "404": {
            "$ref": "#/components/responses/NotFound",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "409": {
            "$ref": "#/components/responses/Conflict",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "429": {
            "$ref": "#/components/responses/TooManyRequests",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "500": {
            "$ref": "#/components/responses/InternalServerError",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          }
        },
        "x-codeSamples": [
          {
            "lang": "cURL",
            "label": "cURL",
            "source": "curl -X PUT \"https://api.kangopenbanking.com/v1/gateway/payment-links/{linkId}\" \\\n  -H \"Authorization: Bearer $KOB_ACCESS_TOKEN\" \\\n  -H \"Content-Type: application/json\" \\\n  -d '{}'"
          },
          {
            "lang": "JavaScript",
            "label": "Node.js",
            "source": "import { KangOpenBanking } from \"@kangopenbanking/sdk\";\n\nconst kob = new KangOpenBanking({ apiKey: process.env.KOB_API_KEY });\nconst res = await kob.request(\"PUT\", \"/v1/gateway/payment-links/{linkId}\", { /* payload */ });\nconsole.log(res);"
          },
          {
            "lang": "Python",
            "label": "Python",
            "source": "from kangopenbanking import KangOpenBanking\n\nkob = KangOpenBanking(api_key=os.environ[\"KOB_API_KEY\"])\nres = kob.request(\"PUT\", \"/v1/gateway/payment-links/{linkId}\", json={})\nprint(res)"
          },
          {
            "lang": "PHP",
            "label": "PHP",
            "source": "<?php\n$kob = new KangOpenBanking\\KangOpenBanking(getenv('KOB_API_KEY'));\n$res = $kob->request('PUT', '/v1/gateway/payment-links/{linkId}', []);\nprint_r($res);"
          }
        ]
      },
      "delete": {
        "tags": [
          "Payment Gateway"
        ],
        "summary": "Delete payment link",
        "operationId": "gatewayDeletePaymentLink",
        "security": [
          {
            "bearerAuth": []
          }
        ],
        "parameters": [
          {
            "name": "linkId",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "$ref": "#/components/parameters/RequestId"
          },
          {
            "$ref": "#/components/parameters/Traceparent"
          },
          {
            "$ref": "#/components/parameters/Tracestate"
          },
          {
            "$ref": "#/components/parameters/AcceptLanguage"
          }
        ],
        "responses": {
          "204": {
            "description": "Payment link deleted",
            "headers": {
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/XRateLimitLimit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/XRateLimitRemaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/XRateLimitReset"
              },
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              },
              "traceparent": {
                "$ref": "#/components/headers/Traceparent"
              },
              "Content-Language": {
                "$ref": "#/components/headers/Content-Language"
              }
            }
          },
          "400": {
            "description": "Bad request",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              },
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                },
                "examples": {
                  "error": {
                    "$ref": "#/components/examples/ErrorBadRequest"
                  }
                }
              }
            },
            "headers": {
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/XRateLimitLimit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/XRateLimitRemaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/XRateLimitReset"
              },
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "403": {
            "$ref": "#/components/responses/Forbidden",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "404": {
            "$ref": "#/components/responses/NotFound",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "409": {
            "$ref": "#/components/responses/Conflict",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "429": {
            "$ref": "#/components/responses/TooManyRequests",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "500": {
            "$ref": "#/components/responses/InternalServerError",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          }
        },
        "x-codeSamples": [
          {
            "lang": "cURL",
            "label": "cURL",
            "source": "curl -X DELETE \"https://api.kangopenbanking.com/v1/gateway/payment-links/{linkId}\" \\\n  -H \"Authorization: Bearer $KOB_ACCESS_TOKEN\" \\\n  -H \"Content-Type: application/json\""
          },
          {
            "lang": "JavaScript",
            "label": "Node.js",
            "source": "import { KangOpenBanking } from \"@kangopenbanking/sdk\";\n\nconst kob = new KangOpenBanking({ apiKey: process.env.KOB_API_KEY });\nconst res = await kob.request(\"DELETE\", \"/v1/gateway/payment-links/{linkId}\");\nconsole.log(res);"
          },
          {
            "lang": "Python",
            "label": "Python",
            "source": "from kangopenbanking import KangOpenBanking\n\nkob = KangOpenBanking(api_key=os.environ[\"KOB_API_KEY\"])\nres = kob.request(\"DELETE\", \"/v1/gateway/payment-links/{linkId}\")\nprint(res)"
          },
          {
            "lang": "PHP",
            "label": "PHP",
            "source": "<?php\n$kob = new KangOpenBanking\\KangOpenBanking(getenv('KOB_API_KEY'));\n$res = $kob->request('DELETE', '/v1/gateway/payment-links/{linkId}');\nprint_r($res);"
          }
        ]
      }
    },
    "/v1/gateway/payment-plans": {
      "post": {
        "tags": [
          "Payment Gateway"
        ],
        "summary": "Create payment plan",
        "operationId": "gatewayCreatePaymentPlan",
        "security": [
          {
            "bearerAuth": []
          }
        ],
        "parameters": [
          {
            "name": "Idempotency-Key",
            "in": "header",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid"
            },
            "description": "Required on all POST/PUT endpoints. Unique key for idempotent request processing (UUID v4 recommended). Keys expire after 24 hours."
          },
          {
            "$ref": "#/components/parameters/RequestId"
          },
          {
            "$ref": "#/components/parameters/Traceparent"
          },
          {
            "$ref": "#/components/parameters/Tracestate"
          },
          {
            "$ref": "#/components/parameters/AcceptLanguage"
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "required": [
                  "merchant_id",
                  "name",
                  "amount",
                  "interval"
                ],
                "properties": {
                  "merchant_id": {
                    "type": "string",
                    "format": "uuid"
                  },
                  "name": {
                    "type": "string"
                  },
                  "amount": {
                    "type": "string",
                    "pattern": "^[0-9]{1,15}$",
                    "description": "Represented as a string integer in the currency's minor unit (XAF has no subunits). Must be consistent with the currency field."
                  },
                  "currency": {
                    "type": "string",
                    "default": "XAF",
                    "enum": [
                      "XAF",
                      "XOF",
                      "USD",
                      "EUR",
                      "GBP",
                      "CNY",
                      "NGN",
                      "GHS",
                      "KES",
                      "ZAR"
                    ],
                    "description": "ISO 4217 currency code. Default is XAF (Central African CFA Franc)."
                  },
                  "interval": {
                    "type": "string",
                    "enum": [
                      "daily",
                      "weekly",
                      "monthly",
                      "quarterly",
                      "yearly"
                    ]
                  },
                  "duration": {
                    "type": "integer"
                  }
                }
              }
            }
          }
        },
        "responses": {
          "201": {
            "description": "Plan created",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/GatewayPaymentPlan"
                },
                "example": {
                  "id": "00000000-0000-4000-8000-000000000000",
                  "merchant_id": "00000000-0000-4000-8000-000000000000",
                  "name": "Monthly Pro Plan",
                  "amount": "10000",
                  "currency": "XAF",
                  "interval": "daily",
                  "duration": 0,
                  "status": "active",
                  "created_at": "2026-01-01T00:00:00Z"
                }
              }
            },
            "headers": {
              "x-fapi-interaction-id": {
                "$ref": "#/components/headers/XFapiInteractionIdResponse"
              },
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/XRateLimitLimit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/XRateLimitRemaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/XRateLimitReset"
              },
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              },
              "X-Idempotent-Replay": {
                "$ref": "#/components/headers/X-Idempotent-Replay"
              },
              "X-Idempotency-Status": {
                "$ref": "#/components/headers/X-Idempotency-Status"
              },
              "traceparent": {
                "$ref": "#/components/headers/Traceparent"
              },
              "Content-Language": {
                "$ref": "#/components/headers/Content-Language"
              }
            }
          },
          "400": {
            "description": "Bad request",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              },
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                },
                "examples": {
                  "error": {
                    "$ref": "#/components/examples/ErrorBadRequest"
                  }
                }
              }
            },
            "headers": {
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/XRateLimitLimit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/XRateLimitRemaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/XRateLimitReset"
              },
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "403": {
            "$ref": "#/components/responses/Forbidden",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "404": {
            "$ref": "#/components/responses/NotFound",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "409": {
            "$ref": "#/components/responses/Conflict",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "429": {
            "$ref": "#/components/responses/TooManyRequests",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "500": {
            "$ref": "#/components/responses/InternalServerError",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          }
        },
        "x-codeSamples": [
          {
            "lang": "cURL",
            "label": "cURL",
            "source": "curl -X POST \"https://api.kangopenbanking.com/v1/gateway/payment-plans\" \\\n  -H \"Authorization: Bearer $KOB_ACCESS_TOKEN\" \\\n  -H \"Content-Type: application/json\" \\\n  -d '{}'"
          },
          {
            "lang": "JavaScript",
            "label": "Node.js",
            "source": "import { KangOpenBanking } from \"@kangopenbanking/sdk\";\n\nconst kob = new KangOpenBanking({ apiKey: process.env.KOB_API_KEY });\nconst res = await kob.request(\"POST\", \"/v1/gateway/payment-plans\", { /* payload */ });\nconsole.log(res);"
          },
          {
            "lang": "Python",
            "label": "Python",
            "source": "from kangopenbanking import KangOpenBanking\n\nkob = KangOpenBanking(api_key=os.environ[\"KOB_API_KEY\"])\nres = kob.request(\"POST\", \"/v1/gateway/payment-plans\", json={})\nprint(res)"
          },
          {
            "lang": "PHP",
            "label": "PHP",
            "source": "<?php\n$kob = new KangOpenBanking\\KangOpenBanking(getenv('KOB_API_KEY'));\n$res = $kob->request('POST', '/v1/gateway/payment-plans', []);\nprint_r($res);"
          }
        ]
      },
      "get": {
        "tags": [
          "Payment Gateway"
        ],
        "summary": "List payment plans",
        "operationId": "gatewayListPaymentPlans",
        "security": [
          {
            "bearerAuth": []
          }
        ],
        "parameters": [
          {
            "name": "merchant_id",
            "in": "query",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "limit",
            "in": "query",
            "schema": {
              "type": "integer",
              "default": 25,
              "maximum": 100
            },
            "description": "Items per page"
          },
          {
            "name": "offset",
            "in": "query",
            "schema": {
              "type": "integer",
              "default": 0
            },
            "description": "Items to skip"
          },
          {
            "name": "sort_by",
            "in": "query",
            "schema": {
              "type": "string",
              "default": "created_at"
            },
            "description": "Sort field"
          },
          {
            "name": "sort_order",
            "in": "query",
            "schema": {
              "type": "string",
              "enum": [
                "asc",
                "desc"
              ],
              "default": "desc"
            },
            "description": "Sort direction"
          },
          {
            "$ref": "#/components/parameters/StartingAfter"
          },
          {
            "$ref": "#/components/parameters/EndingBefore"
          },
          {
            "$ref": "#/components/parameters/RequestId"
          },
          {
            "$ref": "#/components/parameters/Traceparent"
          },
          {
            "$ref": "#/components/parameters/Tracestate"
          },
          {
            "$ref": "#/components/parameters/AcceptLanguage"
          }
        ],
        "responses": {
          "200": {
            "description": "Payment plans",
            "content": {
              "application/json": {
                "schema": {
                  "allOf": [
                    {
                      "$ref": "#/components/schemas/PaginatedResponse"
                    },
                    {
                      "type": "object",
                      "properties": {
                        "data": {
                          "type": "array",
                          "items": {
                            "$ref": "#/components/schemas/GatewayPaymentPlan"
                          }
                        }
                      }
                    }
                  ]
                },
                "example": {
                  "data": [
                    {
                      "id": "f1d6f4a0-1d4e-4a3a-9e0a-1a2b3c4d5e6f",
                      "merchant_id": "f1d6f4a0-1d4e-4a3a-9e0a-1a2b3c4d5e6f",
                      "name": "Monthly Pro Plan",
                      "amount": "10000",
                      "currency": "XAF",
                      "interval": "daily",
                      "duration": 1,
                      "status": "active",
                      "created_at": "2026-01-31T12:00:00Z"
                    }
                  ],
                  "pagination": {
                    "page": 1,
                    "limit": 20,
                    "total": 150,
                    "has_next": true,
                    "next_cursor": "eyJpZCI6IjEyMyJ9"
                  },
                  "meta": {
                    "request_id": "550e8400-e29b-41d4-a716-446655440000",
                    "timestamp": "2025-03-27T12:00:00Z",
                    "api_version": "4.3.0"
                  }
                }
              }
            },
            "headers": {
              "x-fapi-interaction-id": {
                "$ref": "#/components/headers/XFapiInteractionIdResponse"
              },
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/XRateLimitLimit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/XRateLimitRemaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/XRateLimitReset"
              },
              "Cache-Control": {
                "$ref": "#/components/headers/CacheControl"
              },
              "ETag": {
                "$ref": "#/components/headers/ETag"
              },
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              },
              "traceparent": {
                "$ref": "#/components/headers/Traceparent"
              },
              "Content-Language": {
                "$ref": "#/components/headers/Content-Language"
              }
            }
          },
          "400": {
            "description": "Bad request",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              },
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                },
                "examples": {
                  "error": {
                    "$ref": "#/components/examples/ErrorBadRequest"
                  }
                }
              }
            },
            "headers": {
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/XRateLimitLimit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/XRateLimitRemaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/XRateLimitReset"
              },
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "403": {
            "$ref": "#/components/responses/Forbidden",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "404": {
            "$ref": "#/components/responses/NotFound",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "409": {
            "$ref": "#/components/responses/Conflict",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "429": {
            "$ref": "#/components/responses/TooManyRequests",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "500": {
            "$ref": "#/components/responses/InternalServerError",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          }
        },
        "x-codeSamples": [
          {
            "lang": "cURL",
            "label": "cURL",
            "source": "curl -X GET \"https://api.kangopenbanking.com/v1/gateway/payment-plans\" \\\n  -H \"Authorization: Bearer $KOB_ACCESS_TOKEN\" \\\n  -H \"Content-Type: application/json\""
          },
          {
            "lang": "JavaScript",
            "label": "Node.js",
            "source": "import { KangOpenBanking } from \"@kangopenbanking/sdk\";\n\nconst kob = new KangOpenBanking({ apiKey: process.env.KOB_API_KEY });\nconst res = await kob.request(\"GET\", \"/v1/gateway/payment-plans\");\nconsole.log(res);"
          },
          {
            "lang": "Python",
            "label": "Python",
            "source": "from kangopenbanking import KangOpenBanking\n\nkob = KangOpenBanking(api_key=os.environ[\"KOB_API_KEY\"])\nres = kob.request(\"GET\", \"/v1/gateway/payment-plans\")\nprint(res)"
          },
          {
            "lang": "PHP",
            "label": "PHP",
            "source": "<?php\n$kob = new KangOpenBanking\\KangOpenBanking(getenv('KOB_API_KEY'));\n$res = $kob->request('GET', '/v1/gateway/payment-plans');\nprint_r($res);"
          }
        ]
      }
    },
    "/v1/gateway/payment-plans/{planId}": {
      "get": {
        "tags": [
          "Payment Gateway"
        ],
        "summary": "Get payment plan",
        "operationId": "gatewayGetPaymentPlan",
        "security": [
          {
            "bearerAuth": []
          }
        ],
        "parameters": [
          {
            "name": "planId",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "$ref": "#/components/parameters/RequestId"
          },
          {
            "$ref": "#/components/parameters/Traceparent"
          },
          {
            "$ref": "#/components/parameters/Tracestate"
          },
          {
            "$ref": "#/components/parameters/AcceptLanguage"
          }
        ],
        "responses": {
          "200": {
            "description": "Plan details",
            "content": {
              "application/json": {
                "schema": {
                  "allOf": [
                    {
                      "$ref": "#/components/schemas/StandardResponse"
                    },
                    {
                      "type": "object",
                      "properties": {
                        "data": {
                          "$ref": "#/components/schemas/GatewayPaymentPlan"
                        }
                      }
                    }
                  ]
                },
                "example": {
                  "data": {
                    "id": "00000000-0000-4000-8000-000000000000",
                    "merchant_id": "00000000-0000-4000-8000-000000000000",
                    "name": "Monthly Pro Plan",
                    "amount": "10000",
                    "currency": "XAF",
                    "interval": "daily",
                    "duration": 0,
                    "status": "active",
                    "created_at": "2026-01-01T00:00:00Z"
                  },
                  "meta": {
                    "request_id": "550e8400-e29b-41d4-a716-446655440000",
                    "timestamp": "2025-03-27T12:00:00Z",
                    "api_version": "4.3.0"
                  }
                }
              }
            },
            "headers": {
              "x-fapi-interaction-id": {
                "$ref": "#/components/headers/XFapiInteractionIdResponse"
              },
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/XRateLimitLimit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/XRateLimitRemaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/XRateLimitReset"
              },
              "Cache-Control": {
                "$ref": "#/components/headers/CacheControl"
              },
              "ETag": {
                "$ref": "#/components/headers/ETag"
              },
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              },
              "traceparent": {
                "$ref": "#/components/headers/Traceparent"
              },
              "Content-Language": {
                "$ref": "#/components/headers/Content-Language"
              }
            }
          },
          "400": {
            "description": "Bad request",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              },
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                },
                "examples": {
                  "error": {
                    "$ref": "#/components/examples/ErrorBadRequest"
                  }
                }
              }
            },
            "headers": {
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/XRateLimitLimit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/XRateLimitRemaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/XRateLimitReset"
              },
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "403": {
            "$ref": "#/components/responses/Forbidden",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "404": {
            "$ref": "#/components/responses/NotFound",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "409": {
            "$ref": "#/components/responses/Conflict",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "429": {
            "$ref": "#/components/responses/TooManyRequests",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "500": {
            "$ref": "#/components/responses/InternalServerError",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          }
        },
        "x-codeSamples": [
          {
            "lang": "cURL",
            "label": "cURL",
            "source": "curl -X GET \"https://api.kangopenbanking.com/v1/gateway/payment-plans/{planId}\" \\\n  -H \"Authorization: Bearer $KOB_ACCESS_TOKEN\" \\\n  -H \"Content-Type: application/json\""
          },
          {
            "lang": "JavaScript",
            "label": "Node.js",
            "source": "import { KangOpenBanking } from \"@kangopenbanking/sdk\";\n\nconst kob = new KangOpenBanking({ apiKey: process.env.KOB_API_KEY });\nconst res = await kob.request(\"GET\", \"/v1/gateway/payment-plans/{planId}\");\nconsole.log(res);"
          },
          {
            "lang": "Python",
            "label": "Python",
            "source": "from kangopenbanking import KangOpenBanking\n\nkob = KangOpenBanking(api_key=os.environ[\"KOB_API_KEY\"])\nres = kob.request(\"GET\", \"/v1/gateway/payment-plans/{planId}\")\nprint(res)"
          },
          {
            "lang": "PHP",
            "label": "PHP",
            "source": "<?php\n$kob = new KangOpenBanking\\KangOpenBanking(getenv('KOB_API_KEY'));\n$res = $kob->request('GET', '/v1/gateway/payment-plans/{planId}');\nprint_r($res);"
          }
        ]
      },
      "put": {
        "tags": [
          "Payment Gateway"
        ],
        "summary": "Update payment plan",
        "operationId": "gatewayUpdatePaymentPlan",
        "security": [
          {
            "bearerAuth": []
          }
        ],
        "parameters": [
          {
            "name": "planId",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "$ref": "#/components/parameters/RequestId"
          },
          {
            "$ref": "#/components/parameters/Traceparent"
          },
          {
            "$ref": "#/components/parameters/Tracestate"
          },
          {
            "$ref": "#/components/parameters/AcceptLanguage"
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "name": {
                    "type": "string"
                  },
                  "amount": {
                    "type": "string",
                    "pattern": "^[0-9]{1,15}$",
                    "description": "Represented as a string integer in the currency's minor unit (XAF has no subunits)."
                  },
                  "status": {
                    "type": "string"
                  }
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Plan updated",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/GatewayPaymentPlan"
                },
                "example": {
                  "id": "00000000-0000-4000-8000-000000000000",
                  "merchant_id": "00000000-0000-4000-8000-000000000000",
                  "name": "Monthly Pro Plan",
                  "amount": "10000",
                  "currency": "XAF",
                  "interval": "daily",
                  "duration": 0,
                  "status": "active",
                  "created_at": "2026-01-01T00:00:00Z"
                }
              }
            },
            "headers": {
              "x-fapi-interaction-id": {
                "$ref": "#/components/headers/XFapiInteractionIdResponse"
              },
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/XRateLimitLimit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/XRateLimitRemaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/XRateLimitReset"
              },
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              },
              "traceparent": {
                "$ref": "#/components/headers/Traceparent"
              },
              "Content-Language": {
                "$ref": "#/components/headers/Content-Language"
              }
            }
          },
          "400": {
            "description": "Bad request",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              },
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                },
                "examples": {
                  "error": {
                    "$ref": "#/components/examples/ErrorBadRequest"
                  }
                }
              }
            },
            "headers": {
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/XRateLimitLimit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/XRateLimitRemaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/XRateLimitReset"
              },
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "403": {
            "$ref": "#/components/responses/Forbidden",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "404": {
            "$ref": "#/components/responses/NotFound",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "409": {
            "$ref": "#/components/responses/Conflict",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "429": {
            "$ref": "#/components/responses/TooManyRequests",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "500": {
            "$ref": "#/components/responses/InternalServerError",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          }
        },
        "x-codeSamples": [
          {
            "lang": "cURL",
            "label": "cURL",
            "source": "curl -X PUT \"https://api.kangopenbanking.com/v1/gateway/payment-plans/{planId}\" \\\n  -H \"Authorization: Bearer $KOB_ACCESS_TOKEN\" \\\n  -H \"Content-Type: application/json\" \\\n  -d '{}'"
          },
          {
            "lang": "JavaScript",
            "label": "Node.js",
            "source": "import { KangOpenBanking } from \"@kangopenbanking/sdk\";\n\nconst kob = new KangOpenBanking({ apiKey: process.env.KOB_API_KEY });\nconst res = await kob.request(\"PUT\", \"/v1/gateway/payment-plans/{planId}\", { /* payload */ });\nconsole.log(res);"
          },
          {
            "lang": "Python",
            "label": "Python",
            "source": "from kangopenbanking import KangOpenBanking\n\nkob = KangOpenBanking(api_key=os.environ[\"KOB_API_KEY\"])\nres = kob.request(\"PUT\", \"/v1/gateway/payment-plans/{planId}\", json={})\nprint(res)"
          },
          {
            "lang": "PHP",
            "label": "PHP",
            "source": "<?php\n$kob = new KangOpenBanking\\KangOpenBanking(getenv('KOB_API_KEY'));\n$res = $kob->request('PUT', '/v1/gateway/payment-plans/{planId}', []);\nprint_r($res);"
          }
        ]
      }
    },
    "/v1/gateway/subscriptions": {
      "post": {
        "tags": [
          "Payment Gateway"
        ],
        "summary": "Create subscription",
        "operationId": "gatewayCreateSubscription",
        "security": [
          {
            "bearerAuth": []
          }
        ],
        "parameters": [
          {
            "name": "Idempotency-Key",
            "in": "header",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid"
            },
            "description": "Required on all POST/PUT endpoints. Unique key for idempotent request processing (UUID v4 recommended). Keys expire after 24 hours."
          },
          {
            "$ref": "#/components/parameters/RequestId"
          },
          {
            "$ref": "#/components/parameters/Traceparent"
          },
          {
            "$ref": "#/components/parameters/Tracestate"
          },
          {
            "$ref": "#/components/parameters/AcceptLanguage"
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "required": [
                  "plan_id",
                  "customer_email"
                ],
                "properties": {
                  "plan_id": {
                    "type": "string",
                    "format": "uuid"
                  },
                  "customer_email": {
                    "type": "string"
                  },
                  "customer_phone": {
                    "type": "string"
                  },
                  "token_id": {
                    "type": "string",
                    "description": "Saved payment token for recurring charges"
                  },
                  "metadata": {
                    "type": "object"
                  }
                }
              }
            }
          }
        },
        "responses": {
          "201": {
            "description": "Subscription created",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/GatewaySubscription"
                },
                "example": {
                  "id": "00000000-0000-4000-8000-000000000000",
                  "plan_id": "00000000-0000-4000-8000-000000000000",
                  "customer_email": "string",
                  "customer_phone": "string",
                  "status": "active",
                  "current_period_start": "2026-01-01T00:00:00Z",
                  "current_period_end": "2026-01-01T00:00:00Z",
                  "next_charge_date": "2026-01-01T00:00:00Z",
                  "charges_count": 0,
                  "created_at": "2026-01-01T00:00:00Z",
                  "trial_start": "2025-03-01T00:00:00Z",
                  "trial_end": "2025-03-15T00:00:00Z",
                  "cancel_at_period_end": false,
                  "cancelled_at": "2025-04-01T00:00:00Z",
                  "billing_cycle_anchor": "2025-01-01T00:00:00Z",
                  "metadata": {
                    "customer_ref": "CUST-001",
                    "plan_tier": "professional"
                  }
                }
              }
            },
            "headers": {
              "x-fapi-interaction-id": {
                "$ref": "#/components/headers/XFapiInteractionIdResponse"
              },
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/XRateLimitLimit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/XRateLimitRemaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/XRateLimitReset"
              },
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              },
              "X-Idempotent-Replay": {
                "$ref": "#/components/headers/X-Idempotent-Replay"
              },
              "X-Idempotency-Status": {
                "$ref": "#/components/headers/X-Idempotency-Status"
              },
              "traceparent": {
                "$ref": "#/components/headers/Traceparent"
              },
              "Content-Language": {
                "$ref": "#/components/headers/Content-Language"
              }
            }
          },
          "400": {
            "description": "Bad request",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              },
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                },
                "examples": {
                  "error": {
                    "$ref": "#/components/examples/ErrorBadRequest"
                  }
                }
              }
            },
            "headers": {
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/XRateLimitLimit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/XRateLimitRemaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/XRateLimitReset"
              },
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "403": {
            "$ref": "#/components/responses/Forbidden",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "404": {
            "$ref": "#/components/responses/NotFound",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "409": {
            "$ref": "#/components/responses/Conflict",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "429": {
            "$ref": "#/components/responses/TooManyRequests",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "500": {
            "$ref": "#/components/responses/InternalServerError",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          }
        },
        "x-codeSamples": [
          {
            "lang": "cURL",
            "label": "cURL",
            "source": "curl -X POST \"https://api.kangopenbanking.com/v1/gateway/subscriptions\" \\\n  -H \"Authorization: Bearer $KOB_ACCESS_TOKEN\" \\\n  -H \"Content-Type: application/json\" \\\n  -d '{}'"
          },
          {
            "lang": "JavaScript",
            "label": "Node.js",
            "source": "import { KangOpenBanking } from \"@kangopenbanking/sdk\";\n\nconst kob = new KangOpenBanking({ apiKey: process.env.KOB_API_KEY });\nconst res = await kob.request(\"POST\", \"/v1/gateway/subscriptions\", { /* payload */ });\nconsole.log(res);"
          },
          {
            "lang": "Python",
            "label": "Python",
            "source": "from kangopenbanking import KangOpenBanking\n\nkob = KangOpenBanking(api_key=os.environ[\"KOB_API_KEY\"])\nres = kob.request(\"POST\", \"/v1/gateway/subscriptions\", json={})\nprint(res)"
          },
          {
            "lang": "PHP",
            "label": "PHP",
            "source": "<?php\n$kob = new KangOpenBanking\\KangOpenBanking(getenv('KOB_API_KEY'));\n$res = $kob->request('POST', '/v1/gateway/subscriptions', []);\nprint_r($res);"
          }
        ]
      },
      "get": {
        "tags": [
          "Payment Gateway"
        ],
        "summary": "List subscriptions",
        "operationId": "gatewayListSubscriptions",
        "security": [
          {
            "bearerAuth": []
          }
        ],
        "parameters": [
          {
            "name": "plan_id",
            "in": "query",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "status",
            "in": "query",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "limit",
            "in": "query",
            "schema": {
              "type": "integer",
              "default": 25,
              "maximum": 100
            },
            "description": "Items per page"
          },
          {
            "name": "offset",
            "in": "query",
            "schema": {
              "type": "integer",
              "default": 0
            },
            "description": "Items to skip"
          },
          {
            "name": "sort_by",
            "in": "query",
            "schema": {
              "type": "string",
              "default": "created_at"
            },
            "description": "Sort field"
          },
          {
            "name": "sort_order",
            "in": "query",
            "schema": {
              "type": "string",
              "enum": [
                "asc",
                "desc"
              ],
              "default": "desc"
            },
            "description": "Sort direction"
          },
          {
            "$ref": "#/components/parameters/StartingAfter"
          },
          {
            "$ref": "#/components/parameters/EndingBefore"
          },
          {
            "$ref": "#/components/parameters/RequestId"
          },
          {
            "$ref": "#/components/parameters/Traceparent"
          },
          {
            "$ref": "#/components/parameters/Tracestate"
          },
          {
            "$ref": "#/components/parameters/AcceptLanguage"
          }
        ],
        "responses": {
          "200": {
            "description": "Subscriptions",
            "content": {
              "application/json": {
                "schema": {
                  "allOf": [
                    {
                      "$ref": "#/components/schemas/PaginatedResponse"
                    },
                    {
                      "type": "object",
                      "properties": {
                        "data": {
                          "type": "array",
                          "items": {
                            "$ref": "#/components/schemas/GatewaySubscription"
                          }
                        }
                      }
                    }
                  ]
                },
                "example": {
                  "data": [
                    {
                      "id": "f1d6f4a0-1d4e-4a3a-9e0a-1a2b3c4d5e6f",
                      "plan_id": "f1d6f4a0-1d4e-4a3a-9e0a-1a2b3c4d5e6f",
                      "customer_email": "XAF",
                      "customer_phone": "XAF",
                      "status": "active",
                      "current_period_start": "2026-01-31T12:00:00Z",
                      "current_period_end": "2026-01-31T12:00:00Z",
                      "next_charge_date": "2026-01-31T12:00:00Z",
                      "charges_count": 1,
                      "created_at": "2026-01-31T12:00:00Z",
                      "trial_start": "2025-03-01T00:00:00Z",
                      "trial_end": "2025-03-15T00:00:00Z",
                      "cancel_at_period_end": false,
                      "cancelled_at": "2025-04-01T00:00:00Z",
                      "billing_cycle_anchor": "2025-01-01T00:00:00Z",
                      "metadata": {}
                    }
                  ],
                  "pagination": {
                    "page": 1,
                    "limit": 20,
                    "total": 150,
                    "has_next": true,
                    "next_cursor": "eyJpZCI6IjEyMyJ9"
                  },
                  "meta": {
                    "request_id": "550e8400-e29b-41d4-a716-446655440000",
                    "timestamp": "2025-03-27T12:00:00Z",
                    "api_version": "4.3.0"
                  }
                }
              }
            },
            "headers": {
              "x-fapi-interaction-id": {
                "$ref": "#/components/headers/XFapiInteractionIdResponse"
              },
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/XRateLimitLimit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/XRateLimitRemaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/XRateLimitReset"
              },
              "Cache-Control": {
                "$ref": "#/components/headers/CacheControl"
              },
              "ETag": {
                "$ref": "#/components/headers/ETag"
              },
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              },
              "traceparent": {
                "$ref": "#/components/headers/Traceparent"
              },
              "Content-Language": {
                "$ref": "#/components/headers/Content-Language"
              }
            }
          },
          "400": {
            "description": "Bad request",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              },
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                },
                "examples": {
                  "error": {
                    "$ref": "#/components/examples/ErrorBadRequest"
                  }
                }
              }
            },
            "headers": {
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/XRateLimitLimit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/XRateLimitRemaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/XRateLimitReset"
              },
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "403": {
            "$ref": "#/components/responses/Forbidden",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "404": {
            "$ref": "#/components/responses/NotFound",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "409": {
            "$ref": "#/components/responses/Conflict",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "429": {
            "$ref": "#/components/responses/TooManyRequests",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "500": {
            "$ref": "#/components/responses/InternalServerError",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          }
        },
        "x-codeSamples": [
          {
            "lang": "cURL",
            "label": "cURL",
            "source": "curl -X GET \"https://api.kangopenbanking.com/v1/gateway/subscriptions\" \\\n  -H \"Authorization: Bearer $KOB_ACCESS_TOKEN\" \\\n  -H \"Content-Type: application/json\""
          },
          {
            "lang": "JavaScript",
            "label": "Node.js",
            "source": "import { KangOpenBanking } from \"@kangopenbanking/sdk\";\n\nconst kob = new KangOpenBanking({ apiKey: process.env.KOB_API_KEY });\nconst res = await kob.request(\"GET\", \"/v1/gateway/subscriptions\");\nconsole.log(res);"
          },
          {
            "lang": "Python",
            "label": "Python",
            "source": "from kangopenbanking import KangOpenBanking\n\nkob = KangOpenBanking(api_key=os.environ[\"KOB_API_KEY\"])\nres = kob.request(\"GET\", \"/v1/gateway/subscriptions\")\nprint(res)"
          },
          {
            "lang": "PHP",
            "label": "PHP",
            "source": "<?php\n$kob = new KangOpenBanking\\KangOpenBanking(getenv('KOB_API_KEY'));\n$res = $kob->request('GET', '/v1/gateway/subscriptions');\nprint_r($res);"
          }
        ]
      }
    },
    "/v1/gateway/subscriptions/{subscriptionId}": {
      "get": {
        "tags": [
          "Payment Gateway"
        ],
        "summary": "Get subscription",
        "operationId": "gatewayGetSubscription",
        "security": [
          {
            "bearerAuth": []
          }
        ],
        "parameters": [
          {
            "name": "subscriptionId",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "$ref": "#/components/parameters/RequestId"
          },
          {
            "$ref": "#/components/parameters/Traceparent"
          },
          {
            "$ref": "#/components/parameters/Tracestate"
          },
          {
            "$ref": "#/components/parameters/AcceptLanguage"
          }
        ],
        "responses": {
          "200": {
            "description": "Subscription details",
            "content": {
              "application/json": {
                "schema": {
                  "allOf": [
                    {
                      "$ref": "#/components/schemas/StandardResponse"
                    },
                    {
                      "type": "object",
                      "properties": {
                        "data": {
                          "$ref": "#/components/schemas/GatewaySubscription"
                        }
                      }
                    }
                  ]
                },
                "example": {
                  "data": {
                    "id": "00000000-0000-4000-8000-000000000000",
                    "plan_id": "00000000-0000-4000-8000-000000000000",
                    "customer_email": "string",
                    "customer_phone": "string",
                    "status": "active",
                    "current_period_start": "2026-01-01T00:00:00Z",
                    "current_period_end": "2026-01-01T00:00:00Z",
                    "next_charge_date": "2026-01-01T00:00:00Z",
                    "charges_count": 0,
                    "created_at": "2026-01-01T00:00:00Z",
                    "trial_start": "2025-03-01T00:00:00Z",
                    "trial_end": "2025-03-15T00:00:00Z",
                    "cancel_at_period_end": false,
                    "cancelled_at": "2025-04-01T00:00:00Z",
                    "billing_cycle_anchor": "2025-01-01T00:00:00Z",
                    "metadata": {
                      "customer_ref": "CUST-001",
                      "plan_tier": "professional"
                    }
                  },
                  "meta": {
                    "request_id": "550e8400-e29b-41d4-a716-446655440000",
                    "timestamp": "2025-03-27T12:00:00Z",
                    "api_version": "4.3.0"
                  }
                }
              }
            },
            "headers": {
              "x-fapi-interaction-id": {
                "$ref": "#/components/headers/XFapiInteractionIdResponse"
              },
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/XRateLimitLimit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/XRateLimitRemaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/XRateLimitReset"
              },
              "Cache-Control": {
                "$ref": "#/components/headers/CacheControl"
              },
              "ETag": {
                "$ref": "#/components/headers/ETag"
              },
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              },
              "traceparent": {
                "$ref": "#/components/headers/Traceparent"
              },
              "Content-Language": {
                "$ref": "#/components/headers/Content-Language"
              }
            }
          },
          "400": {
            "description": "Bad request",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              },
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                },
                "examples": {
                  "error": {
                    "$ref": "#/components/examples/ErrorBadRequest"
                  }
                }
              }
            },
            "headers": {
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/XRateLimitLimit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/XRateLimitRemaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/XRateLimitReset"
              },
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "403": {
            "$ref": "#/components/responses/Forbidden",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "404": {
            "$ref": "#/components/responses/NotFound",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "409": {
            "$ref": "#/components/responses/Conflict",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "429": {
            "$ref": "#/components/responses/TooManyRequests",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "500": {
            "$ref": "#/components/responses/InternalServerError",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          }
        },
        "x-codeSamples": [
          {
            "lang": "cURL",
            "label": "cURL",
            "source": "curl -X GET \"https://api.kangopenbanking.com/v1/gateway/subscriptions/{subscriptionId}\" \\\n  -H \"Authorization: Bearer $KOB_ACCESS_TOKEN\" \\\n  -H \"Content-Type: application/json\""
          },
          {
            "lang": "JavaScript",
            "label": "Node.js",
            "source": "import { KangOpenBanking } from \"@kangopenbanking/sdk\";\n\nconst kob = new KangOpenBanking({ apiKey: process.env.KOB_API_KEY });\nconst res = await kob.request(\"GET\", \"/v1/gateway/subscriptions/{subscriptionId}\");\nconsole.log(res);"
          },
          {
            "lang": "Python",
            "label": "Python",
            "source": "from kangopenbanking import KangOpenBanking\n\nkob = KangOpenBanking(api_key=os.environ[\"KOB_API_KEY\"])\nres = kob.request(\"GET\", \"/v1/gateway/subscriptions/{subscriptionId}\")\nprint(res)"
          },
          {
            "lang": "PHP",
            "label": "PHP",
            "source": "<?php\n$kob = new KangOpenBanking\\KangOpenBanking(getenv('KOB_API_KEY'));\n$res = $kob->request('GET', '/v1/gateway/subscriptions/{subscriptionId}');\nprint_r($res);"
          }
        ]
      },
      "patch": {
        "operationId": "updateSubscription",
        "summary": "Update a subscription",
        "description": "Update an existing subscription (e.g. change plan, billing cycle, or metadata). Only non-terminated subscriptions can be updated.",
        "tags": [
          "Payment Gateway"
        ],
        "security": [
          {
            "bearerAuth": []
          }
        ],
        "parameters": [
          {
            "name": "subscriptionId",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid"
            },
            "description": "Subscription unique identifier"
          },
          {
            "$ref": "#/components/parameters/XFapiInteractionId"
          },
          {
            "$ref": "#/components/parameters/RequestId"
          },
          {
            "$ref": "#/components/parameters/Traceparent"
          },
          {
            "$ref": "#/components/parameters/Tracestate"
          },
          {
            "$ref": "#/components/parameters/AcceptLanguage"
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "plan_id": {
                    "type": "string",
                    "description": "New plan identifier to switch to"
                  },
                  "metadata": {
                    "type": "object",
                    "additionalProperties": {
                      "type": "string"
                    }
                  },
                  "billing_cycle_anchor": {
                    "type": "string",
                    "format": "date-time",
                    "description": "New billing cycle anchor date"
                  },
                  "proration_behavior": {
                    "type": "string",
                    "enum": [
                      "create_prorations",
                      "none",
                      "always_invoice"
                    ],
                    "default": "create_prorations"
                  }
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Subscription updated successfully",
            "headers": {
              "x-fapi-interaction-id": {
                "$ref": "#/components/headers/XFapiInteractionIdResponse"
              },
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/XRateLimitLimit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/XRateLimitRemaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/XRateLimitReset"
              },
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              },
              "traceparent": {
                "$ref": "#/components/headers/Traceparent"
              },
              "Content-Language": {
                "$ref": "#/components/headers/Content-Language"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/GatewaySubscription"
                },
                "example": {
                  "id": "00000000-0000-4000-8000-000000000000",
                  "plan_id": "00000000-0000-4000-8000-000000000000",
                  "customer_email": "string",
                  "customer_phone": "string",
                  "status": "active",
                  "current_period_start": "2026-01-01T00:00:00Z",
                  "current_period_end": "2026-01-01T00:00:00Z",
                  "next_charge_date": "2026-01-01T00:00:00Z",
                  "charges_count": 0,
                  "created_at": "2026-01-01T00:00:00Z",
                  "trial_start": "2025-03-01T00:00:00Z",
                  "trial_end": "2025-03-15T00:00:00Z",
                  "cancel_at_period_end": false,
                  "cancelled_at": "2025-04-01T00:00:00Z",
                  "billing_cycle_anchor": "2025-01-01T00:00:00Z",
                  "metadata": {
                    "customer_ref": "CUST-001",
                    "plan_tier": "professional"
                  }
                }
              }
            }
          },
          "400": {
            "description": "Bad Request",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              },
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                },
                "examples": {
                  "error": {
                    "$ref": "#/components/examples/ErrorBadRequest"
                  }
                }
              }
            },
            "headers": {
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/XRateLimitLimit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/XRateLimitRemaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/XRateLimitReset"
              },
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "404": {
            "$ref": "#/components/responses/NotFound",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "429": {
            "$ref": "#/components/responses/TooManyRequests",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "default": {
            "description": "Server error — see ProblemDetails for trace ID.",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            },
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/XRateLimitLimit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/XRateLimitRemaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/XRateLimitReset"
              }
            }
          }
        },
        "x-codeSamples": [
          {
            "lang": "cURL",
            "label": "cURL",
            "source": "curl -X PATCH \"https://api.kangopenbanking.com/v1/gateway/subscriptions/{subscriptionId}\" \\\n  -H \"Authorization: Bearer $KOB_ACCESS_TOKEN\" \\\n  -H \"Content-Type: application/json\" \\\n  -d '{}'"
          },
          {
            "lang": "JavaScript",
            "label": "Node.js",
            "source": "import { KangOpenBanking } from \"@kangopenbanking/sdk\";\n\nconst kob = new KangOpenBanking({ apiKey: process.env.KOB_API_KEY });\nconst res = await kob.request(\"PATCH\", \"/v1/gateway/subscriptions/{subscriptionId}\", { /* payload */ });\nconsole.log(res);"
          },
          {
            "lang": "Python",
            "label": "Python",
            "source": "from kangopenbanking import KangOpenBanking\n\nkob = KangOpenBanking(api_key=os.environ[\"KOB_API_KEY\"])\nres = kob.request(\"PATCH\", \"/v1/gateway/subscriptions/{subscriptionId}\", json={})\nprint(res)"
          },
          {
            "lang": "PHP",
            "label": "PHP",
            "source": "<?php\n$kob = new KangOpenBanking\\KangOpenBanking(getenv('KOB_API_KEY'));\n$res = $kob->request('PATCH', '/v1/gateway/subscriptions/{subscriptionId}', []);\nprint_r($res);"
          }
        ]
      },
      "delete": {
        "operationId": "deleteSubscription",
        "summary": "Cancel a subscription",
        "description": "Cancel (soft-delete) a subscription. The subscription will complete its current billing period unless cancel_immediately is true.",
        "tags": [
          "Payment Gateway"
        ],
        "security": [
          {
            "bearerAuth": []
          }
        ],
        "parameters": [
          {
            "name": "subscriptionId",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid"
            },
            "description": "Subscription unique identifier"
          },
          {
            "name": "cancel_immediately",
            "in": "query",
            "required": false,
            "schema": {
              "type": "boolean",
              "default": false
            },
            "description": "If true, cancel immediately without finishing the current period"
          },
          {
            "$ref": "#/components/parameters/XFapiInteractionId"
          },
          {
            "$ref": "#/components/parameters/RequestId"
          },
          {
            "$ref": "#/components/parameters/Traceparent"
          },
          {
            "$ref": "#/components/parameters/Tracestate"
          },
          {
            "$ref": "#/components/parameters/AcceptLanguage"
          }
        ],
        "responses": {
          "200": {
            "description": "Subscription cancelled successfully",
            "headers": {
              "x-fapi-interaction-id": {
                "$ref": "#/components/headers/XFapiInteractionIdResponse"
              },
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/XRateLimitLimit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/XRateLimitRemaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/XRateLimitReset"
              },
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              },
              "traceparent": {
                "$ref": "#/components/headers/Traceparent"
              },
              "Content-Language": {
                "$ref": "#/components/headers/Content-Language"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/GatewaySubscription"
                },
                "example": {
                  "id": "00000000-0000-4000-8000-000000000000",
                  "plan_id": "00000000-0000-4000-8000-000000000000",
                  "customer_email": "string",
                  "customer_phone": "string",
                  "status": "active",
                  "current_period_start": "2026-01-01T00:00:00Z",
                  "current_period_end": "2026-01-01T00:00:00Z",
                  "next_charge_date": "2026-01-01T00:00:00Z",
                  "charges_count": 0,
                  "created_at": "2026-01-01T00:00:00Z",
                  "trial_start": "2025-03-01T00:00:00Z",
                  "trial_end": "2025-03-15T00:00:00Z",
                  "cancel_at_period_end": false,
                  "cancelled_at": "2025-04-01T00:00:00Z",
                  "billing_cycle_anchor": "2025-01-01T00:00:00Z",
                  "metadata": {
                    "customer_ref": "CUST-001",
                    "plan_tier": "professional"
                  }
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "404": {
            "$ref": "#/components/responses/NotFound",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "429": {
            "$ref": "#/components/responses/TooManyRequests",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "default": {
            "description": "Server error — see ProblemDetails for trace ID.",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            },
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/XRateLimitLimit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/XRateLimitRemaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/XRateLimitReset"
              }
            }
          }
        },
        "x-codeSamples": [
          {
            "lang": "cURL",
            "label": "cURL",
            "source": "curl -X DELETE \"https://api.kangopenbanking.com/v1/gateway/subscriptions/{subscriptionId}\" \\\n  -H \"Authorization: Bearer $KOB_ACCESS_TOKEN\" \\\n  -H \"Content-Type: application/json\""
          },
          {
            "lang": "JavaScript",
            "label": "Node.js",
            "source": "import { KangOpenBanking } from \"@kangopenbanking/sdk\";\n\nconst kob = new KangOpenBanking({ apiKey: process.env.KOB_API_KEY });\nconst res = await kob.request(\"DELETE\", \"/v1/gateway/subscriptions/{subscriptionId}\");\nconsole.log(res);"
          },
          {
            "lang": "Python",
            "label": "Python",
            "source": "from kangopenbanking import KangOpenBanking\n\nkob = KangOpenBanking(api_key=os.environ[\"KOB_API_KEY\"])\nres = kob.request(\"DELETE\", \"/v1/gateway/subscriptions/{subscriptionId}\")\nprint(res)"
          },
          {
            "lang": "PHP",
            "label": "PHP",
            "source": "<?php\n$kob = new KangOpenBanking\\KangOpenBanking(getenv('KOB_API_KEY'));\n$res = $kob->request('DELETE', '/v1/gateway/subscriptions/{subscriptionId}');\nprint_r($res);"
          }
        ]
      }
    },
    "/v1/gateway/subscriptions/cancel": {
      "post": {
        "tags": [
          "Payment Gateway"
        ],
        "summary": "Cancel subscription",
        "operationId": "gatewayCancelSubscription",
        "security": [
          {
            "bearerAuth": []
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "required": [
                  "subscription_id"
                ],
                "properties": {
                  "subscription_id": {
                    "type": "string",
                    "format": "uuid"
                  },
                  "reason": {
                    "type": "string"
                  }
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Subscription cancelled",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/GatewaySubscription"
                },
                "example": {
                  "id": "00000000-0000-4000-8000-000000000000",
                  "plan_id": "00000000-0000-4000-8000-000000000000",
                  "customer_email": "string",
                  "customer_phone": "string",
                  "status": "active",
                  "current_period_start": "2026-01-01T00:00:00Z",
                  "current_period_end": "2026-01-01T00:00:00Z",
                  "next_charge_date": "2026-01-01T00:00:00Z",
                  "charges_count": 0,
                  "created_at": "2026-01-01T00:00:00Z",
                  "trial_start": "2025-03-01T00:00:00Z",
                  "trial_end": "2025-03-15T00:00:00Z",
                  "cancel_at_period_end": false,
                  "cancelled_at": "2025-04-01T00:00:00Z",
                  "billing_cycle_anchor": "2025-01-01T00:00:00Z",
                  "metadata": {
                    "customer_ref": "CUST-001",
                    "plan_tier": "professional"
                  }
                }
              }
            },
            "headers": {
              "x-fapi-interaction-id": {
                "$ref": "#/components/headers/XFapiInteractionIdResponse"
              },
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/XRateLimitLimit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/XRateLimitRemaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/XRateLimitReset"
              },
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              },
              "traceparent": {
                "$ref": "#/components/headers/Traceparent"
              },
              "Content-Language": {
                "$ref": "#/components/headers/Content-Language"
              }
            }
          },
          "400": {
            "description": "Bad request",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              },
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                },
                "examples": {
                  "error": {
                    "$ref": "#/components/examples/ErrorBadRequest"
                  }
                }
              }
            },
            "headers": {
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/XRateLimitLimit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/XRateLimitRemaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/XRateLimitReset"
              },
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "403": {
            "$ref": "#/components/responses/Forbidden",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "404": {
            "$ref": "#/components/responses/NotFound",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "409": {
            "$ref": "#/components/responses/Conflict",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "429": {
            "$ref": "#/components/responses/TooManyRequests",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "500": {
            "$ref": "#/components/responses/InternalServerError",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          }
        },
        "parameters": [
          {
            "$ref": "#/components/parameters/RequestId"
          },
          {
            "$ref": "#/components/parameters/Traceparent"
          },
          {
            "$ref": "#/components/parameters/Tracestate"
          },
          {
            "$ref": "#/components/parameters/AcceptLanguage"
          }
        ],
        "x-codeSamples": [
          {
            "lang": "cURL",
            "label": "cURL",
            "source": "curl -X POST \"https://api.kangopenbanking.com/v1/gateway/subscriptions/cancel\" \\\n  -H \"Authorization: Bearer $KOB_ACCESS_TOKEN\" \\\n  -H \"Content-Type: application/json\" \\\n  -d '{}'"
          },
          {
            "lang": "JavaScript",
            "label": "Node.js",
            "source": "import { KangOpenBanking } from \"@kangopenbanking/sdk\";\n\nconst kob = new KangOpenBanking({ apiKey: process.env.KOB_API_KEY });\nconst res = await kob.request(\"POST\", \"/v1/gateway/subscriptions/cancel\", { /* payload */ });\nconsole.log(res);"
          },
          {
            "lang": "Python",
            "label": "Python",
            "source": "from kangopenbanking import KangOpenBanking\n\nkob = KangOpenBanking(api_key=os.environ[\"KOB_API_KEY\"])\nres = kob.request(\"POST\", \"/v1/gateway/subscriptions/cancel\", json={})\nprint(res)"
          },
          {
            "lang": "PHP",
            "label": "PHP",
            "source": "<?php\n$kob = new KangOpenBanking\\KangOpenBanking(getenv('KOB_API_KEY'));\n$res = $kob->request('POST', '/v1/gateway/subscriptions/cancel', []);\nprint_r($res);"
          }
        ]
      }
    },
    "/v1/gateway/subaccounts": {
      "post": {
        "tags": [
          "Payment Gateway"
        ],
        "summary": "Create subaccount",
        "operationId": "gatewayCreateSubaccount",
        "security": [
          {
            "bearerAuth": []
          }
        ],
        "parameters": [
          {
            "name": "Idempotency-Key",
            "in": "header",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid"
            },
            "description": "Required on all POST/PUT endpoints. Unique key for idempotent request processing (UUID v4 recommended). Keys expire after 24 hours."
          },
          {
            "$ref": "#/components/parameters/RequestId"
          },
          {
            "$ref": "#/components/parameters/Traceparent"
          },
          {
            "$ref": "#/components/parameters/Tracestate"
          },
          {
            "$ref": "#/components/parameters/AcceptLanguage"
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "required": [
                  "merchant_id",
                  "business_name",
                  "settlement_bank",
                  "account_number"
                ],
                "properties": {
                  "merchant_id": {
                    "type": "string",
                    "format": "uuid"
                  },
                  "business_name": {
                    "type": "string"
                  },
                  "settlement_bank": {
                    "type": "string"
                  },
                  "account_number": {
                    "type": "string"
                  },
                  "split_type": {
                    "type": "string",
                    "enum": [
                      "percentage",
                      "flat"
                    ]
                  },
                  "split_value": {
                    "type": "number"
                  },
                  "country": {
                    "type": "string",
                    "default": "CM"
                  }
                }
              }
            }
          }
        },
        "responses": {
          "201": {
            "description": "Subaccount created",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/GatewaySubaccount"
                },
                "example": {
                  "id": "00000000-0000-4000-8000-000000000000",
                  "merchant_id": "00000000-0000-4000-8000-000000000000",
                  "business_name": "string",
                  "settlement_bank": "string",
                  "account_number": "string",
                  "split_type": "percentage",
                  "split_value": 0,
                  "country": "CM",
                  "created_at": "2026-01-01T00:00:00Z"
                }
              }
            },
            "headers": {
              "x-fapi-interaction-id": {
                "$ref": "#/components/headers/XFapiInteractionIdResponse"
              },
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/XRateLimitLimit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/XRateLimitRemaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/XRateLimitReset"
              },
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              },
              "X-Idempotent-Replay": {
                "$ref": "#/components/headers/X-Idempotent-Replay"
              },
              "X-Idempotency-Status": {
                "$ref": "#/components/headers/X-Idempotency-Status"
              },
              "traceparent": {
                "$ref": "#/components/headers/Traceparent"
              },
              "Content-Language": {
                "$ref": "#/components/headers/Content-Language"
              }
            }
          },
          "400": {
            "description": "Bad request",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              },
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                },
                "examples": {
                  "error": {
                    "$ref": "#/components/examples/ErrorBadRequest"
                  }
                }
              }
            },
            "headers": {
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/XRateLimitLimit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/XRateLimitRemaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/XRateLimitReset"
              },
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "403": {
            "$ref": "#/components/responses/Forbidden",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "404": {
            "$ref": "#/components/responses/NotFound",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "409": {
            "$ref": "#/components/responses/Conflict",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "429": {
            "$ref": "#/components/responses/TooManyRequests",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "500": {
            "$ref": "#/components/responses/InternalServerError",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          }
        },
        "x-codeSamples": [
          {
            "lang": "cURL",
            "label": "cURL",
            "source": "curl -X POST \"https://api.kangopenbanking.com/v1/gateway/subaccounts\" \\\n  -H \"Authorization: Bearer $KOB_ACCESS_TOKEN\" \\\n  -H \"Content-Type: application/json\" \\\n  -d '{}'"
          },
          {
            "lang": "JavaScript",
            "label": "Node.js",
            "source": "import { KangOpenBanking } from \"@kangopenbanking/sdk\";\n\nconst kob = new KangOpenBanking({ apiKey: process.env.KOB_API_KEY });\nconst res = await kob.request(\"POST\", \"/v1/gateway/subaccounts\", { /* payload */ });\nconsole.log(res);"
          },
          {
            "lang": "Python",
            "label": "Python",
            "source": "from kangopenbanking import KangOpenBanking\n\nkob = KangOpenBanking(api_key=os.environ[\"KOB_API_KEY\"])\nres = kob.request(\"POST\", \"/v1/gateway/subaccounts\", json={})\nprint(res)"
          },
          {
            "lang": "PHP",
            "label": "PHP",
            "source": "<?php\n$kob = new KangOpenBanking\\KangOpenBanking(getenv('KOB_API_KEY'));\n$res = $kob->request('POST', '/v1/gateway/subaccounts', []);\nprint_r($res);"
          }
        ]
      },
      "get": {
        "tags": [
          "Payment Gateway"
        ],
        "summary": "List subaccounts",
        "operationId": "gatewayListSubaccounts",
        "security": [
          {
            "bearerAuth": []
          }
        ],
        "parameters": [
          {
            "name": "merchant_id",
            "in": "query",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "limit",
            "in": "query",
            "schema": {
              "type": "integer",
              "default": 25,
              "maximum": 100
            },
            "description": "Items per page"
          },
          {
            "name": "offset",
            "in": "query",
            "schema": {
              "type": "integer",
              "default": 0
            },
            "description": "Items to skip"
          },
          {
            "name": "sort_by",
            "in": "query",
            "schema": {
              "type": "string",
              "default": "created_at"
            },
            "description": "Sort field"
          },
          {
            "name": "sort_order",
            "in": "query",
            "schema": {
              "type": "string",
              "enum": [
                "asc",
                "desc"
              ],
              "default": "desc"
            },
            "description": "Sort direction"
          },
          {
            "$ref": "#/components/parameters/StartingAfter"
          },
          {
            "$ref": "#/components/parameters/EndingBefore"
          },
          {
            "$ref": "#/components/parameters/RequestId"
          },
          {
            "$ref": "#/components/parameters/Traceparent"
          },
          {
            "$ref": "#/components/parameters/Tracestate"
          },
          {
            "$ref": "#/components/parameters/AcceptLanguage"
          }
        ],
        "responses": {
          "200": {
            "description": "Subaccounts",
            "content": {
              "application/json": {
                "schema": {
                  "allOf": [
                    {
                      "$ref": "#/components/schemas/PaginatedResponse"
                    },
                    {
                      "type": "object",
                      "properties": {
                        "data": {
                          "type": "array",
                          "items": {
                            "$ref": "#/components/schemas/GatewaySubaccount"
                          }
                        }
                      }
                    }
                  ]
                },
                "example": {
                  "data": [
                    {
                      "id": "f1d6f4a0-1d4e-4a3a-9e0a-1a2b3c4d5e6f",
                      "merchant_id": "f1d6f4a0-1d4e-4a3a-9e0a-1a2b3c4d5e6f",
                      "business_name": "XAF",
                      "settlement_bank": "XAF",
                      "account_number": "XAF",
                      "split_type": "percentage",
                      "split_value": 1,
                      "country": "CM",
                      "created_at": "2026-01-31T12:00:00Z"
                    }
                  ],
                  "pagination": {
                    "page": 1,
                    "limit": 20,
                    "total": 150,
                    "has_next": true,
                    "next_cursor": "eyJpZCI6IjEyMyJ9"
                  },
                  "meta": {
                    "request_id": "550e8400-e29b-41d4-a716-446655440000",
                    "timestamp": "2025-03-27T12:00:00Z",
                    "api_version": "4.3.0"
                  }
                }
              }
            },
            "headers": {
              "x-fapi-interaction-id": {
                "$ref": "#/components/headers/XFapiInteractionIdResponse"
              },
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/XRateLimitLimit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/XRateLimitRemaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/XRateLimitReset"
              },
              "Cache-Control": {
                "$ref": "#/components/headers/CacheControl"
              },
              "ETag": {
                "$ref": "#/components/headers/ETag"
              },
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              },
              "traceparent": {
                "$ref": "#/components/headers/Traceparent"
              },
              "Content-Language": {
                "$ref": "#/components/headers/Content-Language"
              }
            }
          },
          "400": {
            "description": "Bad request",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              },
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                },
                "examples": {
                  "error": {
                    "$ref": "#/components/examples/ErrorBadRequest"
                  }
                }
              }
            },
            "headers": {
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/XRateLimitLimit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/XRateLimitRemaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/XRateLimitReset"
              },
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "403": {
            "$ref": "#/components/responses/Forbidden",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "404": {
            "$ref": "#/components/responses/NotFound",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "409": {
            "$ref": "#/components/responses/Conflict",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "429": {
            "$ref": "#/components/responses/TooManyRequests",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "500": {
            "$ref": "#/components/responses/InternalServerError",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          }
        },
        "x-codeSamples": [
          {
            "lang": "cURL",
            "label": "cURL",
            "source": "curl -X GET \"https://api.kangopenbanking.com/v1/gateway/subaccounts\" \\\n  -H \"Authorization: Bearer $KOB_ACCESS_TOKEN\" \\\n  -H \"Content-Type: application/json\""
          },
          {
            "lang": "JavaScript",
            "label": "Node.js",
            "source": "import { KangOpenBanking } from \"@kangopenbanking/sdk\";\n\nconst kob = new KangOpenBanking({ apiKey: process.env.KOB_API_KEY });\nconst res = await kob.request(\"GET\", \"/v1/gateway/subaccounts\");\nconsole.log(res);"
          },
          {
            "lang": "Python",
            "label": "Python",
            "source": "from kangopenbanking import KangOpenBanking\n\nkob = KangOpenBanking(api_key=os.environ[\"KOB_API_KEY\"])\nres = kob.request(\"GET\", \"/v1/gateway/subaccounts\")\nprint(res)"
          },
          {
            "lang": "PHP",
            "label": "PHP",
            "source": "<?php\n$kob = new KangOpenBanking\\KangOpenBanking(getenv('KOB_API_KEY'));\n$res = $kob->request('GET', '/v1/gateway/subaccounts');\nprint_r($res);"
          }
        ]
      }
    },
    "/v1/gateway/subaccounts/{subaccountId}": {
      "get": {
        "tags": [
          "Payment Gateway"
        ],
        "summary": "Get subaccount",
        "operationId": "gatewayGetSubaccount",
        "security": [
          {
            "bearerAuth": []
          }
        ],
        "parameters": [
          {
            "name": "subaccountId",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "$ref": "#/components/parameters/RequestId"
          },
          {
            "$ref": "#/components/parameters/Traceparent"
          },
          {
            "$ref": "#/components/parameters/Tracestate"
          },
          {
            "$ref": "#/components/parameters/AcceptLanguage"
          }
        ],
        "responses": {
          "200": {
            "description": "Subaccount details",
            "content": {
              "application/json": {
                "schema": {
                  "allOf": [
                    {
                      "$ref": "#/components/schemas/StandardResponse"
                    },
                    {
                      "type": "object",
                      "properties": {
                        "data": {
                          "$ref": "#/components/schemas/GatewaySubaccount"
                        }
                      }
                    }
                  ]
                },
                "example": {
                  "data": {
                    "id": "00000000-0000-4000-8000-000000000000",
                    "merchant_id": "00000000-0000-4000-8000-000000000000",
                    "business_name": "string",
                    "settlement_bank": "string",
                    "account_number": "string",
                    "split_type": "percentage",
                    "split_value": 0,
                    "country": "CM",
                    "created_at": "2026-01-01T00:00:00Z"
                  },
                  "meta": {
                    "request_id": "550e8400-e29b-41d4-a716-446655440000",
                    "timestamp": "2025-03-27T12:00:00Z",
                    "api_version": "4.3.0"
                  }
                }
              }
            },
            "headers": {
              "x-fapi-interaction-id": {
                "$ref": "#/components/headers/XFapiInteractionIdResponse"
              },
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/XRateLimitLimit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/XRateLimitRemaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/XRateLimitReset"
              },
              "Cache-Control": {
                "$ref": "#/components/headers/CacheControl"
              },
              "ETag": {
                "$ref": "#/components/headers/ETag"
              },
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              },
              "traceparent": {
                "$ref": "#/components/headers/Traceparent"
              },
              "Content-Language": {
                "$ref": "#/components/headers/Content-Language"
              }
            }
          },
          "400": {
            "description": "Bad request",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              },
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                },
                "examples": {
                  "error": {
                    "$ref": "#/components/examples/ErrorBadRequest"
                  }
                }
              }
            },
            "headers": {
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/XRateLimitLimit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/XRateLimitRemaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/XRateLimitReset"
              },
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "403": {
            "$ref": "#/components/responses/Forbidden",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "404": {
            "$ref": "#/components/responses/NotFound",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "409": {
            "$ref": "#/components/responses/Conflict",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "429": {
            "$ref": "#/components/responses/TooManyRequests",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "500": {
            "$ref": "#/components/responses/InternalServerError",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          }
        },
        "x-codeSamples": [
          {
            "lang": "cURL",
            "label": "cURL",
            "source": "curl -X GET \"https://api.kangopenbanking.com/v1/gateway/subaccounts/{subaccountId}\" \\\n  -H \"Authorization: Bearer $KOB_ACCESS_TOKEN\" \\\n  -H \"Content-Type: application/json\""
          },
          {
            "lang": "JavaScript",
            "label": "Node.js",
            "source": "import { KangOpenBanking } from \"@kangopenbanking/sdk\";\n\nconst kob = new KangOpenBanking({ apiKey: process.env.KOB_API_KEY });\nconst res = await kob.request(\"GET\", \"/v1/gateway/subaccounts/{subaccountId}\");\nconsole.log(res);"
          },
          {
            "lang": "Python",
            "label": "Python",
            "source": "from kangopenbanking import KangOpenBanking\n\nkob = KangOpenBanking(api_key=os.environ[\"KOB_API_KEY\"])\nres = kob.request(\"GET\", \"/v1/gateway/subaccounts/{subaccountId}\")\nprint(res)"
          },
          {
            "lang": "PHP",
            "label": "PHP",
            "source": "<?php\n$kob = new KangOpenBanking\\KangOpenBanking(getenv('KOB_API_KEY'));\n$res = $kob->request('GET', '/v1/gateway/subaccounts/{subaccountId}');\nprint_r($res);"
          }
        ]
      },
      "put": {
        "tags": [
          "Payment Gateway"
        ],
        "summary": "Update subaccount",
        "operationId": "gatewayUpdateSubaccount",
        "security": [
          {
            "bearerAuth": []
          }
        ],
        "parameters": [
          {
            "name": "subaccountId",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "$ref": "#/components/parameters/RequestId"
          },
          {
            "$ref": "#/components/parameters/Traceparent"
          },
          {
            "$ref": "#/components/parameters/Tracestate"
          },
          {
            "$ref": "#/components/parameters/AcceptLanguage"
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "business_name": {
                    "type": "string"
                  },
                  "split_type": {
                    "type": "string"
                  },
                  "split_value": {
                    "type": "number"
                  }
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Subaccount updated",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/GatewaySubaccount"
                },
                "example": {
                  "id": "00000000-0000-4000-8000-000000000000",
                  "merchant_id": "00000000-0000-4000-8000-000000000000",
                  "business_name": "string",
                  "settlement_bank": "string",
                  "account_number": "string",
                  "split_type": "percentage",
                  "split_value": 0,
                  "country": "CM",
                  "created_at": "2026-01-01T00:00:00Z"
                }
              }
            },
            "headers": {
              "x-fapi-interaction-id": {
                "$ref": "#/components/headers/XFapiInteractionIdResponse"
              },
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/XRateLimitLimit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/XRateLimitRemaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/XRateLimitReset"
              },
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              },
              "traceparent": {
                "$ref": "#/components/headers/Traceparent"
              },
              "Content-Language": {
                "$ref": "#/components/headers/Content-Language"
              }
            }
          },
          "400": {
            "description": "Bad request",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              },
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                },
                "examples": {
                  "error": {
                    "$ref": "#/components/examples/ErrorBadRequest"
                  }
                }
              }
            },
            "headers": {
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/XRateLimitLimit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/XRateLimitRemaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/XRateLimitReset"
              },
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "403": {
            "$ref": "#/components/responses/Forbidden",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "404": {
            "$ref": "#/components/responses/NotFound",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "409": {
            "$ref": "#/components/responses/Conflict",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "429": {
            "$ref": "#/components/responses/TooManyRequests",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "500": {
            "$ref": "#/components/responses/InternalServerError",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          }
        },
        "x-codeSamples": [
          {
            "lang": "cURL",
            "label": "cURL",
            "source": "curl -X PUT \"https://api.kangopenbanking.com/v1/gateway/subaccounts/{subaccountId}\" \\\n  -H \"Authorization: Bearer $KOB_ACCESS_TOKEN\" \\\n  -H \"Content-Type: application/json\" \\\n  -d '{}'"
          },
          {
            "lang": "JavaScript",
            "label": "Node.js",
            "source": "import { KangOpenBanking } from \"@kangopenbanking/sdk\";\n\nconst kob = new KangOpenBanking({ apiKey: process.env.KOB_API_KEY });\nconst res = await kob.request(\"PUT\", \"/v1/gateway/subaccounts/{subaccountId}\", { /* payload */ });\nconsole.log(res);"
          },
          {
            "lang": "Python",
            "label": "Python",
            "source": "from kangopenbanking import KangOpenBanking\n\nkob = KangOpenBanking(api_key=os.environ[\"KOB_API_KEY\"])\nres = kob.request(\"PUT\", \"/v1/gateway/subaccounts/{subaccountId}\", json={})\nprint(res)"
          },
          {
            "lang": "PHP",
            "label": "PHP",
            "source": "<?php\n$kob = new KangOpenBanking\\KangOpenBanking(getenv('KOB_API_KEY'));\n$res = $kob->request('PUT', '/v1/gateway/subaccounts/{subaccountId}', []);\nprint_r($res);"
          }
        ]
      },
      "delete": {
        "tags": [
          "Payment Gateway"
        ],
        "summary": "Delete subaccount",
        "operationId": "gatewayDeleteSubaccount",
        "security": [
          {
            "bearerAuth": []
          }
        ],
        "parameters": [
          {
            "name": "subaccountId",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "$ref": "#/components/parameters/RequestId"
          },
          {
            "$ref": "#/components/parameters/Traceparent"
          },
          {
            "$ref": "#/components/parameters/Tracestate"
          },
          {
            "$ref": "#/components/parameters/AcceptLanguage"
          }
        ],
        "responses": {
          "204": {
            "description": "Subaccount deleted",
            "headers": {
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/XRateLimitLimit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/XRateLimitRemaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/XRateLimitReset"
              },
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              },
              "traceparent": {
                "$ref": "#/components/headers/Traceparent"
              },
              "Content-Language": {
                "$ref": "#/components/headers/Content-Language"
              }
            }
          },
          "400": {
            "description": "Bad request",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              },
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                },
                "examples": {
                  "error": {
                    "$ref": "#/components/examples/ErrorBadRequest"
                  }
                }
              }
            },
            "headers": {
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/XRateLimitLimit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/XRateLimitRemaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/XRateLimitReset"
              },
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "403": {
            "$ref": "#/components/responses/Forbidden",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "404": {
            "$ref": "#/components/responses/NotFound",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "409": {
            "$ref": "#/components/responses/Conflict",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "429": {
            "$ref": "#/components/responses/TooManyRequests",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "500": {
            "$ref": "#/components/responses/InternalServerError",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          }
        },
        "x-codeSamples": [
          {
            "lang": "cURL",
            "label": "cURL",
            "source": "curl -X DELETE \"https://api.kangopenbanking.com/v1/gateway/subaccounts/{subaccountId}\" \\\n  -H \"Authorization: Bearer $KOB_ACCESS_TOKEN\" \\\n  -H \"Content-Type: application/json\""
          },
          {
            "lang": "JavaScript",
            "label": "Node.js",
            "source": "import { KangOpenBanking } from \"@kangopenbanking/sdk\";\n\nconst kob = new KangOpenBanking({ apiKey: process.env.KOB_API_KEY });\nconst res = await kob.request(\"DELETE\", \"/v1/gateway/subaccounts/{subaccountId}\");\nconsole.log(res);"
          },
          {
            "lang": "Python",
            "label": "Python",
            "source": "from kangopenbanking import KangOpenBanking\n\nkob = KangOpenBanking(api_key=os.environ[\"KOB_API_KEY\"])\nres = kob.request(\"DELETE\", \"/v1/gateway/subaccounts/{subaccountId}\")\nprint(res)"
          },
          {
            "lang": "PHP",
            "label": "PHP",
            "source": "<?php\n$kob = new KangOpenBanking\\KangOpenBanking(getenv('KOB_API_KEY'));\n$res = $kob->request('DELETE', '/v1/gateway/subaccounts/{subaccountId}');\nprint_r($res);"
          }
        ]
      }
    },
    "/v1/gateway/customers": {
      "post": {
        "tags": [
          "Payment Gateway"
        ],
        "summary": "Create customer",
        "operationId": "gatewayCreateCustomer",
        "security": [
          {
            "bearerAuth": []
          }
        ],
        "parameters": [
          {
            "name": "Idempotency-Key",
            "in": "header",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid"
            },
            "description": "Required on all POST/PUT endpoints. Unique key for idempotent request processing (UUID v4 recommended). Keys expire after 24 hours."
          },
          {
            "$ref": "#/components/parameters/RequestId"
          },
          {
            "$ref": "#/components/parameters/Traceparent"
          },
          {
            "$ref": "#/components/parameters/Tracestate"
          },
          {
            "$ref": "#/components/parameters/AcceptLanguage"
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "required": [
                  "merchant_id",
                  "email"
                ],
                "properties": {
                  "merchant_id": {
                    "type": "string",
                    "format": "uuid"
                  },
                  "email": {
                    "type": "string"
                  },
                  "phone": {
                    "type": "string"
                  },
                  "name": {
                    "type": "string"
                  },
                  "metadata": {
                    "type": "object"
                  }
                }
              }
            }
          }
        },
        "responses": {
          "201": {
            "description": "Customer created",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/GatewayCustomer"
                },
                "example": {
                  "id": "00000000-0000-4000-8000-000000000000",
                  "merchant_id": "00000000-0000-4000-8000-000000000000",
                  "email": "agent@example.cm",
                  "phone": "string",
                  "name": "string",
                  "metadata": {},
                  "created_at": "2026-01-01T00:00:00Z"
                }
              }
            },
            "headers": {
              "x-fapi-interaction-id": {
                "$ref": "#/components/headers/XFapiInteractionIdResponse"
              },
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/XRateLimitLimit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/XRateLimitRemaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/XRateLimitReset"
              },
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              },
              "X-Idempotent-Replay": {
                "$ref": "#/components/headers/X-Idempotent-Replay"
              },
              "X-Idempotency-Status": {
                "$ref": "#/components/headers/X-Idempotency-Status"
              },
              "traceparent": {
                "$ref": "#/components/headers/Traceparent"
              },
              "Content-Language": {
                "$ref": "#/components/headers/Content-Language"
              }
            }
          },
          "400": {
            "description": "Bad request",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              },
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                },
                "examples": {
                  "error": {
                    "$ref": "#/components/examples/ErrorBadRequest"
                  }
                }
              }
            },
            "headers": {
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/XRateLimitLimit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/XRateLimitRemaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/XRateLimitReset"
              },
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "403": {
            "$ref": "#/components/responses/Forbidden",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "404": {
            "$ref": "#/components/responses/NotFound",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "409": {
            "$ref": "#/components/responses/Conflict",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "429": {
            "$ref": "#/components/responses/TooManyRequests",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "500": {
            "$ref": "#/components/responses/InternalServerError",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          }
        },
        "x-codeSamples": [
          {
            "lang": "cURL",
            "label": "cURL",
            "source": "curl -X POST \"https://api.kangopenbanking.com/v1/gateway/customers\" \\\n  -H \"Authorization: Bearer $KOB_ACCESS_TOKEN\" \\\n  -H \"Content-Type: application/json\" \\\n  -d '{}'"
          },
          {
            "lang": "JavaScript",
            "label": "Node.js",
            "source": "import { KangOpenBanking } from \"@kangopenbanking/sdk\";\n\nconst kob = new KangOpenBanking({ apiKey: process.env.KOB_API_KEY });\nconst res = await kob.request(\"POST\", \"/v1/gateway/customers\", { /* payload */ });\nconsole.log(res);"
          },
          {
            "lang": "Python",
            "label": "Python",
            "source": "from kangopenbanking import KangOpenBanking\n\nkob = KangOpenBanking(api_key=os.environ[\"KOB_API_KEY\"])\nres = kob.request(\"POST\", \"/v1/gateway/customers\", json={})\nprint(res)"
          },
          {
            "lang": "PHP",
            "label": "PHP",
            "source": "<?php\n$kob = new KangOpenBanking\\KangOpenBanking(getenv('KOB_API_KEY'));\n$res = $kob->request('POST', '/v1/gateway/customers', []);\nprint_r($res);"
          }
        ]
      },
      "get": {
        "tags": [
          "Payment Gateway"
        ],
        "summary": "List customers",
        "operationId": "gatewayListCustomers",
        "security": [
          {
            "bearerAuth": []
          }
        ],
        "parameters": [
          {
            "name": "merchant_id",
            "in": "query",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "limit",
            "in": "query",
            "schema": {
              "type": "integer",
              "default": 25,
              "maximum": 100
            },
            "description": "Items per page"
          },
          {
            "name": "offset",
            "in": "query",
            "schema": {
              "type": "integer",
              "default": 0
            },
            "description": "Items to skip"
          },
          {
            "name": "sort_by",
            "in": "query",
            "schema": {
              "type": "string",
              "default": "created_at"
            },
            "description": "Sort field"
          },
          {
            "name": "sort_order",
            "in": "query",
            "schema": {
              "type": "string",
              "enum": [
                "asc",
                "desc"
              ],
              "default": "desc"
            },
            "description": "Sort direction"
          },
          {
            "$ref": "#/components/parameters/StartingAfter"
          },
          {
            "$ref": "#/components/parameters/EndingBefore"
          },
          {
            "$ref": "#/components/parameters/RequestId"
          },
          {
            "$ref": "#/components/parameters/Traceparent"
          },
          {
            "$ref": "#/components/parameters/Tracestate"
          },
          {
            "$ref": "#/components/parameters/AcceptLanguage"
          }
        ],
        "responses": {
          "200": {
            "description": "Customers",
            "content": {
              "application/json": {
                "schema": {
                  "allOf": [
                    {
                      "$ref": "#/components/schemas/PaginatedResponse"
                    },
                    {
                      "type": "object",
                      "properties": {
                        "data": {
                          "type": "array",
                          "items": {
                            "$ref": "#/components/schemas/GatewayCustomer"
                          }
                        }
                      }
                    }
                  ]
                },
                "example": {
                  "data": [
                    {
                      "id": "f1d6f4a0-1d4e-4a3a-9e0a-1a2b3c4d5e6f",
                      "merchant_id": "f1d6f4a0-1d4e-4a3a-9e0a-1a2b3c4d5e6f",
                      "email": "XAF",
                      "phone": "XAF",
                      "name": "XAF",
                      "metadata": {},
                      "created_at": "2026-01-31T12:00:00Z"
                    }
                  ],
                  "pagination": {
                    "page": 1,
                    "limit": 20,
                    "total": 150,
                    "has_next": true,
                    "next_cursor": "eyJpZCI6IjEyMyJ9"
                  },
                  "meta": {
                    "request_id": "550e8400-e29b-41d4-a716-446655440000",
                    "timestamp": "2025-03-27T12:00:00Z",
                    "api_version": "4.3.0"
                  }
                }
              }
            },
            "headers": {
              "x-fapi-interaction-id": {
                "$ref": "#/components/headers/XFapiInteractionIdResponse"
              },
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/XRateLimitLimit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/XRateLimitRemaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/XRateLimitReset"
              },
              "Cache-Control": {
                "$ref": "#/components/headers/CacheControl"
              },
              "ETag": {
                "$ref": "#/components/headers/ETag"
              },
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              },
              "traceparent": {
                "$ref": "#/components/headers/Traceparent"
              },
              "Content-Language": {
                "$ref": "#/components/headers/Content-Language"
              }
            }
          },
          "400": {
            "description": "Bad request",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              },
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                },
                "examples": {
                  "error": {
                    "$ref": "#/components/examples/ErrorBadRequest"
                  }
                }
              }
            },
            "headers": {
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/XRateLimitLimit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/XRateLimitRemaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/XRateLimitReset"
              },
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "403": {
            "$ref": "#/components/responses/Forbidden",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "404": {
            "$ref": "#/components/responses/NotFound",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "409": {
            "$ref": "#/components/responses/Conflict",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "429": {
            "$ref": "#/components/responses/TooManyRequests",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "500": {
            "$ref": "#/components/responses/InternalServerError",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          }
        },
        "x-codeSamples": [
          {
            "lang": "cURL",
            "label": "cURL",
            "source": "curl -X GET \"https://api.kangopenbanking.com/v1/gateway/customers\" \\\n  -H \"Authorization: Bearer $KOB_ACCESS_TOKEN\" \\\n  -H \"Content-Type: application/json\""
          },
          {
            "lang": "JavaScript",
            "label": "Node.js",
            "source": "import { KangOpenBanking } from \"@kangopenbanking/sdk\";\n\nconst kob = new KangOpenBanking({ apiKey: process.env.KOB_API_KEY });\nconst res = await kob.request(\"GET\", \"/v1/gateway/customers\");\nconsole.log(res);"
          },
          {
            "lang": "Python",
            "label": "Python",
            "source": "from kangopenbanking import KangOpenBanking\n\nkob = KangOpenBanking(api_key=os.environ[\"KOB_API_KEY\"])\nres = kob.request(\"GET\", \"/v1/gateway/customers\")\nprint(res)"
          },
          {
            "lang": "PHP",
            "label": "PHP",
            "source": "<?php\n$kob = new KangOpenBanking\\KangOpenBanking(getenv('KOB_API_KEY'));\n$res = $kob->request('GET', '/v1/gateway/customers');\nprint_r($res);"
          }
        ]
      }
    },
    "/v1/gateway/customers/{customerId}": {
      "get": {
        "tags": [
          "Payment Gateway"
        ],
        "summary": "Get customer",
        "operationId": "gatewayGetCustomer",
        "security": [
          {
            "bearerAuth": []
          }
        ],
        "parameters": [
          {
            "name": "customerId",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "$ref": "#/components/parameters/RequestId"
          },
          {
            "$ref": "#/components/parameters/Traceparent"
          },
          {
            "$ref": "#/components/parameters/Tracestate"
          },
          {
            "$ref": "#/components/parameters/AcceptLanguage"
          }
        ],
        "responses": {
          "200": {
            "description": "Customer details",
            "content": {
              "application/json": {
                "schema": {
                  "allOf": [
                    {
                      "$ref": "#/components/schemas/StandardResponse"
                    },
                    {
                      "type": "object",
                      "properties": {
                        "data": {
                          "$ref": "#/components/schemas/GatewayCustomer"
                        }
                      }
                    }
                  ]
                },
                "example": {
                  "data": {
                    "id": "00000000-0000-4000-8000-000000000000",
                    "merchant_id": "00000000-0000-4000-8000-000000000000",
                    "email": "agent@example.cm",
                    "phone": "string",
                    "name": "string",
                    "metadata": {},
                    "created_at": "2026-01-01T00:00:00Z"
                  },
                  "meta": {
                    "request_id": "550e8400-e29b-41d4-a716-446655440000",
                    "timestamp": "2025-03-27T12:00:00Z",
                    "api_version": "4.3.0"
                  }
                }
              }
            },
            "headers": {
              "x-fapi-interaction-id": {
                "$ref": "#/components/headers/XFapiInteractionIdResponse"
              },
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/XRateLimitLimit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/XRateLimitRemaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/XRateLimitReset"
              },
              "Cache-Control": {
                "$ref": "#/components/headers/CacheControl"
              },
              "ETag": {
                "$ref": "#/components/headers/ETag"
              },
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              },
              "traceparent": {
                "$ref": "#/components/headers/Traceparent"
              },
              "Content-Language": {
                "$ref": "#/components/headers/Content-Language"
              }
            }
          },
          "400": {
            "description": "Bad request",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              },
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                },
                "examples": {
                  "error": {
                    "$ref": "#/components/examples/ErrorBadRequest"
                  }
                }
              }
            },
            "headers": {
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/XRateLimitLimit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/XRateLimitRemaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/XRateLimitReset"
              },
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "403": {
            "$ref": "#/components/responses/Forbidden",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "404": {
            "$ref": "#/components/responses/NotFound",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "409": {
            "$ref": "#/components/responses/Conflict",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "429": {
            "$ref": "#/components/responses/TooManyRequests",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "500": {
            "$ref": "#/components/responses/InternalServerError",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          }
        },
        "x-codeSamples": [
          {
            "lang": "cURL",
            "label": "cURL",
            "source": "curl -X GET \"https://api.kangopenbanking.com/v1/gateway/customers/{customerId}\" \\\n  -H \"Authorization: Bearer $KOB_ACCESS_TOKEN\" \\\n  -H \"Content-Type: application/json\""
          },
          {
            "lang": "JavaScript",
            "label": "Node.js",
            "source": "import { KangOpenBanking } from \"@kangopenbanking/sdk\";\n\nconst kob = new KangOpenBanking({ apiKey: process.env.KOB_API_KEY });\nconst res = await kob.request(\"GET\", \"/v1/gateway/customers/{customerId}\");\nconsole.log(res);"
          },
          {
            "lang": "Python",
            "label": "Python",
            "source": "from kangopenbanking import KangOpenBanking\n\nkob = KangOpenBanking(api_key=os.environ[\"KOB_API_KEY\"])\nres = kob.request(\"GET\", \"/v1/gateway/customers/{customerId}\")\nprint(res)"
          },
          {
            "lang": "PHP",
            "label": "PHP",
            "source": "<?php\n$kob = new KangOpenBanking\\KangOpenBanking(getenv('KOB_API_KEY'));\n$res = $kob->request('GET', '/v1/gateway/customers/{customerId}');\nprint_r($res);"
          }
        ]
      },
      "put": {
        "tags": [
          "Payment Gateway"
        ],
        "summary": "Update customer",
        "operationId": "gatewayUpdateCustomer",
        "security": [
          {
            "bearerAuth": []
          }
        ],
        "parameters": [
          {
            "name": "customerId",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "$ref": "#/components/parameters/RequestId"
          },
          {
            "$ref": "#/components/parameters/Traceparent"
          },
          {
            "$ref": "#/components/parameters/Tracestate"
          },
          {
            "$ref": "#/components/parameters/AcceptLanguage"
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "email": {
                    "type": "string"
                  },
                  "phone": {
                    "type": "string"
                  },
                  "name": {
                    "type": "string"
                  },
                  "metadata": {
                    "type": "object"
                  }
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Customer updated",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/GatewayCustomer"
                },
                "example": {
                  "id": "00000000-0000-4000-8000-000000000000",
                  "merchant_id": "00000000-0000-4000-8000-000000000000",
                  "email": "agent@example.cm",
                  "phone": "string",
                  "name": "string",
                  "metadata": {},
                  "created_at": "2026-01-01T00:00:00Z"
                }
              }
            },
            "headers": {
              "x-fapi-interaction-id": {
                "$ref": "#/components/headers/XFapiInteractionIdResponse"
              },
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/XRateLimitLimit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/XRateLimitRemaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/XRateLimitReset"
              },
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              },
              "traceparent": {
                "$ref": "#/components/headers/Traceparent"
              },
              "Content-Language": {
                "$ref": "#/components/headers/Content-Language"
              }
            }
          },
          "400": {
            "description": "Bad request",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              },
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                },
                "examples": {
                  "error": {
                    "$ref": "#/components/examples/ErrorBadRequest"
                  }
                }
              }
            },
            "headers": {
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/XRateLimitLimit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/XRateLimitRemaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/XRateLimitReset"
              },
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "403": {
            "$ref": "#/components/responses/Forbidden",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "404": {
            "$ref": "#/components/responses/NotFound",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "409": {
            "$ref": "#/components/responses/Conflict",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "429": {
            "$ref": "#/components/responses/TooManyRequests",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "500": {
            "$ref": "#/components/responses/InternalServerError",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          }
        },
        "x-codeSamples": [
          {
            "lang": "cURL",
            "label": "cURL",
            "source": "curl -X PUT \"https://api.kangopenbanking.com/v1/gateway/customers/{customerId}\" \\\n  -H \"Authorization: Bearer $KOB_ACCESS_TOKEN\" \\\n  -H \"Content-Type: application/json\" \\\n  -d '{}'"
          },
          {
            "lang": "JavaScript",
            "label": "Node.js",
            "source": "import { KangOpenBanking } from \"@kangopenbanking/sdk\";\n\nconst kob = new KangOpenBanking({ apiKey: process.env.KOB_API_KEY });\nconst res = await kob.request(\"PUT\", \"/v1/gateway/customers/{customerId}\", { /* payload */ });\nconsole.log(res);"
          },
          {
            "lang": "Python",
            "label": "Python",
            "source": "from kangopenbanking import KangOpenBanking\n\nkob = KangOpenBanking(api_key=os.environ[\"KOB_API_KEY\"])\nres = kob.request(\"PUT\", \"/v1/gateway/customers/{customerId}\", json={})\nprint(res)"
          },
          {
            "lang": "PHP",
            "label": "PHP",
            "source": "<?php\n$kob = new KangOpenBanking\\KangOpenBanking(getenv('KOB_API_KEY'));\n$res = $kob->request('PUT', '/v1/gateway/customers/{customerId}', []);\nprint_r($res);"
          }
        ]
      }
    },
    "/v1/gateway/customers/{customerId}/tokens": {
      "get": {
        "tags": [
          "Payment Gateway"
        ],
        "summary": "List customer tokens",
        "operationId": "gatewayListCustomerTokens",
        "security": [
          {
            "bearerAuth": []
          }
        ],
        "parameters": [
          {
            "name": "customerId",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "$ref": "#/components/parameters/RequestId"
          },
          {
            "$ref": "#/components/parameters/Traceparent"
          },
          {
            "$ref": "#/components/parameters/Tracestate"
          },
          {
            "$ref": "#/components/parameters/AcceptLanguage"
          }
        ],
        "responses": {
          "200": {
            "description": "Customer payment tokens",
            "content": {
              "application/json": {
                "schema": {
                  "allOf": [
                    {
                      "$ref": "#/components/schemas/PaginatedResponse"
                    },
                    {
                      "type": "object",
                      "properties": {
                        "data": {
                          "type": "array",
                          "items": {
                            "$ref": "#/components/schemas/GatewayCustomerToken"
                          }
                        }
                      }
                    }
                  ]
                },
                "example": {
                  "data": [
                    {
                      "id": "f1d6f4a0-1d4e-4a3a-9e0a-1a2b3c4d5e6f",
                      "customer_id": "f1d6f4a0-1d4e-4a3a-9e0a-1a2b3c4d5e6f",
                      "channel": "mobile_money",
                      "token_ref": "XAF",
                      "last4": "1234",
                      "provider": "XAF",
                      "is_active": false,
                      "created_at": "2026-01-31T12:00:00Z"
                    }
                  ],
                  "pagination": {
                    "page": 1,
                    "limit": 20,
                    "total": 150,
                    "has_next": true,
                    "next_cursor": "eyJpZCI6IjEyMyJ9"
                  },
                  "meta": {
                    "request_id": "550e8400-e29b-41d4-a716-446655440000",
                    "timestamp": "2025-03-27T12:00:00Z",
                    "api_version": "4.3.0"
                  }
                }
              }
            },
            "headers": {
              "x-fapi-interaction-id": {
                "$ref": "#/components/headers/XFapiInteractionIdResponse"
              },
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/XRateLimitLimit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/XRateLimitRemaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/XRateLimitReset"
              },
              "Cache-Control": {
                "$ref": "#/components/headers/CacheControl"
              },
              "ETag": {
                "$ref": "#/components/headers/ETag"
              },
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              },
              "traceparent": {
                "$ref": "#/components/headers/Traceparent"
              },
              "Content-Language": {
                "$ref": "#/components/headers/Content-Language"
              }
            }
          },
          "400": {
            "description": "Bad request",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              },
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                },
                "examples": {
                  "error": {
                    "$ref": "#/components/examples/ErrorBadRequest"
                  }
                }
              }
            },
            "headers": {
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/XRateLimitLimit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/XRateLimitRemaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/XRateLimitReset"
              },
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "403": {
            "$ref": "#/components/responses/Forbidden",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "404": {
            "$ref": "#/components/responses/NotFound",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "409": {
            "$ref": "#/components/responses/Conflict",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "429": {
            "$ref": "#/components/responses/TooManyRequests",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "500": {
            "$ref": "#/components/responses/InternalServerError",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          }
        },
        "x-codeSamples": [
          {
            "lang": "cURL",
            "label": "cURL",
            "source": "curl -X GET \"https://api.kangopenbanking.com/v1/gateway/customers/{customerId}/tokens\" \\\n  -H \"Authorization: Bearer $KOB_ACCESS_TOKEN\" \\\n  -H \"Content-Type: application/json\""
          },
          {
            "lang": "JavaScript",
            "label": "Node.js",
            "source": "import { KangOpenBanking } from \"@kangopenbanking/sdk\";\n\nconst kob = new KangOpenBanking({ apiKey: process.env.KOB_API_KEY });\nconst res = await kob.request(\"GET\", \"/v1/gateway/customers/{customerId}/tokens\");\nconsole.log(res);"
          },
          {
            "lang": "Python",
            "label": "Python",
            "source": "from kangopenbanking import KangOpenBanking\n\nkob = KangOpenBanking(api_key=os.environ[\"KOB_API_KEY\"])\nres = kob.request(\"GET\", \"/v1/gateway/customers/{customerId}/tokens\")\nprint(res)"
          },
          {
            "lang": "PHP",
            "label": "PHP",
            "source": "<?php\n$kob = new KangOpenBanking\\KangOpenBanking(getenv('KOB_API_KEY'));\n$res = $kob->request('GET', '/v1/gateway/customers/{customerId}/tokens');\nprint_r($res);"
          }
        ]
      }
    },
    "/v1/gateway/customers/{customerId}/tokens/{tokenId}": {
      "delete": {
        "tags": [
          "Payment Gateway"
        ],
        "summary": "Revoke customer token",
        "operationId": "gatewayRevokeCustomerToken",
        "security": [
          {
            "bearerAuth": []
          }
        ],
        "parameters": [
          {
            "name": "customerId",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "tokenId",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "$ref": "#/components/parameters/RequestId"
          },
          {
            "$ref": "#/components/parameters/Traceparent"
          },
          {
            "$ref": "#/components/parameters/Tracestate"
          },
          {
            "$ref": "#/components/parameters/AcceptLanguage"
          }
        ],
        "responses": {
          "204": {
            "description": "Token revoked",
            "headers": {
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/XRateLimitLimit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/XRateLimitRemaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/XRateLimitReset"
              },
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              },
              "traceparent": {
                "$ref": "#/components/headers/Traceparent"
              },
              "Content-Language": {
                "$ref": "#/components/headers/Content-Language"
              }
            }
          },
          "400": {
            "description": "Bad request",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              },
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                },
                "examples": {
                  "error": {
                    "$ref": "#/components/examples/ErrorBadRequest"
                  }
                }
              }
            },
            "headers": {
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/XRateLimitLimit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/XRateLimitRemaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/XRateLimitReset"
              },
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "403": {
            "$ref": "#/components/responses/Forbidden",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "404": {
            "$ref": "#/components/responses/NotFound",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "409": {
            "$ref": "#/components/responses/Conflict",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "429": {
            "$ref": "#/components/responses/TooManyRequests",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "500": {
            "$ref": "#/components/responses/InternalServerError",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          }
        },
        "x-codeSamples": [
          {
            "lang": "cURL",
            "label": "cURL",
            "source": "curl -X DELETE \"https://api.kangopenbanking.com/v1/gateway/customers/{customerId}/tokens/{tokenId}\" \\\n  -H \"Authorization: Bearer $KOB_ACCESS_TOKEN\" \\\n  -H \"Content-Type: application/json\""
          },
          {
            "lang": "JavaScript",
            "label": "Node.js",
            "source": "import { KangOpenBanking } from \"@kangopenbanking/sdk\";\n\nconst kob = new KangOpenBanking({ apiKey: process.env.KOB_API_KEY });\nconst res = await kob.request(\"DELETE\", \"/v1/gateway/customers/{customerId}/tokens/{tokenId}\");\nconsole.log(res);"
          },
          {
            "lang": "Python",
            "label": "Python",
            "source": "from kangopenbanking import KangOpenBanking\n\nkob = KangOpenBanking(api_key=os.environ[\"KOB_API_KEY\"])\nres = kob.request(\"DELETE\", \"/v1/gateway/customers/{customerId}/tokens/{tokenId}\")\nprint(res)"
          },
          {
            "lang": "PHP",
            "label": "PHP",
            "source": "<?php\n$kob = new KangOpenBanking\\KangOpenBanking(getenv('KOB_API_KEY'));\n$res = $kob->request('DELETE', '/v1/gateway/customers/{customerId}/tokens/{tokenId}');\nprint_r($res);"
          }
        ]
      }
    },
    "/v1/gateway/charges/token": {
      "post": {
        "tags": [
          "Payment Gateway"
        ],
        "summary": "Charge a saved token",
        "operationId": "gatewayChargeToken",
        "security": [
          {
            "bearerAuth": []
          }
        ],
        "parameters": [
          {
            "name": "Idempotency-Key",
            "in": "header",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid"
            },
            "description": "Required on all POST/PUT endpoints. Unique key for idempotent request processing (UUID v4 recommended). Keys expire after 24 hours."
          },
          {
            "$ref": "#/components/parameters/RequestId"
          },
          {
            "$ref": "#/components/parameters/Traceparent"
          },
          {
            "$ref": "#/components/parameters/Tracestate"
          },
          {
            "$ref": "#/components/parameters/AcceptLanguage"
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "required": [
                  "token_id",
                  "amount",
                  "tx_ref"
                ],
                "properties": {
                  "token_id": {
                    "type": "string",
                    "format": "uuid"
                  },
                  "amount": {
                    "type": "string",
                    "pattern": "^[0-9]{1,15}$",
                    "description": "Represented as a string integer in the currency's minor unit (XAF has no subunits). Must be consistent with the currency field."
                  },
                  "currency": {
                    "type": "string",
                    "default": "XAF",
                    "enum": [
                      "XAF",
                      "XOF",
                      "USD",
                      "EUR",
                      "GBP",
                      "CNY",
                      "NGN",
                      "GHS",
                      "KES",
                      "ZAR"
                    ],
                    "description": "ISO 4217 currency code. Default is XAF (Central African CFA Franc)."
                  },
                  "tx_ref": {
                    "type": "string"
                  },
                  "metadata": {
                    "type": "object"
                  }
                }
              }
            }
          }
        },
        "responses": {
          "201": {
            "description": "Token charge created",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/GatewayCharge"
                },
                "example": {
                  "id": "00000000-0000-4000-8000-000000000000",
                  "merchant_id": "00000000-0000-4000-8000-000000000000",
                  "amount": "5000",
                  "currency": "XAF",
                  "channel": "mobile_money",
                  "status": "pending",
                  "provider": "flutterwave",
                  "provider_ref": "string",
                  "fee_amount": "200",
                  "net_amount": "4800",
                  "tx_ref": "string",
                  "customer_phone": "string",
                  "customer_email": "string",
                  "capture_mode": "auto",
                  "captured_amount": 0,
                  "fee_bearer": "merchant",
                  "created_at": "2026-01-01T00:00:00Z",
                  "updated_at": "2026-01-01T00:00:00Z",
                  "description": "string",
                  "metadata": {},
                  "customer_id": "string",
                  "dispute_id": "00000000-0000-4000-8000-000000000000",
                  "refunded_at": "2026-01-01T00:00:00Z",
                  "failure_reason": "string",
                  "failure_message": "string"
                }
              }
            },
            "headers": {
              "x-fapi-interaction-id": {
                "$ref": "#/components/headers/XFapiInteractionIdResponse"
              },
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/XRateLimitLimit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/XRateLimitRemaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/XRateLimitReset"
              },
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              },
              "X-Idempotent-Replay": {
                "$ref": "#/components/headers/X-Idempotent-Replay"
              },
              "X-Idempotency-Status": {
                "$ref": "#/components/headers/X-Idempotency-Status"
              },
              "traceparent": {
                "$ref": "#/components/headers/Traceparent"
              },
              "Content-Language": {
                "$ref": "#/components/headers/Content-Language"
              }
            }
          },
          "400": {
            "description": "Bad request",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              },
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                },
                "examples": {
                  "error": {
                    "$ref": "#/components/examples/ErrorBadRequest"
                  }
                }
              }
            },
            "headers": {
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/XRateLimitLimit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/XRateLimitRemaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/XRateLimitReset"
              },
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "403": {
            "$ref": "#/components/responses/Forbidden",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "404": {
            "$ref": "#/components/responses/NotFound",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "409": {
            "$ref": "#/components/responses/Conflict",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "429": {
            "$ref": "#/components/responses/TooManyRequests",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "500": {
            "$ref": "#/components/responses/InternalServerError",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          }
        },
        "x-codeSamples": [
          {
            "lang": "cURL",
            "label": "cURL",
            "source": "curl -X POST \"https://api.kangopenbanking.com/v1/gateway/charges/token\" \\\n  -H \"Authorization: Bearer $KOB_ACCESS_TOKEN\" \\\n  -H \"Content-Type: application/json\" \\\n  -d '{}'"
          },
          {
            "lang": "JavaScript",
            "label": "Node.js",
            "source": "import { KangOpenBanking } from \"@kangopenbanking/sdk\";\n\nconst kob = new KangOpenBanking({ apiKey: process.env.KOB_API_KEY });\nconst res = await kob.request(\"POST\", \"/v1/gateway/charges/token\", { /* payload */ });\nconsole.log(res);"
          },
          {
            "lang": "Python",
            "label": "Python",
            "source": "from kangopenbanking import KangOpenBanking\n\nkob = KangOpenBanking(api_key=os.environ[\"KOB_API_KEY\"])\nres = kob.request(\"POST\", \"/v1/gateway/charges/token\", json={})\nprint(res)"
          },
          {
            "lang": "PHP",
            "label": "PHP",
            "source": "<?php\n$kob = new KangOpenBanking\\KangOpenBanking(getenv('KOB_API_KEY'));\n$res = $kob->request('POST', '/v1/gateway/charges/token', []);\nprint_r($res);"
          }
        ]
      }
    },
    "/v1/gateway/charges/{chargeId}/events": {
      "get": {
        "tags": [
          "Payment Gateway"
        ],
        "summary": "Get charge events",
        "description": "Retrieve the full event timeline for a charge.",
        "operationId": "gatewayGetChargeEvents",
        "security": [
          {
            "bearerAuth": []
          }
        ],
        "parameters": [
          {
            "name": "chargeId",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "$ref": "#/components/parameters/RequestId"
          },
          {
            "$ref": "#/components/parameters/Traceparent"
          },
          {
            "$ref": "#/components/parameters/Tracestate"
          },
          {
            "$ref": "#/components/parameters/AcceptLanguage"
          }
        ],
        "responses": {
          "200": {
            "description": "Charge event timeline",
            "content": {
              "application/json": {
                "schema": {
                  "allOf": [
                    {
                      "$ref": "#/components/schemas/PaginatedResponse"
                    },
                    {
                      "type": "object",
                      "properties": {
                        "data": {
                          "type": "array",
                          "items": {
                            "$ref": "#/components/schemas/GatewayChargeEvent"
                          }
                        }
                      }
                    }
                  ]
                },
                "example": {
                  "data": [
                    {
                      "id": "f1d6f4a0-1d4e-4a3a-9e0a-1a2b3c4d5e6f",
                      "charge_id": "f1d6f4a0-1d4e-4a3a-9e0a-1a2b3c4d5e6f",
                      "event_type": "charge.created",
                      "data": {},
                      "created_at": "2026-01-31T12:00:00Z"
                    }
                  ],
                  "pagination": {
                    "page": 1,
                    "limit": 20,
                    "total": 150,
                    "has_next": true,
                    "next_cursor": "eyJpZCI6IjEyMyJ9"
                  },
                  "meta": {
                    "request_id": "550e8400-e29b-41d4-a716-446655440000",
                    "timestamp": "2025-03-27T12:00:00Z",
                    "api_version": "4.3.0"
                  }
                }
              }
            },
            "headers": {
              "x-fapi-interaction-id": {
                "$ref": "#/components/headers/XFapiInteractionIdResponse"
              },
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/XRateLimitLimit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/XRateLimitRemaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/XRateLimitReset"
              },
              "Cache-Control": {
                "$ref": "#/components/headers/CacheControl"
              },
              "ETag": {
                "$ref": "#/components/headers/ETag"
              },
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              },
              "traceparent": {
                "$ref": "#/components/headers/Traceparent"
              },
              "Content-Language": {
                "$ref": "#/components/headers/Content-Language"
              }
            }
          },
          "400": {
            "description": "Bad request",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              },
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                },
                "examples": {
                  "error": {
                    "$ref": "#/components/examples/ErrorBadRequest"
                  }
                }
              }
            },
            "headers": {
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/XRateLimitLimit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/XRateLimitRemaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/XRateLimitReset"
              },
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "403": {
            "$ref": "#/components/responses/Forbidden",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "404": {
            "$ref": "#/components/responses/NotFound",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "409": {
            "$ref": "#/components/responses/Conflict",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "429": {
            "$ref": "#/components/responses/TooManyRequests",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "500": {
            "$ref": "#/components/responses/InternalServerError",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          }
        },
        "x-codeSamples": [
          {
            "lang": "cURL",
            "label": "cURL",
            "source": "curl -X GET \"https://api.kangopenbanking.com/v1/gateway/charges/{chargeId}/events\" \\\n  -H \"Authorization: Bearer $KOB_ACCESS_TOKEN\" \\\n  -H \"Content-Type: application/json\""
          },
          {
            "lang": "JavaScript",
            "label": "Node.js",
            "source": "import { KangOpenBanking } from \"@kangopenbanking/sdk\";\n\nconst kob = new KangOpenBanking({ apiKey: process.env.KOB_API_KEY });\nconst res = await kob.request(\"GET\", \"/v1/gateway/charges/{chargeId}/events\");\nconsole.log(res);"
          },
          {
            "lang": "Python",
            "label": "Python",
            "source": "from kangopenbanking import KangOpenBanking\n\nkob = KangOpenBanking(api_key=os.environ[\"KOB_API_KEY\"])\nres = kob.request(\"GET\", \"/v1/gateway/charges/{chargeId}/events\")\nprint(res)"
          },
          {
            "lang": "PHP",
            "label": "PHP",
            "source": "<?php\n$kob = new KangOpenBanking\\KangOpenBanking(getenv('KOB_API_KEY'));\n$res = $kob->request('GET', '/v1/gateway/charges/{chargeId}/events');\nprint_r($res);"
          }
        ]
      }
    },
    "/v1/gateway/reconciliation": {
      "post": {
        "tags": [
          "Payment Gateway"
        ],
        "summary": "Run reconciliation",
        "operationId": "gatewayRunReconciliation",
        "security": [
          {
            "bearerAuth": []
          }
        ],
        "parameters": [
          {
            "name": "Idempotency-Key",
            "in": "header",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid"
            },
            "description": "Required on all POST/PUT endpoints. Unique key for idempotent request processing (UUID v4 recommended). Keys expire after 24 hours."
          },
          {
            "$ref": "#/components/parameters/RequestId"
          },
          {
            "$ref": "#/components/parameters/Traceparent"
          },
          {
            "$ref": "#/components/parameters/Tracestate"
          },
          {
            "$ref": "#/components/parameters/AcceptLanguage"
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "required": [
                  "merchant_id",
                  "period_start",
                  "period_end"
                ],
                "properties": {
                  "merchant_id": {
                    "type": "string",
                    "format": "uuid"
                  },
                  "period_start": {
                    "type": "string",
                    "format": "date"
                  },
                  "period_end": {
                    "type": "string",
                    "format": "date"
                  },
                  "provider": {
                    "type": "string",
                    "enum": [
                      "flutterwave",
                      "stripe",
                      "paypal"
                    ],
                    "description": "Payment provider to reconcile against"
                  }
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Reconciliation started",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/GatewayReconciliationRun"
                },
                "example": {
                  "id": "00000000-0000-4000-8000-000000000000",
                  "merchant_id": "00000000-0000-4000-8000-000000000000",
                  "status": "pending",
                  "matched_count": 0,
                  "mismatched_count": 0,
                  "period_start": "2026-01-01",
                  "period_end": "2026-01-01",
                  "created_at": "2026-01-01T00:00:00Z"
                }
              }
            },
            "headers": {
              "x-fapi-interaction-id": {
                "$ref": "#/components/headers/XFapiInteractionIdResponse"
              },
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/XRateLimitLimit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/XRateLimitRemaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/XRateLimitReset"
              },
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              },
              "X-Idempotent-Replay": {
                "$ref": "#/components/headers/X-Idempotent-Replay"
              },
              "X-Idempotency-Status": {
                "$ref": "#/components/headers/X-Idempotency-Status"
              },
              "traceparent": {
                "$ref": "#/components/headers/Traceparent"
              },
              "Content-Language": {
                "$ref": "#/components/headers/Content-Language"
              }
            }
          },
          "400": {
            "description": "Bad request",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              },
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                },
                "examples": {
                  "error": {
                    "$ref": "#/components/examples/ErrorBadRequest"
                  }
                }
              }
            },
            "headers": {
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/XRateLimitLimit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/XRateLimitRemaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/XRateLimitReset"
              },
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "403": {
            "$ref": "#/components/responses/Forbidden",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "404": {
            "$ref": "#/components/responses/NotFound",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "409": {
            "$ref": "#/components/responses/Conflict",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "429": {
            "$ref": "#/components/responses/TooManyRequests",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "500": {
            "$ref": "#/components/responses/InternalServerError",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          }
        },
        "x-codeSamples": [
          {
            "lang": "cURL",
            "label": "cURL",
            "source": "curl -X POST \"https://api.kangopenbanking.com/v1/gateway/reconciliation\" \\\n  -H \"Authorization: Bearer $KOB_ACCESS_TOKEN\" \\\n  -H \"Content-Type: application/json\" \\\n  -d '{}'"
          },
          {
            "lang": "JavaScript",
            "label": "Node.js",
            "source": "import { KangOpenBanking } from \"@kangopenbanking/sdk\";\n\nconst kob = new KangOpenBanking({ apiKey: process.env.KOB_API_KEY });\nconst res = await kob.request(\"POST\", \"/v1/gateway/reconciliation\", { /* payload */ });\nconsole.log(res);"
          },
          {
            "lang": "Python",
            "label": "Python",
            "source": "from kangopenbanking import KangOpenBanking\n\nkob = KangOpenBanking(api_key=os.environ[\"KOB_API_KEY\"])\nres = kob.request(\"POST\", \"/v1/gateway/reconciliation\", json={})\nprint(res)"
          },
          {
            "lang": "PHP",
            "label": "PHP",
            "source": "<?php\n$kob = new KangOpenBanking\\KangOpenBanking(getenv('KOB_API_KEY'));\n$res = $kob->request('POST', '/v1/gateway/reconciliation', []);\nprint_r($res);"
          }
        ]
      },
      "get": {
        "tags": [
          "Payment Gateway"
        ],
        "summary": "List reconciliation runs",
        "operationId": "gatewayListReconciliationRuns",
        "security": [
          {
            "bearerAuth": []
          }
        ],
        "parameters": [
          {
            "name": "merchant_id",
            "in": "query",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "limit",
            "in": "query",
            "schema": {
              "type": "integer",
              "default": 25,
              "maximum": 100
            },
            "description": "Items per page"
          },
          {
            "name": "offset",
            "in": "query",
            "schema": {
              "type": "integer",
              "default": 0
            },
            "description": "Items to skip"
          },
          {
            "name": "sort_by",
            "in": "query",
            "schema": {
              "type": "string",
              "default": "created_at"
            },
            "description": "Sort field"
          },
          {
            "name": "sort_order",
            "in": "query",
            "schema": {
              "type": "string",
              "enum": [
                "asc",
                "desc"
              ],
              "default": "desc"
            },
            "description": "Sort direction"
          },
          {
            "$ref": "#/components/parameters/StartingAfter"
          },
          {
            "$ref": "#/components/parameters/EndingBefore"
          },
          {
            "$ref": "#/components/parameters/RequestId"
          },
          {
            "$ref": "#/components/parameters/Traceparent"
          },
          {
            "$ref": "#/components/parameters/Tracestate"
          },
          {
            "$ref": "#/components/parameters/AcceptLanguage"
          }
        ],
        "responses": {
          "200": {
            "description": "Reconciliation runs",
            "content": {
              "application/json": {
                "schema": {
                  "allOf": [
                    {
                      "$ref": "#/components/schemas/PaginatedResponse"
                    },
                    {
                      "type": "object",
                      "properties": {
                        "data": {
                          "type": "array",
                          "items": {
                            "$ref": "#/components/schemas/GatewayReconciliationRun"
                          }
                        }
                      }
                    }
                  ]
                },
                "example": {
                  "data": [
                    {
                      "id": "f1d6f4a0-1d4e-4a3a-9e0a-1a2b3c4d5e6f",
                      "merchant_id": "f1d6f4a0-1d4e-4a3a-9e0a-1a2b3c4d5e6f",
                      "status": "pending",
                      "matched_count": 1,
                      "mismatched_count": 1,
                      "period_start": "2026-01-31",
                      "period_end": "2026-01-31",
                      "created_at": "2026-01-31T12:00:00Z"
                    }
                  ],
                  "pagination": {
                    "page": 1,
                    "limit": 20,
                    "total": 150,
                    "has_next": true,
                    "next_cursor": "eyJpZCI6IjEyMyJ9"
                  },
                  "meta": {
                    "request_id": "550e8400-e29b-41d4-a716-446655440000",
                    "timestamp": "2025-03-27T12:00:00Z",
                    "api_version": "4.3.0"
                  }
                }
              }
            },
            "headers": {
              "x-fapi-interaction-id": {
                "$ref": "#/components/headers/XFapiInteractionIdResponse"
              },
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/XRateLimitLimit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/XRateLimitRemaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/XRateLimitReset"
              },
              "Cache-Control": {
                "$ref": "#/components/headers/CacheControl"
              },
              "ETag": {
                "$ref": "#/components/headers/ETag"
              },
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              },
              "traceparent": {
                "$ref": "#/components/headers/Traceparent"
              },
              "Content-Language": {
                "$ref": "#/components/headers/Content-Language"
              }
            }
          },
          "400": {
            "description": "Bad request",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              },
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                },
                "examples": {
                  "error": {
                    "$ref": "#/components/examples/ErrorBadRequest"
                  }
                }
              }
            },
            "headers": {
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/XRateLimitLimit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/XRateLimitRemaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/XRateLimitReset"
              },
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "403": {
            "$ref": "#/components/responses/Forbidden",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "404": {
            "$ref": "#/components/responses/NotFound",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "409": {
            "$ref": "#/components/responses/Conflict",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "429": {
            "$ref": "#/components/responses/TooManyRequests",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "500": {
            "$ref": "#/components/responses/InternalServerError",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          }
        },
        "x-codeSamples": [
          {
            "lang": "cURL",
            "label": "cURL",
            "source": "curl -X GET \"https://api.kangopenbanking.com/v1/gateway/reconciliation\" \\\n  -H \"Authorization: Bearer $KOB_ACCESS_TOKEN\" \\\n  -H \"Content-Type: application/json\""
          },
          {
            "lang": "JavaScript",
            "label": "Node.js",
            "source": "import { KangOpenBanking } from \"@kangopenbanking/sdk\";\n\nconst kob = new KangOpenBanking({ apiKey: process.env.KOB_API_KEY });\nconst res = await kob.request(\"GET\", \"/v1/gateway/reconciliation\");\nconsole.log(res);"
          },
          {
            "lang": "Python",
            "label": "Python",
            "source": "from kangopenbanking import KangOpenBanking\n\nkob = KangOpenBanking(api_key=os.environ[\"KOB_API_KEY\"])\nres = kob.request(\"GET\", \"/v1/gateway/reconciliation\")\nprint(res)"
          },
          {
            "lang": "PHP",
            "label": "PHP",
            "source": "<?php\n$kob = new KangOpenBanking\\KangOpenBanking(getenv('KOB_API_KEY'));\n$res = $kob->request('GET', '/v1/gateway/reconciliation');\nprint_r($res);"
          }
        ]
      }
    },
    "/v1/gateway/reports/fees": {
      "get": {
        "tags": [
          "Payment Gateway"
        ],
        "summary": "Fee report",
        "operationId": "gatewayReportFees",
        "security": [
          {
            "bearerAuth": []
          }
        ],
        "parameters": [
          {
            "name": "merchant_id",
            "in": "query",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "from",
            "in": "query",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "to",
            "in": "query",
            "schema": {
              "type": "string"
            }
          },
          {
            "$ref": "#/components/parameters/RequestId"
          },
          {
            "$ref": "#/components/parameters/Traceparent"
          },
          {
            "$ref": "#/components/parameters/Tracestate"
          },
          {
            "$ref": "#/components/parameters/AcceptLanguage"
          }
        ],
        "responses": {
          "200": {
            "description": "Fee report with totals by channel",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "total_fees": {
                      "type": "number"
                    },
                    "by_channel": {
                      "type": "object",
                      "additionalProperties": {
                        "type": "number"
                      }
                    },
                    "period": {
                      "type": "string"
                    }
                  }
                },
                "example": {
                  "total_fees": 0,
                  "by_channel": {},
                  "period": "string"
                }
              }
            },
            "headers": {
              "x-fapi-interaction-id": {
                "$ref": "#/components/headers/XFapiInteractionIdResponse"
              },
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/XRateLimitLimit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/XRateLimitRemaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/XRateLimitReset"
              },
              "Cache-Control": {
                "$ref": "#/components/headers/CacheControl"
              },
              "ETag": {
                "$ref": "#/components/headers/ETag"
              },
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              },
              "traceparent": {
                "$ref": "#/components/headers/Traceparent"
              },
              "Content-Language": {
                "$ref": "#/components/headers/Content-Language"
              }
            }
          },
          "400": {
            "description": "Bad request",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              },
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                },
                "examples": {
                  "error": {
                    "$ref": "#/components/examples/ErrorBadRequest"
                  }
                }
              }
            },
            "headers": {
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/XRateLimitLimit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/XRateLimitRemaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/XRateLimitReset"
              },
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "403": {
            "$ref": "#/components/responses/Forbidden",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "404": {
            "$ref": "#/components/responses/NotFound",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "409": {
            "$ref": "#/components/responses/Conflict",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "429": {
            "$ref": "#/components/responses/TooManyRequests",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "500": {
            "$ref": "#/components/responses/InternalServerError",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          }
        },
        "x-codeSamples": [
          {
            "lang": "cURL",
            "label": "cURL",
            "source": "curl -X GET \"https://api.kangopenbanking.com/v1/gateway/reports/fees\" \\\n  -H \"Authorization: Bearer $KOB_ACCESS_TOKEN\" \\\n  -H \"Content-Type: application/json\""
          },
          {
            "lang": "JavaScript",
            "label": "Node.js",
            "source": "import { KangOpenBanking } from \"@kangopenbanking/sdk\";\n\nconst kob = new KangOpenBanking({ apiKey: process.env.KOB_API_KEY });\nconst res = await kob.request(\"GET\", \"/v1/gateway/reports/fees\");\nconsole.log(res);"
          },
          {
            "lang": "Python",
            "label": "Python",
            "source": "from kangopenbanking import KangOpenBanking\n\nkob = KangOpenBanking(api_key=os.environ[\"KOB_API_KEY\"])\nres = kob.request(\"GET\", \"/v1/gateway/reports/fees\")\nprint(res)"
          },
          {
            "lang": "PHP",
            "label": "PHP",
            "source": "<?php\n$kob = new KangOpenBanking\\KangOpenBanking(getenv('KOB_API_KEY'));\n$res = $kob->request('GET', '/v1/gateway/reports/fees');\nprint_r($res);"
          }
        ]
      }
    },
    "/v1/gateway/payouts/{payoutId}/retry": {
      "post": {
        "tags": [
          "Payment Gateway"
        ],
        "summary": "Retry failed payout",
        "operationId": "gatewayRetryPayout",
        "security": [
          {
            "bearerAuth": []
          }
        ],
        "parameters": [
          {
            "name": "payoutId",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "Idempotency-Key",
            "in": "header",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid"
            },
            "description": "Required on all POST/PUT endpoints. Unique key for idempotent request processing (UUID v4 recommended). Keys expire after 24 hours."
          },
          {
            "$ref": "#/components/parameters/RequestId"
          },
          {
            "$ref": "#/components/parameters/Traceparent"
          },
          {
            "$ref": "#/components/parameters/Tracestate"
          },
          {
            "$ref": "#/components/parameters/AcceptLanguage"
          }
        ],
        "responses": {
          "200": {
            "description": "Payout retried",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/GatewayPayout"
                },
                "example": {
                  "id": "00000000-0000-4000-8000-000000000000",
                  "merchant_id": "00000000-0000-4000-8000-000000000000",
                  "amount": "10000",
                  "currency": "XAF",
                  "channel": "mobile_money",
                  "status": "pending",
                  "beneficiary_name": "string",
                  "beneficiary_phone": "string",
                  "tx_ref": "string",
                  "created_at": "2026-01-01T00:00:00Z"
                }
              }
            },
            "headers": {
              "x-fapi-interaction-id": {
                "$ref": "#/components/headers/XFapiInteractionIdResponse"
              },
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/XRateLimitLimit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/XRateLimitRemaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/XRateLimitReset"
              },
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              },
              "X-Idempotent-Replay": {
                "$ref": "#/components/headers/X-Idempotent-Replay"
              },
              "X-Idempotency-Status": {
                "$ref": "#/components/headers/X-Idempotency-Status"
              },
              "traceparent": {
                "$ref": "#/components/headers/Traceparent"
              },
              "Content-Language": {
                "$ref": "#/components/headers/Content-Language"
              }
            }
          },
          "400": {
            "description": "Bad request",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              },
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                },
                "examples": {
                  "error": {
                    "$ref": "#/components/examples/ErrorBadRequest"
                  }
                }
              }
            },
            "headers": {
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/XRateLimitLimit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/XRateLimitRemaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/XRateLimitReset"
              },
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "403": {
            "$ref": "#/components/responses/Forbidden",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "404": {
            "$ref": "#/components/responses/NotFound",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "409": {
            "$ref": "#/components/responses/Conflict",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "429": {
            "$ref": "#/components/responses/TooManyRequests",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "500": {
            "$ref": "#/components/responses/InternalServerError",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          }
        },
        "x-codeSamples": [
          {
            "lang": "cURL",
            "label": "cURL",
            "source": "curl -X POST \"https://api.kangopenbanking.com/v1/gateway/payouts/{payoutId}/retry\" \\\n  -H \"Authorization: Bearer $KOB_ACCESS_TOKEN\" \\\n  -H \"Content-Type: application/json\""
          },
          {
            "lang": "JavaScript",
            "label": "Node.js",
            "source": "import { KangOpenBanking } from \"@kangopenbanking/sdk\";\n\nconst kob = new KangOpenBanking({ apiKey: process.env.KOB_API_KEY });\nconst res = await kob.request(\"POST\", \"/v1/gateway/payouts/{payoutId}/retry\");\nconsole.log(res);"
          },
          {
            "lang": "Python",
            "label": "Python",
            "source": "from kangopenbanking import KangOpenBanking\n\nkob = KangOpenBanking(api_key=os.environ[\"KOB_API_KEY\"])\nres = kob.request(\"POST\", \"/v1/gateway/payouts/{payoutId}/retry\")\nprint(res)"
          },
          {
            "lang": "PHP",
            "label": "PHP",
            "source": "<?php\n$kob = new KangOpenBanking\\KangOpenBanking(getenv('KOB_API_KEY'));\n$res = $kob->request('POST', '/v1/gateway/payouts/{payoutId}/retry');\nprint_r($res);"
          }
        ]
      }
    },
    "/v1/merchants": {
      "post": {
        "tags": [
          "Merchant Onboarding"
        ],
        "summary": "Create merchant",
        "operationId": "merchantCreate",
        "security": [
          {
            "bearerAuth": []
          }
        ],
        "parameters": [
          {
            "name": "Idempotency-Key",
            "in": "header",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid"
            },
            "description": "Required on all POST/PUT endpoints. Unique key for idempotent request processing (UUID v4 recommended). Keys expire after 24 hours."
          },
          {
            "$ref": "#/components/parameters/RequestId"
          },
          {
            "$ref": "#/components/parameters/Traceparent"
          },
          {
            "$ref": "#/components/parameters/Tracestate"
          },
          {
            "$ref": "#/components/parameters/AcceptLanguage"
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "required": [
                  "business_name",
                  "business_type",
                  "contact_email"
                ],
                "properties": {
                  "business_name": {
                    "type": "string"
                  },
                  "business_type": {
                    "type": "string"
                  },
                  "contact_email": {
                    "type": "string"
                  },
                  "contact_phone": {
                    "type": "string"
                  },
                  "country": {
                    "type": "string",
                    "default": "CM"
                  },
                  "action": {
                    "type": "string",
                    "enum": [
                      "create",
                      "submit",
                      "activate",
                      "suspend"
                    ],
                    "default": "create"
                  }
                }
              }
            }
          }
        },
        "responses": {
          "201": {
            "description": "Merchant created",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/GatewayMerchant"
                },
                "example": {
                  "id": "00000000-0000-4000-8000-000000000000",
                  "user_id": "00000000-0000-4000-8000-000000000000",
                  "business_name": "string",
                  "business_type": "string",
                  "contact_email": "string",
                  "contact_phone": "string",
                  "country": "CM",
                  "status": "pending",
                  "kyb_status": "not_submitted",
                  "logo_url": "string",
                  "created_at": "2026-01-01T00:00:00Z"
                }
              }
            },
            "headers": {
              "x-fapi-interaction-id": {
                "$ref": "#/components/headers/XFapiInteractionIdResponse"
              },
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/XRateLimitLimit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/XRateLimitRemaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/XRateLimitReset"
              },
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              },
              "traceparent": {
                "$ref": "#/components/headers/Traceparent"
              },
              "Content-Language": {
                "$ref": "#/components/headers/Content-Language"
              }
            }
          },
          "400": {
            "description": "Bad request",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              },
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                },
                "examples": {
                  "error": {
                    "$ref": "#/components/examples/ErrorBadRequest"
                  }
                }
              }
            },
            "headers": {
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/XRateLimitLimit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/XRateLimitRemaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/XRateLimitReset"
              },
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "403": {
            "$ref": "#/components/responses/Forbidden",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "404": {
            "$ref": "#/components/responses/NotFound",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "409": {
            "$ref": "#/components/responses/Conflict",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "429": {
            "$ref": "#/components/responses/TooManyRequests",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "500": {
            "$ref": "#/components/responses/InternalServerError",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          }
        },
        "x-codeSamples": [
          {
            "lang": "cURL",
            "label": "cURL",
            "source": "curl -X POST \"https://api.kangopenbanking.com/v1/merchants\" \\\n  -H \"Authorization: Bearer $KOB_ACCESS_TOKEN\" \\\n  -H \"Content-Type: application/json\" \\\n  -d '{}'"
          },
          {
            "lang": "JavaScript",
            "label": "Node.js",
            "source": "import { KangOpenBanking } from \"@kangopenbanking/sdk\";\n\nconst kob = new KangOpenBanking({ apiKey: process.env.KOB_API_KEY });\nconst res = await kob.request(\"POST\", \"/v1/merchants\", { /* payload */ });\nconsole.log(res);"
          },
          {
            "lang": "Python",
            "label": "Python",
            "source": "from kangopenbanking import KangOpenBanking\n\nkob = KangOpenBanking(api_key=os.environ[\"KOB_API_KEY\"])\nres = kob.request(\"POST\", \"/v1/merchants\", json={})\nprint(res)"
          },
          {
            "lang": "PHP",
            "label": "PHP",
            "source": "<?php\n$kob = new KangOpenBanking\\KangOpenBanking(getenv('KOB_API_KEY'));\n$res = $kob->request('POST', '/v1/merchants', []);\nprint_r($res);"
          }
        ]
      },
      "get": {
        "tags": [
          "Merchant Onboarding"
        ],
        "summary": "List merchants",
        "operationId": "merchantList",
        "security": [
          {
            "bearerAuth": []
          }
        ],
        "parameters": [
          {
            "name": "status",
            "in": "query",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "limit",
            "in": "query",
            "schema": {
              "type": "integer",
              "default": 25,
              "maximum": 100
            },
            "description": "Items per page"
          },
          {
            "name": "offset",
            "in": "query",
            "schema": {
              "type": "integer",
              "default": 0
            },
            "description": "Items to skip"
          },
          {
            "name": "sort_by",
            "in": "query",
            "schema": {
              "type": "string",
              "default": "created_at"
            },
            "description": "Sort field"
          },
          {
            "name": "sort_order",
            "in": "query",
            "schema": {
              "type": "string",
              "enum": [
                "asc",
                "desc"
              ],
              "default": "desc"
            },
            "description": "Sort direction"
          },
          {
            "$ref": "#/components/parameters/StartingAfter"
          },
          {
            "$ref": "#/components/parameters/EndingBefore"
          },
          {
            "$ref": "#/components/parameters/RequestId"
          },
          {
            "$ref": "#/components/parameters/Traceparent"
          },
          {
            "$ref": "#/components/parameters/Tracestate"
          },
          {
            "$ref": "#/components/parameters/AcceptLanguage"
          }
        ],
        "responses": {
          "200": {
            "description": "Merchants",
            "content": {
              "application/json": {
                "schema": {
                  "allOf": [
                    {
                      "$ref": "#/components/schemas/PaginatedResponse"
                    },
                    {
                      "type": "object",
                      "properties": {
                        "data": {
                          "type": "array",
                          "items": {
                            "$ref": "#/components/schemas/GatewayMerchant"
                          }
                        }
                      }
                    }
                  ]
                },
                "example": {
                  "data": [
                    {
                      "id": "f1d6f4a0-1d4e-4a3a-9e0a-1a2b3c4d5e6f",
                      "user_id": "f1d6f4a0-1d4e-4a3a-9e0a-1a2b3c4d5e6f",
                      "business_name": "XAF",
                      "business_type": "XAF",
                      "contact_email": "XAF",
                      "contact_phone": "XAF",
                      "country": "CM",
                      "status": "pending",
                      "kyb_status": "not_submitted",
                      "logo_url": "XAF",
                      "created_at": "2026-01-31T12:00:00Z"
                    }
                  ],
                  "pagination": {
                    "page": 1,
                    "limit": 20,
                    "total": 150,
                    "has_next": true,
                    "next_cursor": "eyJpZCI6IjEyMyJ9"
                  },
                  "meta": {
                    "request_id": "550e8400-e29b-41d4-a716-446655440000",
                    "timestamp": "2025-03-27T12:00:00Z",
                    "api_version": "4.3.0"
                  }
                }
              }
            },
            "headers": {
              "x-fapi-interaction-id": {
                "$ref": "#/components/headers/XFapiInteractionIdResponse"
              },
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/XRateLimitLimit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/XRateLimitRemaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/XRateLimitReset"
              },
              "Cache-Control": {
                "$ref": "#/components/headers/CacheControl"
              },
              "ETag": {
                "$ref": "#/components/headers/ETag"
              },
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              },
              "traceparent": {
                "$ref": "#/components/headers/Traceparent"
              },
              "Content-Language": {
                "$ref": "#/components/headers/Content-Language"
              }
            }
          },
          "400": {
            "description": "Bad request",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              },
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                },
                "examples": {
                  "error": {
                    "$ref": "#/components/examples/ErrorBadRequest"
                  }
                }
              }
            },
            "headers": {
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/XRateLimitLimit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/XRateLimitRemaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/XRateLimitReset"
              },
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "403": {
            "$ref": "#/components/responses/Forbidden",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "404": {
            "$ref": "#/components/responses/NotFound",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "409": {
            "$ref": "#/components/responses/Conflict",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "429": {
            "$ref": "#/components/responses/TooManyRequests",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "500": {
            "$ref": "#/components/responses/InternalServerError",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          }
        },
        "x-codeSamples": [
          {
            "lang": "cURL",
            "label": "cURL",
            "source": "curl -X GET \"https://api.kangopenbanking.com/v1/merchants\" \\\n  -H \"Authorization: Bearer $KOB_ACCESS_TOKEN\" \\\n  -H \"Content-Type: application/json\""
          },
          {
            "lang": "JavaScript",
            "label": "Node.js",
            "source": "import { KangOpenBanking } from \"@kangopenbanking/sdk\";\n\nconst kob = new KangOpenBanking({ apiKey: process.env.KOB_API_KEY });\nconst res = await kob.request(\"GET\", \"/v1/merchants\");\nconsole.log(res);"
          },
          {
            "lang": "Python",
            "label": "Python",
            "source": "from kangopenbanking import KangOpenBanking\n\nkob = KangOpenBanking(api_key=os.environ[\"KOB_API_KEY\"])\nres = kob.request(\"GET\", \"/v1/merchants\")\nprint(res)"
          },
          {
            "lang": "PHP",
            "label": "PHP",
            "source": "<?php\n$kob = new KangOpenBanking\\KangOpenBanking(getenv('KOB_API_KEY'));\n$res = $kob->request('GET', '/v1/merchants');\nprint_r($res);"
          }
        ]
      },
      "patch": {
        "tags": [
          "Merchant Onboarding"
        ],
        "summary": "Update merchant",
        "operationId": "merchantUpdate",
        "security": [
          {
            "bearerAuth": []
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "merchant_id": {
                    "type": "string"
                  },
                  "business_name": {
                    "type": "string"
                  },
                  "contact_email": {
                    "type": "string"
                  },
                  "logo_url": {
                    "type": "string"
                  }
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Merchant updated",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/GatewayMerchant"
                },
                "example": {
                  "id": "00000000-0000-4000-8000-000000000000",
                  "user_id": "00000000-0000-4000-8000-000000000000",
                  "business_name": "string",
                  "business_type": "string",
                  "contact_email": "string",
                  "contact_phone": "string",
                  "country": "CM",
                  "status": "pending",
                  "kyb_status": "not_submitted",
                  "logo_url": "string",
                  "created_at": "2026-01-01T00:00:00Z"
                }
              }
            },
            "headers": {
              "x-fapi-interaction-id": {
                "$ref": "#/components/headers/XFapiInteractionIdResponse"
              },
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/XRateLimitLimit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/XRateLimitRemaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/XRateLimitReset"
              },
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              },
              "traceparent": {
                "$ref": "#/components/headers/Traceparent"
              },
              "Content-Language": {
                "$ref": "#/components/headers/Content-Language"
              }
            }
          },
          "400": {
            "description": "Bad request",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              },
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                },
                "examples": {
                  "error": {
                    "$ref": "#/components/examples/ErrorBadRequest"
                  }
                }
              }
            },
            "headers": {
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/XRateLimitLimit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/XRateLimitRemaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/XRateLimitReset"
              },
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "403": {
            "$ref": "#/components/responses/Forbidden",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "404": {
            "$ref": "#/components/responses/NotFound",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "409": {
            "$ref": "#/components/responses/Conflict",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "429": {
            "$ref": "#/components/responses/TooManyRequests",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "500": {
            "$ref": "#/components/responses/InternalServerError",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          }
        },
        "parameters": [
          {
            "$ref": "#/components/parameters/IdempotencyKey"
          },
          {
            "$ref": "#/components/parameters/RequestId"
          },
          {
            "$ref": "#/components/parameters/Traceparent"
          },
          {
            "$ref": "#/components/parameters/Tracestate"
          },
          {
            "$ref": "#/components/parameters/AcceptLanguage"
          }
        ],
        "x-codeSamples": [
          {
            "lang": "cURL",
            "label": "cURL",
            "source": "curl -X PATCH \"https://api.kangopenbanking.com/v1/merchants\" \\\n  -H \"Authorization: Bearer $KOB_ACCESS_TOKEN\" \\\n  -H \"Content-Type: application/json\" \\\n  -d '{}'"
          },
          {
            "lang": "JavaScript",
            "label": "Node.js",
            "source": "import { KangOpenBanking } from \"@kangopenbanking/sdk\";\n\nconst kob = new KangOpenBanking({ apiKey: process.env.KOB_API_KEY });\nconst res = await kob.request(\"PATCH\", \"/v1/merchants\", { /* payload */ });\nconsole.log(res);"
          },
          {
            "lang": "Python",
            "label": "Python",
            "source": "from kangopenbanking import KangOpenBanking\n\nkob = KangOpenBanking(api_key=os.environ[\"KOB_API_KEY\"])\nres = kob.request(\"PATCH\", \"/v1/merchants\", json={})\nprint(res)"
          },
          {
            "lang": "PHP",
            "label": "PHP",
            "source": "<?php\n$kob = new KangOpenBanking\\KangOpenBanking(getenv('KOB_API_KEY'));\n$res = $kob->request('PATCH', '/v1/merchants', []);\nprint_r($res);"
          }
        ]
      }
    },
    "/v1/merchants/kyb": {
      "post": {
        "tags": [
          "Merchant Onboarding"
        ],
        "summary": "Submit KYB verification",
        "operationId": "merchantSubmitKyb",
        "security": [
          {
            "bearerAuth": []
          }
        ],
        "parameters": [
          {
            "name": "Idempotency-Key",
            "in": "header",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid"
            },
            "description": "Required on all POST/PUT endpoints. Unique key for idempotent request processing (UUID v4 recommended). Keys expire after 24 hours."
          },
          {
            "$ref": "#/components/parameters/RequestId"
          },
          {
            "$ref": "#/components/parameters/Traceparent"
          },
          {
            "$ref": "#/components/parameters/Tracestate"
          },
          {
            "$ref": "#/components/parameters/AcceptLanguage"
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "required": [
                  "merchant_id"
                ],
                "properties": {
                  "merchant_id": {
                    "type": "string"
                  },
                  "registration_number": {
                    "type": "string"
                  },
                  "tax_id": {
                    "type": "string"
                  },
                  "documents": {
                    "type": "array",
                    "items": {
                      "type": "object"
                    }
                  }
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "KYB submitted",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "success": {
                      "type": "boolean",
                      "example": true
                    },
                    "message": {
                      "type": "string"
                    }
                  }
                },
                "example": {
                  "success": true,
                  "message": "string"
                }
              }
            },
            "headers": {
              "x-fapi-interaction-id": {
                "$ref": "#/components/headers/XFapiInteractionIdResponse"
              },
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/XRateLimitLimit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/XRateLimitRemaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/XRateLimitReset"
              },
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              },
              "traceparent": {
                "$ref": "#/components/headers/Traceparent"
              },
              "Content-Language": {
                "$ref": "#/components/headers/Content-Language"
              }
            }
          },
          "400": {
            "description": "Bad request",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              },
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                },
                "examples": {
                  "error": {
                    "$ref": "#/components/examples/ErrorBadRequest"
                  }
                }
              }
            },
            "headers": {
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/XRateLimitLimit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/XRateLimitRemaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/XRateLimitReset"
              },
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "403": {
            "$ref": "#/components/responses/Forbidden",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "404": {
            "$ref": "#/components/responses/NotFound",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "409": {
            "$ref": "#/components/responses/Conflict",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "429": {
            "$ref": "#/components/responses/TooManyRequests",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "500": {
            "$ref": "#/components/responses/InternalServerError",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          }
        },
        "x-codeSamples": [
          {
            "lang": "cURL",
            "label": "cURL",
            "source": "curl -X POST \"https://api.kangopenbanking.com/v1/merchants/kyb\" \\\n  -H \"Authorization: Bearer $KOB_ACCESS_TOKEN\" \\\n  -H \"Content-Type: application/json\" \\\n  -d '{}'"
          },
          {
            "lang": "JavaScript",
            "label": "Node.js",
            "source": "import { KangOpenBanking } from \"@kangopenbanking/sdk\";\n\nconst kob = new KangOpenBanking({ apiKey: process.env.KOB_API_KEY });\nconst res = await kob.request(\"POST\", \"/v1/merchants/kyb\", { /* payload */ });\nconsole.log(res);"
          },
          {
            "lang": "Python",
            "label": "Python",
            "source": "from kangopenbanking import KangOpenBanking\n\nkob = KangOpenBanking(api_key=os.environ[\"KOB_API_KEY\"])\nres = kob.request(\"POST\", \"/v1/merchants/kyb\", json={})\nprint(res)"
          },
          {
            "lang": "PHP",
            "label": "PHP",
            "source": "<?php\n$kob = new KangOpenBanking\\KangOpenBanking(getenv('KOB_API_KEY'));\n$res = $kob->request('POST', '/v1/merchants/kyb', []);\nprint_r($res);"
          }
        ]
      },
      "get": {
        "tags": [
          "Merchant Onboarding"
        ],
        "summary": "Get KYB status",
        "operationId": "merchantGetKyb",
        "security": [
          {
            "bearerAuth": []
          }
        ],
        "parameters": [
          {
            "name": "merchant_id",
            "in": "query",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "$ref": "#/components/parameters/RequestId"
          },
          {
            "$ref": "#/components/parameters/Traceparent"
          },
          {
            "$ref": "#/components/parameters/Tracestate"
          },
          {
            "$ref": "#/components/parameters/AcceptLanguage"
          }
        ],
        "responses": {
          "200": {
            "description": "KYB verification status",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "merchant_id": {
                      "type": "string"
                    },
                    "kyb_status": {
                      "type": "string",
                      "enum": [
                        "not_submitted",
                        "pending",
                        "approved",
                        "rejected"
                      ]
                    },
                    "submitted_at": {
                      "type": "string",
                      "format": "date-time"
                    },
                    "reviewed_at": {
                      "type": "string",
                      "format": "date-time"
                    }
                  }
                },
                "example": {
                  "merchant_id": "string",
                  "kyb_status": "not_submitted",
                  "submitted_at": "2026-01-01T00:00:00Z",
                  "reviewed_at": "2026-01-01T00:00:00Z"
                }
              }
            },
            "headers": {
              "x-fapi-interaction-id": {
                "$ref": "#/components/headers/XFapiInteractionIdResponse"
              },
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/XRateLimitLimit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/XRateLimitRemaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/XRateLimitReset"
              },
              "Cache-Control": {
                "$ref": "#/components/headers/CacheControl"
              },
              "ETag": {
                "$ref": "#/components/headers/ETag"
              },
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              },
              "traceparent": {
                "$ref": "#/components/headers/Traceparent"
              },
              "Content-Language": {
                "$ref": "#/components/headers/Content-Language"
              }
            }
          },
          "400": {
            "description": "Bad request",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              },
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                },
                "examples": {
                  "error": {
                    "$ref": "#/components/examples/ErrorBadRequest"
                  }
                }
              }
            },
            "headers": {
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/XRateLimitLimit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/XRateLimitRemaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/XRateLimitReset"
              },
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "403": {
            "$ref": "#/components/responses/Forbidden",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "404": {
            "$ref": "#/components/responses/NotFound",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "409": {
            "$ref": "#/components/responses/Conflict",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "429": {
            "$ref": "#/components/responses/TooManyRequests",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "500": {
            "$ref": "#/components/responses/InternalServerError",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          }
        },
        "x-codeSamples": [
          {
            "lang": "cURL",
            "label": "cURL",
            "source": "curl -X GET \"https://api.kangopenbanking.com/v1/merchants/kyb\" \\\n  -H \"Authorization: Bearer $KOB_ACCESS_TOKEN\" \\\n  -H \"Content-Type: application/json\""
          },
          {
            "lang": "JavaScript",
            "label": "Node.js",
            "source": "import { KangOpenBanking } from \"@kangopenbanking/sdk\";\n\nconst kob = new KangOpenBanking({ apiKey: process.env.KOB_API_KEY });\nconst res = await kob.request(\"GET\", \"/v1/merchants/kyb\");\nconsole.log(res);"
          },
          {
            "lang": "Python",
            "label": "Python",
            "source": "from kangopenbanking import KangOpenBanking\n\nkob = KangOpenBanking(api_key=os.environ[\"KOB_API_KEY\"])\nres = kob.request(\"GET\", \"/v1/merchants/kyb\")\nprint(res)"
          },
          {
            "lang": "PHP",
            "label": "PHP",
            "source": "<?php\n$kob = new KangOpenBanking\\KangOpenBanking(getenv('KOB_API_KEY'));\n$res = $kob->request('GET', '/v1/merchants/kyb');\nprint_r($res);"
          }
        ]
      }
    },
    "/v1/merchants/api-keys": {
      "post": {
        "tags": [
          "Merchant Onboarding"
        ],
        "summary": "Issue API key",
        "operationId": "merchantIssueApiKey",
        "security": [
          {
            "bearerAuth": []
          }
        ],
        "parameters": [
          {
            "name": "Idempotency-Key",
            "in": "header",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid"
            },
            "description": "Required on all POST/PUT endpoints. Unique key for idempotent request processing (UUID v4 recommended). Keys expire after 24 hours."
          },
          {
            "$ref": "#/components/parameters/RequestId"
          },
          {
            "$ref": "#/components/parameters/Traceparent"
          },
          {
            "$ref": "#/components/parameters/Tracestate"
          },
          {
            "$ref": "#/components/parameters/AcceptLanguage"
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "required": [
                  "merchant_id"
                ],
                "properties": {
                  "merchant_id": {
                    "type": "string"
                  },
                  "environment": {
                    "type": "string",
                    "enum": [
                      "sandbox",
                      "production"
                    ]
                  }
                }
              }
            }
          }
        },
        "responses": {
          "201": {
            "description": "API key issued",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "id": {
                      "type": "string"
                    },
                    "public_key": {
                      "type": "string"
                    },
                    "secret_key": {
                      "type": "string",
                      "description": "Shown only once"
                    },
                    "environment": {
                      "type": "string"
                    },
                    "label": {
                      "type": "string"
                    }
                  }
                },
                "example": {
                  "id": "string",
                  "public_key": "string",
                  "secret_key": "string",
                  "environment": "string",
                  "label": "string"
                }
              }
            },
            "headers": {
              "x-fapi-interaction-id": {
                "$ref": "#/components/headers/XFapiInteractionIdResponse"
              },
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/XRateLimitLimit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/XRateLimitRemaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/XRateLimitReset"
              },
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              },
              "traceparent": {
                "$ref": "#/components/headers/Traceparent"
              },
              "Content-Language": {
                "$ref": "#/components/headers/Content-Language"
              }
            }
          },
          "400": {
            "description": "Bad request",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              },
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                },
                "examples": {
                  "error": {
                    "$ref": "#/components/examples/ErrorBadRequest"
                  }
                }
              }
            },
            "headers": {
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/XRateLimitLimit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/XRateLimitRemaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/XRateLimitReset"
              },
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "403": {
            "$ref": "#/components/responses/Forbidden",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "404": {
            "$ref": "#/components/responses/NotFound",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "409": {
            "$ref": "#/components/responses/Conflict",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "429": {
            "$ref": "#/components/responses/TooManyRequests",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "500": {
            "$ref": "#/components/responses/InternalServerError",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          }
        },
        "x-codeSamples": [
          {
            "lang": "cURL",
            "label": "cURL",
            "source": "curl -X POST \"https://api.kangopenbanking.com/v1/merchants/api-keys\" \\\n  -H \"Authorization: Bearer $KOB_ACCESS_TOKEN\" \\\n  -H \"Content-Type: application/json\" \\\n  -d '{}'"
          },
          {
            "lang": "JavaScript",
            "label": "Node.js",
            "source": "import { KangOpenBanking } from \"@kangopenbanking/sdk\";\n\nconst kob = new KangOpenBanking({ apiKey: process.env.KOB_API_KEY });\nconst res = await kob.request(\"POST\", \"/v1/merchants/api-keys\", { /* payload */ });\nconsole.log(res);"
          },
          {
            "lang": "Python",
            "label": "Python",
            "source": "from kangopenbanking import KangOpenBanking\n\nkob = KangOpenBanking(api_key=os.environ[\"KOB_API_KEY\"])\nres = kob.request(\"POST\", \"/v1/merchants/api-keys\", json={})\nprint(res)"
          },
          {
            "lang": "PHP",
            "label": "PHP",
            "source": "<?php\n$kob = new KangOpenBanking\\KangOpenBanking(getenv('KOB_API_KEY'));\n$res = $kob->request('POST', '/v1/merchants/api-keys', []);\nprint_r($res);"
          }
        ]
      },
      "get": {
        "tags": [
          "Merchant Onboarding"
        ],
        "summary": "List API keys",
        "operationId": "merchantListApiKeys",
        "security": [
          {
            "bearerAuth": []
          }
        ],
        "parameters": [
          {
            "name": "merchant_id",
            "in": "query",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "$ref": "#/components/parameters/RequestId"
          },
          {
            "$ref": "#/components/parameters/Traceparent"
          },
          {
            "$ref": "#/components/parameters/Tracestate"
          },
          {
            "$ref": "#/components/parameters/AcceptLanguage"
          }
        ],
        "responses": {
          "200": {
            "description": "API keys list",
            "content": {
              "application/json": {
                "schema": {
                  "allOf": [
                    {
                      "$ref": "#/components/schemas/PaginatedResponse"
                    },
                    {
                      "type": "object",
                      "properties": {
                        "data": {
                          "type": "array",
                          "items": {}
                        }
                      }
                    }
                  ]
                },
                "example": {
                  "data": [
                    {}
                  ],
                  "pagination": {
                    "page": 1,
                    "limit": 20,
                    "total": 150,
                    "has_next": true,
                    "next_cursor": "eyJpZCI6IjEyMyJ9"
                  },
                  "meta": {
                    "request_id": "550e8400-e29b-41d4-a716-446655440000",
                    "timestamp": "2025-03-27T12:00:00Z",
                    "api_version": "4.3.0"
                  }
                }
              }
            },
            "headers": {
              "x-fapi-interaction-id": {
                "$ref": "#/components/headers/XFapiInteractionIdResponse"
              },
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/XRateLimitLimit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/XRateLimitRemaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/XRateLimitReset"
              },
              "Cache-Control": {
                "$ref": "#/components/headers/CacheControl"
              },
              "ETag": {
                "$ref": "#/components/headers/ETag"
              },
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              },
              "traceparent": {
                "$ref": "#/components/headers/Traceparent"
              },
              "Content-Language": {
                "$ref": "#/components/headers/Content-Language"
              }
            }
          },
          "400": {
            "description": "Bad request",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              },
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                },
                "examples": {
                  "error": {
                    "$ref": "#/components/examples/ErrorBadRequest"
                  }
                }
              }
            },
            "headers": {
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/XRateLimitLimit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/XRateLimitRemaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/XRateLimitReset"
              },
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "403": {
            "$ref": "#/components/responses/Forbidden",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "404": {
            "$ref": "#/components/responses/NotFound",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "409": {
            "$ref": "#/components/responses/Conflict",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "429": {
            "$ref": "#/components/responses/TooManyRequests",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "500": {
            "$ref": "#/components/responses/InternalServerError",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          }
        },
        "x-codeSamples": [
          {
            "lang": "cURL",
            "label": "cURL",
            "source": "curl -X GET \"https://api.kangopenbanking.com/v1/merchants/api-keys\" \\\n  -H \"Authorization: Bearer $KOB_ACCESS_TOKEN\" \\\n  -H \"Content-Type: application/json\""
          },
          {
            "lang": "JavaScript",
            "label": "Node.js",
            "source": "import { KangOpenBanking } from \"@kangopenbanking/sdk\";\n\nconst kob = new KangOpenBanking({ apiKey: process.env.KOB_API_KEY });\nconst res = await kob.request(\"GET\", \"/v1/merchants/api-keys\");\nconsole.log(res);"
          },
          {
            "lang": "Python",
            "label": "Python",
            "source": "from kangopenbanking import KangOpenBanking\n\nkob = KangOpenBanking(api_key=os.environ[\"KOB_API_KEY\"])\nres = kob.request(\"GET\", \"/v1/merchants/api-keys\")\nprint(res)"
          },
          {
            "lang": "PHP",
            "label": "PHP",
            "source": "<?php\n$kob = new KangOpenBanking\\KangOpenBanking(getenv('KOB_API_KEY'));\n$res = $kob->request('GET', '/v1/merchants/api-keys');\nprint_r($res);"
          }
        ]
      },
      "delete": {
        "tags": [
          "Merchant Onboarding"
        ],
        "summary": "Revoke API key",
        "operationId": "merchantRevokeApiKey",
        "security": [
          {
            "bearerAuth": []
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "required": [
                  "key_id"
                ],
                "properties": {
                  "key_id": {
                    "type": "string"
                  }
                }
              }
            }
          }
        },
        "responses": {
          "204": {
            "description": "API key revoked",
            "headers": {
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/XRateLimitLimit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/XRateLimitRemaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/XRateLimitReset"
              },
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              },
              "traceparent": {
                "$ref": "#/components/headers/Traceparent"
              },
              "Content-Language": {
                "$ref": "#/components/headers/Content-Language"
              }
            }
          },
          "400": {
            "description": "Bad request",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              },
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                },
                "examples": {
                  "error": {
                    "$ref": "#/components/examples/ErrorBadRequest"
                  }
                }
              }
            },
            "headers": {
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/XRateLimitLimit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/XRateLimitRemaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/XRateLimitReset"
              },
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "403": {
            "$ref": "#/components/responses/Forbidden",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "404": {
            "$ref": "#/components/responses/NotFound",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "409": {
            "$ref": "#/components/responses/Conflict",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "429": {
            "$ref": "#/components/responses/TooManyRequests",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "500": {
            "$ref": "#/components/responses/InternalServerError",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          }
        },
        "parameters": [
          {
            "$ref": "#/components/parameters/RequestId"
          },
          {
            "$ref": "#/components/parameters/Traceparent"
          },
          {
            "$ref": "#/components/parameters/Tracestate"
          },
          {
            "$ref": "#/components/parameters/AcceptLanguage"
          }
        ],
        "x-codeSamples": [
          {
            "lang": "cURL",
            "label": "cURL",
            "source": "curl -X DELETE \"https://api.kangopenbanking.com/v1/merchants/api-keys\" \\\n  -H \"Authorization: Bearer $KOB_ACCESS_TOKEN\" \\\n  -H \"Content-Type: application/json\" \\\n  -d '{}'"
          },
          {
            "lang": "JavaScript",
            "label": "Node.js",
            "source": "import { KangOpenBanking } from \"@kangopenbanking/sdk\";\n\nconst kob = new KangOpenBanking({ apiKey: process.env.KOB_API_KEY });\nconst res = await kob.request(\"DELETE\", \"/v1/merchants/api-keys\", { /* payload */ });\nconsole.log(res);"
          },
          {
            "lang": "Python",
            "label": "Python",
            "source": "from kangopenbanking import KangOpenBanking\n\nkob = KangOpenBanking(api_key=os.environ[\"KOB_API_KEY\"])\nres = kob.request(\"DELETE\", \"/v1/merchants/api-keys\", json={})\nprint(res)"
          },
          {
            "lang": "PHP",
            "label": "PHP",
            "source": "<?php\n$kob = new KangOpenBanking\\KangOpenBanking(getenv('KOB_API_KEY'));\n$res = $kob->request('DELETE', '/v1/merchants/api-keys', []);\nprint_r($res);"
          }
        ]
      }
    },
    "/v1/merchants/settlement-accounts": {
      "post": {
        "tags": [
          "Merchant Onboarding"
        ],
        "summary": "Add settlement account",
        "operationId": "merchantAddSettlementAccount",
        "security": [
          {
            "bearerAuth": []
          }
        ],
        "parameters": [
          {
            "name": "Idempotency-Key",
            "in": "header",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid"
            },
            "description": "Required on all POST/PUT endpoints. Unique key for idempotent request processing (UUID v4 recommended). Keys expire after 24 hours."
          },
          {
            "$ref": "#/components/parameters/RequestId"
          },
          {
            "$ref": "#/components/parameters/Traceparent"
          },
          {
            "$ref": "#/components/parameters/Tracestate"
          },
          {
            "$ref": "#/components/parameters/AcceptLanguage"
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "required": [
                  "merchant_id",
                  "account_number",
                  "bank_code"
                ],
                "properties": {
                  "merchant_id": {
                    "type": "string"
                  },
                  "account_number": {
                    "type": "string"
                  },
                  "bank_code": {
                    "type": "string"
                  },
                  "bank_name": {
                    "type": "string"
                  },
                  "currency": {
                    "type": "string",
                    "default": "XAF",
                    "enum": [
                      "XAF",
                      "XOF",
                      "USD",
                      "EUR",
                      "GBP",
                      "CNY",
                      "NGN",
                      "GHS",
                      "KES",
                      "ZAR"
                    ],
                    "description": "ISO 4217 currency code. Default is XAF (Central African CFA Franc)."
                  }
                }
              }
            }
          }
        },
        "responses": {
          "201": {
            "description": "Settlement account added",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "success": {
                      "type": "boolean",
                      "example": true
                    },
                    "message": {
                      "type": "string"
                    }
                  }
                },
                "example": {
                  "success": true,
                  "message": "string"
                }
              }
            },
            "headers": {
              "x-fapi-interaction-id": {
                "$ref": "#/components/headers/XFapiInteractionIdResponse"
              },
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/XRateLimitLimit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/XRateLimitRemaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/XRateLimitReset"
              },
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              },
              "traceparent": {
                "$ref": "#/components/headers/Traceparent"
              },
              "Content-Language": {
                "$ref": "#/components/headers/Content-Language"
              }
            }
          },
          "400": {
            "description": "Bad request",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              },
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                },
                "examples": {
                  "error": {
                    "$ref": "#/components/examples/ErrorBadRequest"
                  }
                }
              }
            },
            "headers": {
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/XRateLimitLimit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/XRateLimitRemaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/XRateLimitReset"
              },
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "403": {
            "$ref": "#/components/responses/Forbidden",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "404": {
            "$ref": "#/components/responses/NotFound",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "409": {
            "$ref": "#/components/responses/Conflict",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "429": {
            "$ref": "#/components/responses/TooManyRequests",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "500": {
            "$ref": "#/components/responses/InternalServerError",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          }
        },
        "x-codeSamples": [
          {
            "lang": "cURL",
            "label": "cURL",
            "source": "curl -X POST \"https://api.kangopenbanking.com/v1/merchants/settlement-accounts\" \\\n  -H \"Authorization: Bearer $KOB_ACCESS_TOKEN\" \\\n  -H \"Content-Type: application/json\" \\\n  -d '{}'"
          },
          {
            "lang": "JavaScript",
            "label": "Node.js",
            "source": "import { KangOpenBanking } from \"@kangopenbanking/sdk\";\n\nconst kob = new KangOpenBanking({ apiKey: process.env.KOB_API_KEY });\nconst res = await kob.request(\"POST\", \"/v1/merchants/settlement-accounts\", { /* payload */ });\nconsole.log(res);"
          },
          {
            "lang": "Python",
            "label": "Python",
            "source": "from kangopenbanking import KangOpenBanking\n\nkob = KangOpenBanking(api_key=os.environ[\"KOB_API_KEY\"])\nres = kob.request(\"POST\", \"/v1/merchants/settlement-accounts\", json={})\nprint(res)"
          },
          {
            "lang": "PHP",
            "label": "PHP",
            "source": "<?php\n$kob = new KangOpenBanking\\KangOpenBanking(getenv('KOB_API_KEY'));\n$res = $kob->request('POST', '/v1/merchants/settlement-accounts', []);\nprint_r($res);"
          }
        ]
      },
      "get": {
        "tags": [
          "Merchant Onboarding"
        ],
        "summary": "List settlement accounts",
        "operationId": "merchantListSettlementAccounts",
        "security": [
          {
            "bearerAuth": []
          }
        ],
        "parameters": [
          {
            "name": "merchant_id",
            "in": "query",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "$ref": "#/components/parameters/RequestId"
          },
          {
            "$ref": "#/components/parameters/Traceparent"
          },
          {
            "$ref": "#/components/parameters/Tracestate"
          },
          {
            "$ref": "#/components/parameters/AcceptLanguage"
          }
        ],
        "responses": {
          "200": {
            "description": "Settlement accounts",
            "content": {
              "application/json": {
                "schema": {
                  "allOf": [
                    {
                      "$ref": "#/components/schemas/PaginatedResponse"
                    },
                    {
                      "type": "object",
                      "properties": {
                        "data": {
                          "type": "array",
                          "items": {}
                        }
                      }
                    }
                  ]
                },
                "example": {
                  "data": [
                    {}
                  ],
                  "pagination": {
                    "page": 1,
                    "limit": 20,
                    "total": 150,
                    "has_next": true,
                    "next_cursor": "eyJpZCI6IjEyMyJ9"
                  },
                  "meta": {
                    "request_id": "550e8400-e29b-41d4-a716-446655440000",
                    "timestamp": "2025-03-27T12:00:00Z",
                    "api_version": "4.3.0"
                  }
                }
              }
            },
            "headers": {
              "x-fapi-interaction-id": {
                "$ref": "#/components/headers/XFapiInteractionIdResponse"
              },
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/XRateLimitLimit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/XRateLimitRemaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/XRateLimitReset"
              },
              "Cache-Control": {
                "$ref": "#/components/headers/CacheControl"
              },
              "ETag": {
                "$ref": "#/components/headers/ETag"
              },
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              },
              "traceparent": {
                "$ref": "#/components/headers/Traceparent"
              },
              "Content-Language": {
                "$ref": "#/components/headers/Content-Language"
              }
            }
          },
          "400": {
            "description": "Bad request",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              },
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                },
                "examples": {
                  "error": {
                    "$ref": "#/components/examples/ErrorBadRequest"
                  }
                }
              }
            },
            "headers": {
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/XRateLimitLimit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/XRateLimitRemaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/XRateLimitReset"
              },
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "403": {
            "$ref": "#/components/responses/Forbidden",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "404": {
            "$ref": "#/components/responses/NotFound",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "409": {
            "$ref": "#/components/responses/Conflict",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "429": {
            "$ref": "#/components/responses/TooManyRequests",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "500": {
            "$ref": "#/components/responses/InternalServerError",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          }
        },
        "x-codeSamples": [
          {
            "lang": "cURL",
            "label": "cURL",
            "source": "curl -X GET \"https://api.kangopenbanking.com/v1/merchants/settlement-accounts\" \\\n  -H \"Authorization: Bearer $KOB_ACCESS_TOKEN\" \\\n  -H \"Content-Type: application/json\""
          },
          {
            "lang": "JavaScript",
            "label": "Node.js",
            "source": "import { KangOpenBanking } from \"@kangopenbanking/sdk\";\n\nconst kob = new KangOpenBanking({ apiKey: process.env.KOB_API_KEY });\nconst res = await kob.request(\"GET\", \"/v1/merchants/settlement-accounts\");\nconsole.log(res);"
          },
          {
            "lang": "Python",
            "label": "Python",
            "source": "from kangopenbanking import KangOpenBanking\n\nkob = KangOpenBanking(api_key=os.environ[\"KOB_API_KEY\"])\nres = kob.request(\"GET\", \"/v1/merchants/settlement-accounts\")\nprint(res)"
          },
          {
            "lang": "PHP",
            "label": "PHP",
            "source": "<?php\n$kob = new KangOpenBanking\\KangOpenBanking(getenv('KOB_API_KEY'));\n$res = $kob->request('GET', '/v1/merchants/settlement-accounts');\nprint_r($res);"
          }
        ]
      }
    },
    "/v1/merchants/webhooks": {
      "post": {
        "tags": [
          "Merchant Onboarding"
        ],
        "summary": "Register merchant webhook",
        "operationId": "merchantRegisterWebhook",
        "security": [
          {
            "bearerAuth": []
          }
        ],
        "parameters": [
          {
            "name": "Idempotency-Key",
            "in": "header",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid"
            },
            "description": "Required on all POST/PUT endpoints. Unique key for idempotent request processing (UUID v4 recommended). Keys expire after 24 hours."
          },
          {
            "$ref": "#/components/parameters/RequestId"
          },
          {
            "$ref": "#/components/parameters/Traceparent"
          },
          {
            "$ref": "#/components/parameters/Tracestate"
          },
          {
            "$ref": "#/components/parameters/AcceptLanguage"
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "required": [
                  "merchant_id",
                  "url",
                  "events"
                ],
                "properties": {
                  "merchant_id": {
                    "type": "string"
                  },
                  "url": {
                    "type": "string",
                    "format": "uri"
                  },
                  "events": {
                    "type": "array",
                    "items": {
                      "type": "string"
                    }
                  }
                }
              }
            }
          }
        },
        "responses": {
          "201": {
            "description": "Webhook registered",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "id": {
                      "type": "string",
                      "format": "uuid"
                    },
                    "url": {
                      "type": "string"
                    },
                    "events": {
                      "type": "array",
                      "items": {
                        "type": "string"
                      }
                    },
                    "secret": {
                      "type": "string",
                      "description": "HMAC secret — shown once"
                    },
                    "status": {
                      "type": "string"
                    },
                    "created_at": {
                      "type": "string",
                      "format": "date-time"
                    }
                  }
                },
                "example": {
                  "id": "00000000-0000-4000-8000-000000000000",
                  "url": "string",
                  "events": [
                    "string"
                  ],
                  "secret": "string",
                  "status": "string",
                  "created_at": "2026-01-01T00:00:00Z"
                }
              }
            },
            "headers": {
              "x-fapi-interaction-id": {
                "$ref": "#/components/headers/XFapiInteractionIdResponse"
              },
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/XRateLimitLimit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/XRateLimitRemaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/XRateLimitReset"
              },
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              },
              "traceparent": {
                "$ref": "#/components/headers/Traceparent"
              },
              "Content-Language": {
                "$ref": "#/components/headers/Content-Language"
              }
            }
          },
          "400": {
            "description": "Bad request",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              },
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                },
                "examples": {
                  "error": {
                    "$ref": "#/components/examples/ErrorBadRequest"
                  }
                }
              }
            },
            "headers": {
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/XRateLimitLimit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/XRateLimitRemaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/XRateLimitReset"
              },
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "403": {
            "$ref": "#/components/responses/Forbidden",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "404": {
            "$ref": "#/components/responses/NotFound",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "409": {
            "$ref": "#/components/responses/Conflict",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "429": {
            "$ref": "#/components/responses/TooManyRequests",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "500": {
            "$ref": "#/components/responses/InternalServerError",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          }
        },
        "deprecated": true,
        "x-sunset-date": "2026-12-31",
        "x-successor": "/v1/webhooks/v2/endpoints",
        "x-codeSamples": [
          {
            "lang": "cURL",
            "label": "cURL",
            "source": "curl -X POST \"https://api.kangopenbanking.com/v1/merchants/webhooks\" \\\n  -H \"Authorization: Bearer $KOB_ACCESS_TOKEN\" \\\n  -H \"Content-Type: application/json\" \\\n  -d '{}'"
          },
          {
            "lang": "JavaScript",
            "label": "Node.js",
            "source": "import { KangOpenBanking } from \"@kangopenbanking/sdk\";\n\nconst kob = new KangOpenBanking({ apiKey: process.env.KOB_API_KEY });\nconst res = await kob.request(\"POST\", \"/v1/merchants/webhooks\", { /* payload */ });\nconsole.log(res);"
          },
          {
            "lang": "Python",
            "label": "Python",
            "source": "from kangopenbanking import KangOpenBanking\n\nkob = KangOpenBanking(api_key=os.environ[\"KOB_API_KEY\"])\nres = kob.request(\"POST\", \"/v1/merchants/webhooks\", json={})\nprint(res)"
          },
          {
            "lang": "PHP",
            "label": "PHP",
            "source": "<?php\n$kob = new KangOpenBanking\\KangOpenBanking(getenv('KOB_API_KEY'));\n$res = $kob->request('POST', '/v1/merchants/webhooks', []);\nprint_r($res);"
          }
        ],
        "description": "**Deprecated.** Use Webhooks v2 (`/v1/webhooks/v2/endpoints`). Sunset: 2026-12-31.\n\nRegister merchant webhook.\n\n**Tag:** Merchant Onboarding\n\nAuthenticate with a bearer token issued by `/v1/oauth/token`. All state-changing requests\n(POST, PUT, PATCH, DELETE) MUST include an `Idempotency-Key` header (UUID v4) to make\nretries safe — Kang will return the original response for any duplicate key within 24 hours.\n\nErrors follow [RFC 7807](https://datatracker.ietf.org/doc/html/rfc7807) and are returned with\n`Content-Type: application/problem+json`. The `code` field is stable and machine-readable.\nRate-limit headers (`X-RateLimit-Limit`, `X-RateLimit-Remaining`, `X-RateLimit-Reset`)\nare present on every response.\n\n**Migration:** Replace with `webhookV2Create`. Move the endpoint to Webhooks v2 and verify the timestamped `X-Webhook-Signature` described in the webhook definitions.",
        "x-replacement-operation-ids": [
          "webhookV2Create"
        ],
        "x-migration-guide": "Move the endpoint to Webhooks v2 and verify the timestamped `X-Webhook-Signature` described in the webhook definitions."
      },
      "get": {
        "tags": [
          "Merchant Onboarding"
        ],
        "summary": "List merchant webhooks",
        "operationId": "merchantListWebhooks",
        "security": [
          {
            "bearerAuth": []
          }
        ],
        "parameters": [
          {
            "name": "merchant_id",
            "in": "query",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "$ref": "#/components/parameters/RequestId"
          },
          {
            "$ref": "#/components/parameters/Traceparent"
          },
          {
            "$ref": "#/components/parameters/Tracestate"
          },
          {
            "$ref": "#/components/parameters/AcceptLanguage"
          }
        ],
        "responses": {
          "200": {
            "description": "Merchant webhooks",
            "content": {
              "application/json": {
                "schema": {
                  "allOf": [
                    {
                      "$ref": "#/components/schemas/PaginatedResponse"
                    },
                    {
                      "type": "object",
                      "properties": {
                        "data": {
                          "type": "array",
                          "items": {
                            "$ref": "#/components/schemas/Webhook"
                          }
                        }
                      }
                    }
                  ]
                },
                "example": {
                  "data": [
                    {
                      "webhook_id": "f1d6f4a0-1d4e-4a3a-9e0a-1a2b3c4d5e6f",
                      "url": "https://example.com/callback",
                      "events": [
                        {
                          "id": "evt_a1b2c3d4-e5f6-7890-abcd-ef1234567890",
                          "event": "charge.created",
                          "created_at": "2025-03-27T14:32:00Z",
                          "api_version": "4.6.0",
                          "livemode": true,
                          "data": {},
                          "metadata": {}
                        }
                      ],
                      "is_active": false,
                      "secret": "XAF"
                    }
                  ],
                  "pagination": {
                    "page": 1,
                    "limit": 20,
                    "total": 150,
                    "has_next": true,
                    "next_cursor": "eyJpZCI6IjEyMyJ9"
                  },
                  "meta": {
                    "request_id": "550e8400-e29b-41d4-a716-446655440000",
                    "timestamp": "2025-03-27T12:00:00Z",
                    "api_version": "4.3.0"
                  }
                }
              }
            },
            "headers": {
              "x-fapi-interaction-id": {
                "$ref": "#/components/headers/XFapiInteractionIdResponse"
              },
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/XRateLimitLimit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/XRateLimitRemaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/XRateLimitReset"
              },
              "Cache-Control": {
                "$ref": "#/components/headers/CacheControl"
              },
              "ETag": {
                "$ref": "#/components/headers/ETag"
              },
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              },
              "traceparent": {
                "$ref": "#/components/headers/Traceparent"
              },
              "Content-Language": {
                "$ref": "#/components/headers/Content-Language"
              }
            }
          },
          "400": {
            "description": "Bad request",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              },
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                },
                "examples": {
                  "error": {
                    "$ref": "#/components/examples/ErrorBadRequest"
                  }
                }
              }
            },
            "headers": {
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/XRateLimitLimit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/XRateLimitRemaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/XRateLimitReset"
              },
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "403": {
            "$ref": "#/components/responses/Forbidden",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "404": {
            "$ref": "#/components/responses/NotFound",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "409": {
            "$ref": "#/components/responses/Conflict",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "429": {
            "$ref": "#/components/responses/TooManyRequests",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "500": {
            "$ref": "#/components/responses/InternalServerError",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          }
        },
        "deprecated": true,
        "x-sunset-date": "2026-12-31",
        "x-successor": "/v1/webhooks/v2/endpoints",
        "x-codeSamples": [
          {
            "lang": "cURL",
            "label": "cURL",
            "source": "curl -X GET \"https://api.kangopenbanking.com/v1/merchants/webhooks\" \\\n  -H \"Authorization: Bearer $KOB_ACCESS_TOKEN\" \\\n  -H \"Content-Type: application/json\""
          },
          {
            "lang": "JavaScript",
            "label": "Node.js",
            "source": "import { KangOpenBanking } from \"@kangopenbanking/sdk\";\n\nconst kob = new KangOpenBanking({ apiKey: process.env.KOB_API_KEY });\nconst res = await kob.request(\"GET\", \"/v1/merchants/webhooks\");\nconsole.log(res);"
          },
          {
            "lang": "Python",
            "label": "Python",
            "source": "from kangopenbanking import KangOpenBanking\n\nkob = KangOpenBanking(api_key=os.environ[\"KOB_API_KEY\"])\nres = kob.request(\"GET\", \"/v1/merchants/webhooks\")\nprint(res)"
          },
          {
            "lang": "PHP",
            "label": "PHP",
            "source": "<?php\n$kob = new KangOpenBanking\\KangOpenBanking(getenv('KOB_API_KEY'));\n$res = $kob->request('GET', '/v1/merchants/webhooks');\nprint_r($res);"
          }
        ],
        "description": "**Deprecated.** Use Webhooks v2 (`/v1/webhooks/v2/endpoints`). Sunset: 2026-12-31.\n\nList merchant webhooks.\n\n**Tag:** Merchant Onboarding\n\nAuthenticate with a bearer token issued by `/v1/oauth/token`. All state-changing requests\n(POST, PUT, PATCH, DELETE) MUST include an `Idempotency-Key` header (UUID v4) to make\nretries safe — Kang will return the original response for any duplicate key within 24 hours.\n\nErrors follow [RFC 7807](https://datatracker.ietf.org/doc/html/rfc7807) and are returned with\n`Content-Type: application/problem+json`. The `code` field is stable and machine-readable.\nRate-limit headers (`X-RateLimit-Limit`, `X-RateLimit-Remaining`, `X-RateLimit-Reset`)\nare present on every response.\n\n**Migration:** Replace with `webhookV2List`. Move the endpoint to Webhooks v2 and verify the timestamped `X-Webhook-Signature` described in the webhook definitions.",
        "x-replacement-operation-ids": [
          "webhookV2List"
        ],
        "x-migration-guide": "Move the endpoint to Webhooks v2 and verify the timestamped `X-Webhook-Signature` described in the webhook definitions."
      }
    },
    "/v1/oauth/revoke": {
      "post": {
        "tags": [
          "OAuth"
        ],
        "summary": "Revoke token",
        "description": "Revoke an access or refresh token (RFC 7009). Always returns 200.",
        "operationId": "oauthRevoke",
        "security": [],
        "requestBody": {
          "required": true,
          "content": {
            "application/x-www-form-urlencoded": {
              "schema": {
                "type": "object",
                "required": [
                  "token",
                  "client_id",
                  "client_secret"
                ],
                "properties": {
                  "token": {
                    "type": "string"
                  },
                  "token_type_hint": {
                    "type": "string",
                    "enum": [
                      "access_token",
                      "refresh_token"
                    ]
                  },
                  "client_id": {
                    "type": "string"
                  },
                  "client_secret": {
                    "type": "string"
                  }
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Token revoked (or was already invalid)",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "success": {
                      "type": "boolean",
                      "example": true
                    },
                    "message": {
                      "type": "string"
                    }
                  }
                },
                "example": {
                  "success": true,
                  "message": "string"
                }
              }
            },
            "headers": {
              "x-fapi-interaction-id": {
                "$ref": "#/components/headers/XFapiInteractionIdResponse"
              },
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/XRateLimitLimit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/XRateLimitRemaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/XRateLimitReset"
              },
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              },
              "traceparent": {
                "$ref": "#/components/headers/Traceparent"
              },
              "Content-Language": {
                "$ref": "#/components/headers/Content-Language"
              }
            }
          },
          "400": {
            "description": "Bad request",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              },
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                },
                "examples": {
                  "error": {
                    "$ref": "#/components/examples/ErrorBadRequest"
                  }
                }
              }
            },
            "headers": {
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/XRateLimitLimit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/XRateLimitRemaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/XRateLimitReset"
              },
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "403": {
            "$ref": "#/components/responses/Forbidden",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "404": {
            "$ref": "#/components/responses/NotFound",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "409": {
            "$ref": "#/components/responses/Conflict",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "429": {
            "$ref": "#/components/responses/TooManyRequests",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "500": {
            "$ref": "#/components/responses/InternalServerError",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          }
        },
        "parameters": [
          {
            "$ref": "#/components/parameters/RequestId"
          },
          {
            "$ref": "#/components/parameters/Traceparent"
          },
          {
            "$ref": "#/components/parameters/Tracestate"
          },
          {
            "$ref": "#/components/parameters/AcceptLanguage"
          }
        ],
        "x-codeSamples": [
          {
            "lang": "cURL",
            "label": "cURL",
            "source": "curl -X POST \"https://api.kangopenbanking.com/v1/oauth/revoke\" \\\n  -H \"Authorization: Bearer $KOB_ACCESS_TOKEN\" \\\n  -H \"Content-Type: application/json\" \\\n  -d '{}'"
          },
          {
            "lang": "JavaScript",
            "label": "Node.js",
            "source": "import { KangOpenBanking } from \"@kangopenbanking/sdk\";\n\nconst kob = new KangOpenBanking({ apiKey: process.env.KOB_API_KEY });\nconst res = await kob.request(\"POST\", \"/v1/oauth/revoke\", { /* payload */ });\nconsole.log(res);"
          },
          {
            "lang": "Python",
            "label": "Python",
            "source": "from kangopenbanking import KangOpenBanking\n\nkob = KangOpenBanking(api_key=os.environ[\"KOB_API_KEY\"])\nres = kob.request(\"POST\", \"/v1/oauth/revoke\", json={})\nprint(res)"
          },
          {
            "lang": "PHP",
            "label": "PHP",
            "source": "<?php\n$kob = new KangOpenBanking\\KangOpenBanking(getenv('KOB_API_KEY'));\n$res = $kob->request('POST', '/v1/oauth/revoke', []);\nprint_r($res);"
          }
        ]
      }
    },
    "/v1/oauth/userinfo": {
      "get": {
        "tags": [
          "OAuth"
        ],
        "summary": "Get user info",
        "description": "OpenID Connect UserInfo endpoint. Returns claims about the authenticated user based on the access token scope.",
        "operationId": "oauthUserInfo",
        "security": [
          {
            "bearerAuth": []
          }
        ],
        "responses": {
          "200": {
            "description": "User claims",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "sub": {
                      "type": "string"
                    },
                    "name": {
                      "type": "string"
                    },
                    "email": {
                      "type": "string"
                    },
                    "phone_number": {
                      "type": "string"
                    },
                    "updated_at": {
                      "type": "integer"
                    }
                  }
                },
                "example": {
                  "sub": "string",
                  "name": "string",
                  "email": "agent@example.cm",
                  "phone_number": "string",
                  "updated_at": 0
                }
              }
            },
            "headers": {
              "x-fapi-interaction-id": {
                "$ref": "#/components/headers/XFapiInteractionIdResponse"
              },
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/XRateLimitLimit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/XRateLimitRemaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/XRateLimitReset"
              },
              "Cache-Control": {
                "$ref": "#/components/headers/CacheControl"
              },
              "ETag": {
                "$ref": "#/components/headers/ETag"
              },
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              },
              "traceparent": {
                "$ref": "#/components/headers/Traceparent"
              },
              "Content-Language": {
                "$ref": "#/components/headers/Content-Language"
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "403": {
            "$ref": "#/components/responses/Forbidden",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "429": {
            "$ref": "#/components/responses/TooManyRequests",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "default": {
            "description": "Server error — see ProblemDetails for trace ID.",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            },
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/XRateLimitLimit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/XRateLimitRemaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/XRateLimitReset"
              }
            }
          }
        },
        "parameters": [
          {
            "$ref": "#/components/parameters/RequestId"
          },
          {
            "$ref": "#/components/parameters/Traceparent"
          },
          {
            "$ref": "#/components/parameters/Tracestate"
          },
          {
            "$ref": "#/components/parameters/AcceptLanguage"
          }
        ],
        "x-codeSamples": [
          {
            "lang": "cURL",
            "label": "cURL",
            "source": "curl -X GET \"https://api.kangopenbanking.com/v1/oauth/userinfo\" \\\n  -H \"Authorization: Bearer $KOB_ACCESS_TOKEN\" \\\n  -H \"Content-Type: application/json\""
          },
          {
            "lang": "JavaScript",
            "label": "Node.js",
            "source": "import { KangOpenBanking } from \"@kangopenbanking/sdk\";\n\nconst kob = new KangOpenBanking({ apiKey: process.env.KOB_API_KEY });\nconst res = await kob.request(\"GET\", \"/v1/oauth/userinfo\");\nconsole.log(res);"
          },
          {
            "lang": "Python",
            "label": "Python",
            "source": "from kangopenbanking import KangOpenBanking\n\nkob = KangOpenBanking(api_key=os.environ[\"KOB_API_KEY\"])\nres = kob.request(\"GET\", \"/v1/oauth/userinfo\")\nprint(res)"
          },
          {
            "lang": "PHP",
            "label": "PHP",
            "source": "<?php\n$kob = new KangOpenBanking\\KangOpenBanking(getenv('KOB_API_KEY'));\n$res = $kob->request('GET', '/v1/oauth/userinfo');\nprint_r($res);"
          }
        ]
      }
    },
    "/v1/consumer/piggybank": {
      "post": {
        "tags": [
          "Consumer Tools"
        ],
        "summary": "Create savings goal",
        "description": "Create a personal savings goal (Piggy Bank) with target amount and schedule.",
        "operationId": "piggybankCreate",
        "security": [
          {
            "bearerAuth": []
          }
        ],
        "parameters": [
          {
            "name": "Idempotency-Key",
            "in": "header",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid"
            },
            "description": "Required on all POST/PUT endpoints. Unique key for idempotent request processing (UUID v4 recommended). Keys expire after 24 hours."
          },
          {
            "$ref": "#/components/parameters/RequestId"
          },
          {
            "$ref": "#/components/parameters/Traceparent"
          },
          {
            "$ref": "#/components/parameters/Tracestate"
          },
          {
            "$ref": "#/components/parameters/AcceptLanguage"
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "required": [
                  "name",
                  "target_amount",
                  "currency"
                ],
                "properties": {
                  "name": {
                    "type": "string",
                    "example": "Emergency Fund"
                  },
                  "target_amount": {
                    "type": "number",
                    "example": 500000
                  },
                  "currency": {
                    "type": "string",
                    "default": "XAF",
                    "enum": [
                      "XAF",
                      "XOF",
                      "USD",
                      "EUR",
                      "GBP",
                      "CNY",
                      "NGN",
                      "GHS",
                      "KES",
                      "ZAR"
                    ],
                    "description": "ISO 4217 currency code. Default is XAF (Central African CFA Franc)."
                  },
                  "frequency": {
                    "type": "string",
                    "enum": [
                      "daily",
                      "weekly",
                      "monthly"
                    ]
                  },
                  "contribution_amount": {
                    "type": "number",
                    "example": 10000
                  },
                  "target_date": {
                    "type": "string",
                    "format": "date"
                  }
                }
              }
            }
          }
        },
        "responses": {
          "201": {
            "description": "Piggy bank created",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "id": {
                      "type": "string",
                      "format": "uuid"
                    },
                    "name": {
                      "type": "string"
                    },
                    "target_amount": {
                      "type": "number"
                    },
                    "current_amount": {
                      "type": "number",
                      "example": 0
                    },
                    "currency": {
                      "type": "string",
                      "enum": [
                        "XAF",
                        "XOF",
                        "USD",
                        "EUR",
                        "GBP",
                        "CNY",
                        "NGN",
                        "GHS",
                        "KES",
                        "ZAR"
                      ],
                      "default": "XAF",
                      "description": "ISO 4217 currency code. Default is XAF (Central African CFA Franc)."
                    },
                    "status": {
                      "type": "string",
                      "example": "active"
                    },
                    "created_at": {
                      "type": "string",
                      "format": "date-time"
                    }
                  }
                },
                "example": {
                  "id": "00000000-0000-4000-8000-000000000000",
                  "name": "string",
                  "target_amount": 0,
                  "current_amount": 0,
                  "currency": "XAF",
                  "status": "active",
                  "created_at": "2026-01-01T00:00:00Z"
                }
              }
            },
            "headers": {
              "x-fapi-interaction-id": {
                "$ref": "#/components/headers/XFapiInteractionIdResponse"
              },
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/XRateLimitLimit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/XRateLimitRemaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/XRateLimitReset"
              },
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              },
              "X-Idempotent-Replay": {
                "$ref": "#/components/headers/X-Idempotent-Replay"
              },
              "X-Idempotency-Status": {
                "$ref": "#/components/headers/X-Idempotency-Status"
              },
              "traceparent": {
                "$ref": "#/components/headers/Traceparent"
              },
              "Content-Language": {
                "$ref": "#/components/headers/Content-Language"
              }
            }
          },
          "400": {
            "description": "Bad request",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              },
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                },
                "examples": {
                  "error": {
                    "$ref": "#/components/examples/ErrorBadRequest"
                  }
                }
              }
            },
            "headers": {
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/XRateLimitLimit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/XRateLimitRemaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/XRateLimitReset"
              },
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "403": {
            "$ref": "#/components/responses/Forbidden",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "404": {
            "$ref": "#/components/responses/NotFound",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "409": {
            "$ref": "#/components/responses/Conflict",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "429": {
            "$ref": "#/components/responses/TooManyRequests",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "500": {
            "$ref": "#/components/responses/InternalServerError",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          }
        },
        "x-codeSamples": [
          {
            "lang": "cURL",
            "label": "cURL",
            "source": "curl -X POST \"https://api.kangopenbanking.com/v1/consumer/piggybank\" \\\n  -H \"Authorization: Bearer $KOB_ACCESS_TOKEN\" \\\n  -H \"Content-Type: application/json\" \\\n  -d '{}'"
          },
          {
            "lang": "JavaScript",
            "label": "Node.js",
            "source": "import { KangOpenBanking } from \"@kangopenbanking/sdk\";\n\nconst kob = new KangOpenBanking({ apiKey: process.env.KOB_API_KEY });\nconst res = await kob.request(\"POST\", \"/v1/consumer/piggybank\", { /* payload */ });\nconsole.log(res);"
          },
          {
            "lang": "Python",
            "label": "Python",
            "source": "from kangopenbanking import KangOpenBanking\n\nkob = KangOpenBanking(api_key=os.environ[\"KOB_API_KEY\"])\nres = kob.request(\"POST\", \"/v1/consumer/piggybank\", json={})\nprint(res)"
          },
          {
            "lang": "PHP",
            "label": "PHP",
            "source": "<?php\n$kob = new KangOpenBanking\\KangOpenBanking(getenv('KOB_API_KEY'));\n$res = $kob->request('POST', '/v1/consumer/piggybank', []);\nprint_r($res);"
          }
        ]
      }
    },
    "/v1/consumer/piggybank/pay": {
      "post": {
        "tags": [
          "Consumer Tools"
        ],
        "summary": "Make piggy bank payment",
        "description": "Contribute to a savings goal. Impacts credit score positively (+3 to +10 points for on-time payments).",
        "operationId": "piggybankPay",
        "security": [
          {
            "bearerAuth": []
          }
        ],
        "parameters": [
          {
            "name": "Idempotency-Key",
            "in": "header",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid"
            },
            "description": "Required on all POST/PUT endpoints. Unique key for idempotent request processing (UUID v4 recommended). Keys expire after 24 hours."
          },
          {
            "$ref": "#/components/parameters/RequestId"
          },
          {
            "$ref": "#/components/parameters/Traceparent"
          },
          {
            "$ref": "#/components/parameters/Tracestate"
          },
          {
            "$ref": "#/components/parameters/AcceptLanguage"
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "required": [
                  "piggybank_id",
                  "amount"
                ],
                "properties": {
                  "piggybank_id": {
                    "type": "string",
                    "format": "uuid"
                  },
                  "amount": {
                    "type": "string",
                    "example": "10000",
                    "pattern": "^[0-9]{1,15}$",
                    "description": "Represented as a string integer in the currency's minor unit (XAF has no subunits)."
                  }
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Payment recorded",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "success": {
                      "type": "boolean",
                      "example": true
                    },
                    "message": {
                      "type": "string"
                    }
                  }
                },
                "example": {
                  "success": true,
                  "message": "string"
                }
              }
            },
            "headers": {
              "x-fapi-interaction-id": {
                "$ref": "#/components/headers/XFapiInteractionIdResponse"
              },
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/XRateLimitLimit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/XRateLimitRemaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/XRateLimitReset"
              },
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              },
              "X-Idempotent-Replay": {
                "$ref": "#/components/headers/X-Idempotent-Replay"
              },
              "X-Idempotency-Status": {
                "$ref": "#/components/headers/X-Idempotency-Status"
              },
              "traceparent": {
                "$ref": "#/components/headers/Traceparent"
              },
              "Content-Language": {
                "$ref": "#/components/headers/Content-Language"
              }
            }
          },
          "400": {
            "description": "Bad request",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              },
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                },
                "examples": {
                  "error": {
                    "$ref": "#/components/examples/ErrorBadRequest"
                  }
                }
              }
            },
            "headers": {
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/XRateLimitLimit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/XRateLimitRemaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/XRateLimitReset"
              },
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "403": {
            "$ref": "#/components/responses/Forbidden",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "404": {
            "$ref": "#/components/responses/NotFound",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "409": {
            "$ref": "#/components/responses/Conflict",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "429": {
            "$ref": "#/components/responses/TooManyRequests",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "500": {
            "$ref": "#/components/responses/InternalServerError",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          }
        },
        "x-codeSamples": [
          {
            "lang": "cURL",
            "label": "cURL",
            "source": "curl -X POST \"https://api.kangopenbanking.com/v1/consumer/piggybank/pay\" \\\n  -H \"Authorization: Bearer $KOB_ACCESS_TOKEN\" \\\n  -H \"Content-Type: application/json\" \\\n  -d '{}'"
          },
          {
            "lang": "JavaScript",
            "label": "Node.js",
            "source": "import { KangOpenBanking } from \"@kangopenbanking/sdk\";\n\nconst kob = new KangOpenBanking({ apiKey: process.env.KOB_API_KEY });\nconst res = await kob.request(\"POST\", \"/v1/consumer/piggybank/pay\", { /* payload */ });\nconsole.log(res);"
          },
          {
            "lang": "Python",
            "label": "Python",
            "source": "from kangopenbanking import KangOpenBanking\n\nkob = KangOpenBanking(api_key=os.environ[\"KOB_API_KEY\"])\nres = kob.request(\"POST\", \"/v1/consumer/piggybank/pay\", json={})\nprint(res)"
          },
          {
            "lang": "PHP",
            "label": "PHP",
            "source": "<?php\n$kob = new KangOpenBanking\\KangOpenBanking(getenv('KOB_API_KEY'));\n$res = $kob->request('POST', '/v1/consumer/piggybank/pay', []);\nprint_r($res);"
          }
        ]
      }
    },
    "/v1/consumer/njangi": {
      "post": {
        "tags": [
          "Consumer Tools"
        ],
        "summary": "Create Njangi group",
        "description": "Create a rotating savings circle (Njangi/tontine) with contribution schedule and payout rules.",
        "operationId": "njangiCreate",
        "security": [
          {
            "bearerAuth": []
          }
        ],
        "parameters": [
          {
            "name": "Idempotency-Key",
            "in": "header",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid"
            },
            "description": "Required on all POST/PUT endpoints. Unique key for idempotent request processing (UUID v4 recommended). Keys expire after 24 hours."
          },
          {
            "$ref": "#/components/parameters/RequestId"
          },
          {
            "$ref": "#/components/parameters/Traceparent"
          },
          {
            "$ref": "#/components/parameters/Tracestate"
          },
          {
            "$ref": "#/components/parameters/AcceptLanguage"
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "required": [
                  "name",
                  "contribution_amount",
                  "frequency"
                ],
                "properties": {
                  "name": {
                    "type": "string",
                    "example": "Office Njangi"
                  },
                  "contribution_amount": {
                    "type": "number",
                    "example": 25000
                  },
                  "currency": {
                    "type": "string",
                    "default": "XAF",
                    "enum": [
                      "XAF",
                      "XOF",
                      "USD",
                      "EUR",
                      "GBP",
                      "CNY",
                      "NGN",
                      "GHS",
                      "KES",
                      "ZAR"
                    ],
                    "description": "ISO 4217 currency code. Default is XAF (Central African CFA Franc)."
                  },
                  "frequency": {
                    "type": "string",
                    "enum": [
                      "weekly",
                      "monthly"
                    ]
                  },
                  "max_members": {
                    "type": "integer",
                    "example": 10
                  },
                  "payout_method": {
                    "type": "string",
                    "enum": [
                      "random",
                      "sequential",
                      "manual"
                    ],
                    "default": "random"
                  }
                }
              }
            }
          }
        },
        "responses": {
          "201": {
            "description": "Njangi group created",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "id": {
                      "type": "string",
                      "format": "uuid"
                    },
                    "name": {
                      "type": "string"
                    },
                    "contribution_amount": {
                      "type": "number"
                    },
                    "currency": {
                      "type": "string",
                      "enum": [
                        "XAF",
                        "XOF",
                        "USD",
                        "EUR",
                        "GBP",
                        "CNY",
                        "NGN",
                        "GHS",
                        "KES",
                        "ZAR"
                      ],
                      "default": "XAF",
                      "description": "ISO 4217 currency code. Default is XAF (Central African CFA Franc)."
                    },
                    "frequency": {
                      "type": "string"
                    },
                    "member_count": {
                      "type": "integer",
                      "example": 1
                    },
                    "status": {
                      "type": "string",
                      "example": "active"
                    },
                    "created_at": {
                      "type": "string",
                      "format": "date-time"
                    }
                  }
                },
                "example": {
                  "id": "00000000-0000-4000-8000-000000000000",
                  "name": "string",
                  "contribution_amount": 0,
                  "currency": "XAF",
                  "frequency": "string",
                  "member_count": 1,
                  "status": "active",
                  "created_at": "2026-01-01T00:00:00Z"
                }
              }
            },
            "headers": {
              "x-fapi-interaction-id": {
                "$ref": "#/components/headers/XFapiInteractionIdResponse"
              },
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/XRateLimitLimit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/XRateLimitRemaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/XRateLimitReset"
              },
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              },
              "X-Idempotent-Replay": {
                "$ref": "#/components/headers/X-Idempotent-Replay"
              },
              "X-Idempotency-Status": {
                "$ref": "#/components/headers/X-Idempotency-Status"
              },
              "traceparent": {
                "$ref": "#/components/headers/Traceparent"
              },
              "Content-Language": {
                "$ref": "#/components/headers/Content-Language"
              }
            }
          },
          "400": {
            "description": "Bad request",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              },
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                },
                "examples": {
                  "error": {
                    "$ref": "#/components/examples/ErrorBadRequest"
                  }
                }
              }
            },
            "headers": {
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/XRateLimitLimit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/XRateLimitRemaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/XRateLimitReset"
              },
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "403": {
            "$ref": "#/components/responses/Forbidden",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "404": {
            "$ref": "#/components/responses/NotFound",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "409": {
            "$ref": "#/components/responses/Conflict",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "429": {
            "$ref": "#/components/responses/TooManyRequests",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "500": {
            "$ref": "#/components/responses/InternalServerError",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          }
        },
        "x-codeSamples": [
          {
            "lang": "cURL",
            "label": "cURL",
            "source": "curl -X POST \"https://api.kangopenbanking.com/v1/consumer/njangi\" \\\n  -H \"Authorization: Bearer $KOB_ACCESS_TOKEN\" \\\n  -H \"Content-Type: application/json\" \\\n  -d '{}'"
          },
          {
            "lang": "JavaScript",
            "label": "Node.js",
            "source": "import { KangOpenBanking } from \"@kangopenbanking/sdk\";\n\nconst kob = new KangOpenBanking({ apiKey: process.env.KOB_API_KEY });\nconst res = await kob.request(\"POST\", \"/v1/consumer/njangi\", { /* payload */ });\nconsole.log(res);"
          },
          {
            "lang": "Python",
            "label": "Python",
            "source": "from kangopenbanking import KangOpenBanking\n\nkob = KangOpenBanking(api_key=os.environ[\"KOB_API_KEY\"])\nres = kob.request(\"POST\", \"/v1/consumer/njangi\", json={})\nprint(res)"
          },
          {
            "lang": "PHP",
            "label": "PHP",
            "source": "<?php\n$kob = new KangOpenBanking\\KangOpenBanking(getenv('KOB_API_KEY'));\n$res = $kob->request('POST', '/v1/consumer/njangi', []);\nprint_r($res);"
          }
        ]
      }
    },
    "/v1/consumer/njangi/join": {
      "post": {
        "tags": [
          "Consumer Tools"
        ],
        "summary": "Join Njangi group",
        "operationId": "njangiJoin",
        "security": [
          {
            "bearerAuth": []
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "required": [
                  "group_id"
                ],
                "properties": {
                  "group_id": {
                    "type": "string",
                    "format": "uuid"
                  }
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Joined group",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "success": {
                      "type": "boolean",
                      "example": true
                    },
                    "message": {
                      "type": "string"
                    }
                  }
                },
                "example": {
                  "success": true,
                  "message": "string"
                }
              }
            },
            "headers": {
              "x-fapi-interaction-id": {
                "$ref": "#/components/headers/XFapiInteractionIdResponse"
              },
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/XRateLimitLimit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/XRateLimitRemaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/XRateLimitReset"
              },
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              },
              "traceparent": {
                "$ref": "#/components/headers/Traceparent"
              },
              "Content-Language": {
                "$ref": "#/components/headers/Content-Language"
              }
            }
          },
          "400": {
            "description": "Bad request",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              },
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                },
                "examples": {
                  "error": {
                    "$ref": "#/components/examples/ErrorBadRequest"
                  }
                }
              }
            },
            "headers": {
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/XRateLimitLimit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/XRateLimitRemaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/XRateLimitReset"
              },
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "403": {
            "$ref": "#/components/responses/Forbidden",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "404": {
            "$ref": "#/components/responses/NotFound",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "409": {
            "$ref": "#/components/responses/Conflict",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "429": {
            "$ref": "#/components/responses/TooManyRequests",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "500": {
            "$ref": "#/components/responses/InternalServerError",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          }
        },
        "parameters": [
          {
            "$ref": "#/components/parameters/RequestId"
          },
          {
            "$ref": "#/components/parameters/Traceparent"
          },
          {
            "$ref": "#/components/parameters/Tracestate"
          },
          {
            "$ref": "#/components/parameters/AcceptLanguage"
          }
        ],
        "x-codeSamples": [
          {
            "lang": "cURL",
            "label": "cURL",
            "source": "curl -X POST \"https://api.kangopenbanking.com/v1/consumer/njangi/join\" \\\n  -H \"Authorization: Bearer $KOB_ACCESS_TOKEN\" \\\n  -H \"Content-Type: application/json\" \\\n  -d '{}'"
          },
          {
            "lang": "JavaScript",
            "label": "Node.js",
            "source": "import { KangOpenBanking } from \"@kangopenbanking/sdk\";\n\nconst kob = new KangOpenBanking({ apiKey: process.env.KOB_API_KEY });\nconst res = await kob.request(\"POST\", \"/v1/consumer/njangi/join\", { /* payload */ });\nconsole.log(res);"
          },
          {
            "lang": "Python",
            "label": "Python",
            "source": "from kangopenbanking import KangOpenBanking\n\nkob = KangOpenBanking(api_key=os.environ[\"KOB_API_KEY\"])\nres = kob.request(\"POST\", \"/v1/consumer/njangi/join\", json={})\nprint(res)"
          },
          {
            "lang": "PHP",
            "label": "PHP",
            "source": "<?php\n$kob = new KangOpenBanking\\KangOpenBanking(getenv('KOB_API_KEY'));\n$res = $kob->request('POST', '/v1/consumer/njangi/join', []);\nprint_r($res);"
          }
        ]
      }
    },
    "/v1/consumer/njangi/contribute": {
      "post": {
        "tags": [
          "Consumer Tools"
        ],
        "summary": "Make Njangi contribution",
        "description": "Submit a contribution to the group pot. Late contributions are reported as negative credit events.",
        "operationId": "njangiContribute",
        "security": [
          {
            "bearerAuth": []
          }
        ],
        "parameters": [
          {
            "name": "Idempotency-Key",
            "in": "header",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid"
            },
            "description": "Required on all POST/PUT endpoints. Unique key for idempotent request processing (UUID v4 recommended). Keys expire after 24 hours."
          },
          {
            "$ref": "#/components/parameters/RequestId"
          },
          {
            "$ref": "#/components/parameters/Traceparent"
          },
          {
            "$ref": "#/components/parameters/Tracestate"
          },
          {
            "$ref": "#/components/parameters/AcceptLanguage"
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "required": [
                  "group_id",
                  "amount"
                ],
                "properties": {
                  "group_id": {
                    "type": "string",
                    "format": "uuid"
                  },
                  "amount": {
                    "type": "string",
                    "example": "25000",
                    "pattern": "^[0-9]{1,15}$",
                    "description": "Represented as a string integer in the currency's minor unit (XAF has no subunits)."
                  }
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Contribution recorded",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "success": {
                      "type": "boolean",
                      "example": true
                    },
                    "message": {
                      "type": "string"
                    }
                  }
                },
                "example": {
                  "success": true,
                  "message": "string"
                }
              }
            },
            "headers": {
              "x-fapi-interaction-id": {
                "$ref": "#/components/headers/XFapiInteractionIdResponse"
              },
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/XRateLimitLimit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/XRateLimitRemaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/XRateLimitReset"
              },
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              },
              "X-Idempotent-Replay": {
                "$ref": "#/components/headers/X-Idempotent-Replay"
              },
              "X-Idempotency-Status": {
                "$ref": "#/components/headers/X-Idempotency-Status"
              },
              "traceparent": {
                "$ref": "#/components/headers/Traceparent"
              },
              "Content-Language": {
                "$ref": "#/components/headers/Content-Language"
              }
            }
          },
          "400": {
            "description": "Bad request",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              },
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                },
                "examples": {
                  "error": {
                    "$ref": "#/components/examples/ErrorBadRequest"
                  }
                }
              }
            },
            "headers": {
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/XRateLimitLimit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/XRateLimitRemaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/XRateLimitReset"
              },
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "403": {
            "$ref": "#/components/responses/Forbidden",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "404": {
            "$ref": "#/components/responses/NotFound",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "409": {
            "$ref": "#/components/responses/Conflict",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "429": {
            "$ref": "#/components/responses/TooManyRequests",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "500": {
            "$ref": "#/components/responses/InternalServerError",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          }
        },
        "x-codeSamples": [
          {
            "lang": "cURL",
            "label": "cURL",
            "source": "curl -X POST \"https://api.kangopenbanking.com/v1/consumer/njangi/contribute\" \\\n  -H \"Authorization: Bearer $KOB_ACCESS_TOKEN\" \\\n  -H \"Content-Type: application/json\" \\\n  -d '{}'"
          },
          {
            "lang": "JavaScript",
            "label": "Node.js",
            "source": "import { KangOpenBanking } from \"@kangopenbanking/sdk\";\n\nconst kob = new KangOpenBanking({ apiKey: process.env.KOB_API_KEY });\nconst res = await kob.request(\"POST\", \"/v1/consumer/njangi/contribute\", { /* payload */ });\nconsole.log(res);"
          },
          {
            "lang": "Python",
            "label": "Python",
            "source": "from kangopenbanking import KangOpenBanking\n\nkob = KangOpenBanking(api_key=os.environ[\"KOB_API_KEY\"])\nres = kob.request(\"POST\", \"/v1/consumer/njangi/contribute\", json={})\nprint(res)"
          },
          {
            "lang": "PHP",
            "label": "PHP",
            "source": "<?php\n$kob = new KangOpenBanking\\KangOpenBanking(getenv('KOB_API_KEY'));\n$res = $kob->request('POST', '/v1/consumer/njangi/contribute', []);\nprint_r($res);"
          }
        ]
      }
    },
    "/v1/consumer/njangi/payout": {
      "post": {
        "tags": [
          "Consumer Tools"
        ],
        "summary": "Trigger Njangi payout",
        "description": "Disburse the accumulated pot to the next eligible member.",
        "operationId": "njangiPayout",
        "security": [
          {
            "bearerAuth": []
          }
        ],
        "parameters": [
          {
            "name": "Idempotency-Key",
            "in": "header",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid"
            },
            "description": "Required on all POST/PUT endpoints. Unique key for idempotent request processing (UUID v4 recommended). Keys expire after 24 hours."
          },
          {
            "$ref": "#/components/parameters/RequestId"
          },
          {
            "$ref": "#/components/parameters/Traceparent"
          },
          {
            "$ref": "#/components/parameters/Tracestate"
          },
          {
            "$ref": "#/components/parameters/AcceptLanguage"
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "required": [
                  "group_id"
                ],
                "properties": {
                  "group_id": {
                    "type": "string",
                    "format": "uuid"
                  },
                  "recipient_id": {
                    "type": "string",
                    "format": "uuid",
                    "description": "Override random selection (manual mode only)"
                  }
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Payout initiated",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "success": {
                      "type": "boolean",
                      "example": true
                    },
                    "message": {
                      "type": "string"
                    }
                  }
                },
                "example": {
                  "success": true,
                  "message": "string"
                }
              }
            },
            "headers": {
              "x-fapi-interaction-id": {
                "$ref": "#/components/headers/XFapiInteractionIdResponse"
              },
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/XRateLimitLimit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/XRateLimitRemaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/XRateLimitReset"
              },
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              },
              "X-Idempotent-Replay": {
                "$ref": "#/components/headers/X-Idempotent-Replay"
              },
              "X-Idempotency-Status": {
                "$ref": "#/components/headers/X-Idempotency-Status"
              },
              "traceparent": {
                "$ref": "#/components/headers/Traceparent"
              },
              "Content-Language": {
                "$ref": "#/components/headers/Content-Language"
              }
            }
          },
          "400": {
            "description": "Bad request",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              },
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                },
                "examples": {
                  "error": {
                    "$ref": "#/components/examples/ErrorBadRequest"
                  }
                }
              }
            },
            "headers": {
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/XRateLimitLimit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/XRateLimitRemaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/XRateLimitReset"
              },
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "403": {
            "$ref": "#/components/responses/Forbidden",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "404": {
            "$ref": "#/components/responses/NotFound",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "409": {
            "$ref": "#/components/responses/Conflict",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "429": {
            "$ref": "#/components/responses/TooManyRequests",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "500": {
            "$ref": "#/components/responses/InternalServerError",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          }
        },
        "x-codeSamples": [
          {
            "lang": "cURL",
            "label": "cURL",
            "source": "curl -X POST \"https://api.kangopenbanking.com/v1/consumer/njangi/payout\" \\\n  -H \"Authorization: Bearer $KOB_ACCESS_TOKEN\" \\\n  -H \"Content-Type: application/json\" \\\n  -d '{}'"
          },
          {
            "lang": "JavaScript",
            "label": "Node.js",
            "source": "import { KangOpenBanking } from \"@kangopenbanking/sdk\";\n\nconst kob = new KangOpenBanking({ apiKey: process.env.KOB_API_KEY });\nconst res = await kob.request(\"POST\", \"/v1/consumer/njangi/payout\", { /* payload */ });\nconsole.log(res);"
          },
          {
            "lang": "Python",
            "label": "Python",
            "source": "from kangopenbanking import KangOpenBanking\n\nkob = KangOpenBanking(api_key=os.environ[\"KOB_API_KEY\"])\nres = kob.request(\"POST\", \"/v1/consumer/njangi/payout\", json={})\nprint(res)"
          },
          {
            "lang": "PHP",
            "label": "PHP",
            "source": "<?php\n$kob = new KangOpenBanking\\KangOpenBanking(getenv('KOB_API_KEY'));\n$res = $kob->request('POST', '/v1/consumer/njangi/payout', []);\nprint_r($res);"
          }
        ]
      }
    },
    "/v1/gateway/funding-intents": {
      "post": {
        "tags": [
          "Payment Gateway"
        ],
        "summary": "Create funding intent",
        "description": "Create an intent to fund a merchant or user account. Supports Stripe, PayPal, and mobile money sources.",
        "operationId": "gatewayCreateFundingIntent",
        "security": [
          {
            "bearerAuth": []
          }
        ],
        "parameters": [
          {
            "name": "Idempotency-Key",
            "in": "header",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid"
            },
            "description": "Required on all POST/PUT endpoints. Unique key for idempotent request processing (UUID v4 recommended). Keys expire after 24 hours."
          },
          {
            "$ref": "#/components/parameters/RequestId"
          },
          {
            "$ref": "#/components/parameters/Traceparent"
          },
          {
            "$ref": "#/components/parameters/Tracestate"
          },
          {
            "$ref": "#/components/parameters/AcceptLanguage"
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "required": [
                  "amount",
                  "currency",
                  "source"
                ],
                "properties": {
                  "amount": {
                    "type": "string",
                    "example": "50000",
                    "pattern": "^[0-9]{1,15}$",
                    "description": "Represented as a string integer in the currency's minor unit (XAF has no subunits). Must be consistent with the currency field."
                  },
                  "currency": {
                    "type": "string",
                    "default": "XAF",
                    "enum": [
                      "XAF",
                      "XOF",
                      "USD",
                      "EUR",
                      "GBP",
                      "CNY",
                      "NGN",
                      "GHS",
                      "KES",
                      "ZAR"
                    ],
                    "description": "ISO 4217 currency code. Default is XAF (Central African CFA Franc)."
                  },
                  "source": {
                    "type": "string",
                    "enum": [
                      "stripe",
                      "paypal",
                      "mobile_money"
                    ]
                  },
                  "metadata": {
                    "type": "object"
                  }
                }
              }
            }
          }
        },
        "responses": {
          "201": {
            "description": "Funding intent created",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "id": {
                      "type": "string",
                      "format": "uuid"
                    },
                    "amount": {
                      "type": "string",
                      "pattern": "^[0-9]{1,15}$",
                      "description": "Represented as a string integer in the currency's minor unit (XAF has no subunits). Must be consistent with the currency field."
                    },
                    "currency": {
                      "type": "string",
                      "enum": [
                        "XAF",
                        "XOF",
                        "USD",
                        "EUR",
                        "GBP",
                        "CNY",
                        "NGN",
                        "GHS",
                        "KES",
                        "ZAR"
                      ],
                      "default": "XAF",
                      "description": "ISO 4217 currency code. Default is XAF (Central African CFA Franc)."
                    },
                    "source": {
                      "type": "string"
                    },
                    "status": {
                      "type": "string",
                      "enum": [
                        "pending",
                        "confirmed",
                        "cancelled",
                        "failed"
                      ]
                    },
                    "redirect_url": {
                      "type": "string"
                    },
                    "created_at": {
                      "type": "string",
                      "format": "date-time"
                    }
                  }
                },
                "example": {
                  "id": "00000000-0000-4000-8000-000000000000",
                  "amount": "1000",
                  "currency": "XAF",
                  "source": "string",
                  "status": "pending",
                  "redirect_url": "string",
                  "created_at": "2026-01-01T00:00:00Z"
                }
              }
            },
            "headers": {
              "x-fapi-interaction-id": {
                "$ref": "#/components/headers/XFapiInteractionIdResponse"
              },
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/XRateLimitLimit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/XRateLimitRemaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/XRateLimitReset"
              },
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              },
              "X-Idempotent-Replay": {
                "$ref": "#/components/headers/X-Idempotent-Replay"
              },
              "X-Idempotency-Status": {
                "$ref": "#/components/headers/X-Idempotency-Status"
              },
              "traceparent": {
                "$ref": "#/components/headers/Traceparent"
              },
              "Content-Language": {
                "$ref": "#/components/headers/Content-Language"
              }
            }
          },
          "400": {
            "description": "Bad request",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              },
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                },
                "examples": {
                  "error": {
                    "$ref": "#/components/examples/ErrorBadRequest"
                  }
                }
              }
            },
            "headers": {
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/XRateLimitLimit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/XRateLimitRemaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/XRateLimitReset"
              },
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "403": {
            "$ref": "#/components/responses/Forbidden",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "404": {
            "$ref": "#/components/responses/NotFound",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "409": {
            "$ref": "#/components/responses/Conflict",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "429": {
            "$ref": "#/components/responses/TooManyRequests",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "500": {
            "$ref": "#/components/responses/InternalServerError",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          }
        },
        "x-codeSamples": [
          {
            "lang": "cURL",
            "label": "cURL",
            "source": "curl -X POST \"https://api.kangopenbanking.com/v1/gateway/funding-intents\" \\\n  -H \"Authorization: Bearer $KOB_ACCESS_TOKEN\" \\\n  -H \"Content-Type: application/json\" \\\n  -d '{}'"
          },
          {
            "lang": "JavaScript",
            "label": "Node.js",
            "source": "import { KangOpenBanking } from \"@kangopenbanking/sdk\";\n\nconst kob = new KangOpenBanking({ apiKey: process.env.KOB_API_KEY });\nconst res = await kob.request(\"POST\", \"/v1/gateway/funding-intents\", { /* payload */ });\nconsole.log(res);"
          },
          {
            "lang": "Python",
            "label": "Python",
            "source": "from kangopenbanking import KangOpenBanking\n\nkob = KangOpenBanking(api_key=os.environ[\"KOB_API_KEY\"])\nres = kob.request(\"POST\", \"/v1/gateway/funding-intents\", json={})\nprint(res)"
          },
          {
            "lang": "PHP",
            "label": "PHP",
            "source": "<?php\n$kob = new KangOpenBanking\\KangOpenBanking(getenv('KOB_API_KEY'));\n$res = $kob->request('POST', '/v1/gateway/funding-intents', []);\nprint_r($res);"
          }
        ]
      },
      "get": {
        "tags": [
          "Payment Gateway"
        ],
        "summary": "List funding intents",
        "operationId": "gatewayListFundingIntents",
        "security": [
          {
            "bearerAuth": []
          }
        ],
        "parameters": [
          {
            "name": "status",
            "in": "query",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "limit",
            "in": "query",
            "schema": {
              "type": "integer",
              "default": 25,
              "maximum": 100
            },
            "description": "Items per page"
          },
          {
            "name": "offset",
            "in": "query",
            "schema": {
              "type": "integer",
              "default": 0
            },
            "description": "Items to skip"
          },
          {
            "name": "sort_by",
            "in": "query",
            "schema": {
              "type": "string",
              "default": "created_at"
            },
            "description": "Sort field"
          },
          {
            "name": "sort_order",
            "in": "query",
            "schema": {
              "type": "string",
              "enum": [
                "asc",
                "desc"
              ],
              "default": "desc"
            },
            "description": "Sort direction"
          },
          {
            "$ref": "#/components/parameters/StartingAfter"
          },
          {
            "$ref": "#/components/parameters/EndingBefore"
          },
          {
            "$ref": "#/components/parameters/RequestId"
          },
          {
            "$ref": "#/components/parameters/Traceparent"
          },
          {
            "$ref": "#/components/parameters/Tracestate"
          },
          {
            "$ref": "#/components/parameters/AcceptLanguage"
          }
        ],
        "responses": {
          "200": {
            "description": "Funding intents list",
            "content": {
              "application/json": {
                "schema": {
                  "allOf": [
                    {
                      "$ref": "#/components/schemas/PaginatedResponse"
                    },
                    {
                      "type": "object",
                      "properties": {
                        "data": {
                          "type": "array",
                          "items": {}
                        }
                      }
                    }
                  ]
                },
                "example": {
                  "data": [
                    {}
                  ],
                  "pagination": {
                    "page": 1,
                    "limit": 20,
                    "total": 150,
                    "has_next": true,
                    "next_cursor": "eyJpZCI6IjEyMyJ9"
                  },
                  "meta": {
                    "request_id": "550e8400-e29b-41d4-a716-446655440000",
                    "timestamp": "2025-03-27T12:00:00Z",
                    "api_version": "4.3.0"
                  }
                }
              }
            },
            "headers": {
              "x-fapi-interaction-id": {
                "$ref": "#/components/headers/XFapiInteractionIdResponse"
              },
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/XRateLimitLimit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/XRateLimitRemaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/XRateLimitReset"
              },
              "Cache-Control": {
                "$ref": "#/components/headers/CacheControl"
              },
              "ETag": {
                "$ref": "#/components/headers/ETag"
              },
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              },
              "traceparent": {
                "$ref": "#/components/headers/Traceparent"
              },
              "Content-Language": {
                "$ref": "#/components/headers/Content-Language"
              }
            }
          },
          "400": {
            "description": "Bad request",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              },
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                },
                "examples": {
                  "error": {
                    "$ref": "#/components/examples/ErrorBadRequest"
                  }
                }
              }
            },
            "headers": {
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/XRateLimitLimit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/XRateLimitRemaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/XRateLimitReset"
              },
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "403": {
            "$ref": "#/components/responses/Forbidden",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "404": {
            "$ref": "#/components/responses/NotFound",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "409": {
            "$ref": "#/components/responses/Conflict",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "429": {
            "$ref": "#/components/responses/TooManyRequests",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "500": {
            "$ref": "#/components/responses/InternalServerError",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          }
        },
        "x-codeSamples": [
          {
            "lang": "cURL",
            "label": "cURL",
            "source": "curl -X GET \"https://api.kangopenbanking.com/v1/gateway/funding-intents\" \\\n  -H \"Authorization: Bearer $KOB_ACCESS_TOKEN\" \\\n  -H \"Content-Type: application/json\""
          },
          {
            "lang": "JavaScript",
            "label": "Node.js",
            "source": "import { KangOpenBanking } from \"@kangopenbanking/sdk\";\n\nconst kob = new KangOpenBanking({ apiKey: process.env.KOB_API_KEY });\nconst res = await kob.request(\"GET\", \"/v1/gateway/funding-intents\");\nconsole.log(res);"
          },
          {
            "lang": "Python",
            "label": "Python",
            "source": "from kangopenbanking import KangOpenBanking\n\nkob = KangOpenBanking(api_key=os.environ[\"KOB_API_KEY\"])\nres = kob.request(\"GET\", \"/v1/gateway/funding-intents\")\nprint(res)"
          },
          {
            "lang": "PHP",
            "label": "PHP",
            "source": "<?php\n$kob = new KangOpenBanking\\KangOpenBanking(getenv('KOB_API_KEY'));\n$res = $kob->request('GET', '/v1/gateway/funding-intents');\nprint_r($res);"
          }
        ]
      }
    },
    "/v1/gateway/funding-intents/{intentId}": {
      "get": {
        "tags": [
          "Payment Gateway"
        ],
        "summary": "Get funding intent",
        "operationId": "gatewayGetFundingIntent",
        "security": [
          {
            "bearerAuth": []
          }
        ],
        "parameters": [
          {
            "name": "intentId",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "$ref": "#/components/parameters/RequestId"
          },
          {
            "$ref": "#/components/parameters/Traceparent"
          },
          {
            "$ref": "#/components/parameters/Tracestate"
          },
          {
            "$ref": "#/components/parameters/AcceptLanguage"
          }
        ],
        "responses": {
          "200": {
            "description": "Funding intent details",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "id": {
                      "type": "string"
                    },
                    "amount": {
                      "type": "string",
                      "pattern": "^[0-9]{1,15}$",
                      "description": "Represented as a string integer in the currency's minor unit (XAF has no subunits). Must be consistent with the currency field."
                    },
                    "currency": {
                      "type": "string",
                      "enum": [
                        "XAF",
                        "XOF",
                        "USD",
                        "EUR",
                        "GBP",
                        "CNY",
                        "NGN",
                        "GHS",
                        "KES",
                        "ZAR"
                      ],
                      "default": "XAF",
                      "description": "ISO 4217 currency code. Default is XAF (Central African CFA Franc)."
                    },
                    "source": {
                      "type": "string"
                    },
                    "status": {
                      "type": "string"
                    },
                    "redirect_url": {
                      "type": "string"
                    },
                    "created_at": {
                      "type": "string",
                      "format": "date-time"
                    }
                  }
                },
                "example": {
                  "id": "string",
                  "amount": "1000",
                  "currency": "XAF",
                  "source": "string",
                  "status": "string",
                  "redirect_url": "string",
                  "created_at": "2026-01-01T00:00:00Z"
                }
              }
            },
            "headers": {
              "x-fapi-interaction-id": {
                "$ref": "#/components/headers/XFapiInteractionIdResponse"
              },
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/XRateLimitLimit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/XRateLimitRemaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/XRateLimitReset"
              },
              "Cache-Control": {
                "$ref": "#/components/headers/CacheControl"
              },
              "ETag": {
                "$ref": "#/components/headers/ETag"
              },
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              },
              "traceparent": {
                "$ref": "#/components/headers/Traceparent"
              },
              "Content-Language": {
                "$ref": "#/components/headers/Content-Language"
              }
            }
          },
          "400": {
            "description": "Bad request",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              },
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                },
                "examples": {
                  "error": {
                    "$ref": "#/components/examples/ErrorBadRequest"
                  }
                }
              }
            },
            "headers": {
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/XRateLimitLimit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/XRateLimitRemaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/XRateLimitReset"
              },
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "403": {
            "$ref": "#/components/responses/Forbidden",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "404": {
            "$ref": "#/components/responses/NotFound",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "409": {
            "$ref": "#/components/responses/Conflict",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "429": {
            "$ref": "#/components/responses/TooManyRequests",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "500": {
            "$ref": "#/components/responses/InternalServerError",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          }
        },
        "x-codeSamples": [
          {
            "lang": "cURL",
            "label": "cURL",
            "source": "curl -X GET \"https://api.kangopenbanking.com/v1/gateway/funding-intents/{intentId}\" \\\n  -H \"Authorization: Bearer $KOB_ACCESS_TOKEN\" \\\n  -H \"Content-Type: application/json\""
          },
          {
            "lang": "JavaScript",
            "label": "Node.js",
            "source": "import { KangOpenBanking } from \"@kangopenbanking/sdk\";\n\nconst kob = new KangOpenBanking({ apiKey: process.env.KOB_API_KEY });\nconst res = await kob.request(\"GET\", \"/v1/gateway/funding-intents/{intentId}\");\nconsole.log(res);"
          },
          {
            "lang": "Python",
            "label": "Python",
            "source": "from kangopenbanking import KangOpenBanking\n\nkob = KangOpenBanking(api_key=os.environ[\"KOB_API_KEY\"])\nres = kob.request(\"GET\", \"/v1/gateway/funding-intents/{intentId}\")\nprint(res)"
          },
          {
            "lang": "PHP",
            "label": "PHP",
            "source": "<?php\n$kob = new KangOpenBanking\\KangOpenBanking(getenv('KOB_API_KEY'));\n$res = $kob->request('GET', '/v1/gateway/funding-intents/{intentId}');\nprint_r($res);"
          }
        ]
      }
    },
    "/v1/gateway/funding-intents/{intentId}/cancel": {
      "post": {
        "tags": [
          "Payment Gateway"
        ],
        "summary": "Cancel funding intent",
        "operationId": "gatewayCancelFundingIntent",
        "security": [
          {
            "bearerAuth": []
          }
        ],
        "parameters": [
          {
            "name": "intentId",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "$ref": "#/components/parameters/IdempotencyKey"
          },
          {
            "$ref": "#/components/parameters/RequestId"
          },
          {
            "$ref": "#/components/parameters/Traceparent"
          },
          {
            "$ref": "#/components/parameters/Tracestate"
          },
          {
            "$ref": "#/components/parameters/AcceptLanguage"
          }
        ],
        "responses": {
          "200": {
            "description": "Funding intent cancelled",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "success": {
                      "type": "boolean",
                      "example": true
                    },
                    "message": {
                      "type": "string"
                    }
                  }
                },
                "example": {
                  "success": true,
                  "message": "string"
                }
              }
            },
            "headers": {
              "x-fapi-interaction-id": {
                "$ref": "#/components/headers/XFapiInteractionIdResponse"
              },
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/XRateLimitLimit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/XRateLimitRemaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/XRateLimitReset"
              },
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              },
              "X-Idempotent-Replay": {
                "$ref": "#/components/headers/X-Idempotent-Replay"
              },
              "X-Idempotency-Status": {
                "$ref": "#/components/headers/X-Idempotency-Status"
              },
              "traceparent": {
                "$ref": "#/components/headers/Traceparent"
              },
              "Content-Language": {
                "$ref": "#/components/headers/Content-Language"
              }
            }
          },
          "400": {
            "description": "Bad request",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              },
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                },
                "examples": {
                  "error": {
                    "$ref": "#/components/examples/ErrorBadRequest"
                  }
                }
              }
            },
            "headers": {
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/XRateLimitLimit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/XRateLimitRemaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/XRateLimitReset"
              },
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "403": {
            "$ref": "#/components/responses/Forbidden",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "404": {
            "$ref": "#/components/responses/NotFound",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "409": {
            "$ref": "#/components/responses/Conflict",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "429": {
            "$ref": "#/components/responses/TooManyRequests",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "500": {
            "$ref": "#/components/responses/InternalServerError",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          }
        },
        "x-codeSamples": [
          {
            "lang": "cURL",
            "label": "cURL",
            "source": "curl -X POST \"https://api.kangopenbanking.com/v1/gateway/funding-intents/{intentId}/cancel\" \\\n  -H \"Authorization: Bearer $KOB_ACCESS_TOKEN\" \\\n  -H \"Content-Type: application/json\""
          },
          {
            "lang": "JavaScript",
            "label": "Node.js",
            "source": "import { KangOpenBanking } from \"@kangopenbanking/sdk\";\n\nconst kob = new KangOpenBanking({ apiKey: process.env.KOB_API_KEY });\nconst res = await kob.request(\"POST\", \"/v1/gateway/funding-intents/{intentId}/cancel\");\nconsole.log(res);"
          },
          {
            "lang": "Python",
            "label": "Python",
            "source": "from kangopenbanking import KangOpenBanking\n\nkob = KangOpenBanking(api_key=os.environ[\"KOB_API_KEY\"])\nres = kob.request(\"POST\", \"/v1/gateway/funding-intents/{intentId}/cancel\")\nprint(res)"
          },
          {
            "lang": "PHP",
            "label": "PHP",
            "source": "<?php\n$kob = new KangOpenBanking\\KangOpenBanking(getenv('KOB_API_KEY'));\n$res = $kob->request('POST', '/v1/gateway/funding-intents/{intentId}/cancel');\nprint_r($res);"
          }
        ]
      }
    },
    "/v1/gateway/funding-intents/{intentId}/confirm": {
      "post": {
        "tags": [
          "Payment Gateway"
        ],
        "summary": "Confirm funding intent",
        "description": "Confirm a funding intent after provider payment succeeds.",
        "operationId": "gatewayConfirmFundingIntent",
        "security": [
          {
            "bearerAuth": []
          }
        ],
        "parameters": [
          {
            "name": "intentId",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "$ref": "#/components/parameters/IdempotencyKey"
          },
          {
            "$ref": "#/components/parameters/RequestId"
          },
          {
            "$ref": "#/components/parameters/Traceparent"
          },
          {
            "$ref": "#/components/parameters/Tracestate"
          },
          {
            "$ref": "#/components/parameters/AcceptLanguage"
          }
        ],
        "responses": {
          "200": {
            "description": "Funding confirmed and account credited",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "success": {
                      "type": "boolean",
                      "example": true
                    },
                    "message": {
                      "type": "string"
                    }
                  }
                },
                "example": {
                  "success": true,
                  "message": "string"
                }
              }
            },
            "headers": {
              "x-fapi-interaction-id": {
                "$ref": "#/components/headers/XFapiInteractionIdResponse"
              },
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/XRateLimitLimit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/XRateLimitRemaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/XRateLimitReset"
              },
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              },
              "X-Idempotent-Replay": {
                "$ref": "#/components/headers/X-Idempotent-Replay"
              },
              "X-Idempotency-Status": {
                "$ref": "#/components/headers/X-Idempotency-Status"
              },
              "traceparent": {
                "$ref": "#/components/headers/Traceparent"
              },
              "Content-Language": {
                "$ref": "#/components/headers/Content-Language"
              }
            }
          },
          "400": {
            "description": "Bad request",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              },
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                },
                "examples": {
                  "error": {
                    "$ref": "#/components/examples/ErrorBadRequest"
                  }
                }
              }
            },
            "headers": {
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/XRateLimitLimit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/XRateLimitRemaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/XRateLimitReset"
              },
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "403": {
            "$ref": "#/components/responses/Forbidden",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "404": {
            "$ref": "#/components/responses/NotFound",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "409": {
            "$ref": "#/components/responses/Conflict",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "429": {
            "$ref": "#/components/responses/TooManyRequests",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "500": {
            "$ref": "#/components/responses/InternalServerError",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          }
        },
        "x-codeSamples": [
          {
            "lang": "cURL",
            "label": "cURL",
            "source": "curl -X POST \"https://api.kangopenbanking.com/v1/gateway/funding-intents/{intentId}/confirm\" \\\n  -H \"Authorization: Bearer $KOB_ACCESS_TOKEN\" \\\n  -H \"Content-Type: application/json\""
          },
          {
            "lang": "JavaScript",
            "label": "Node.js",
            "source": "import { KangOpenBanking } from \"@kangopenbanking/sdk\";\n\nconst kob = new KangOpenBanking({ apiKey: process.env.KOB_API_KEY });\nconst res = await kob.request(\"POST\", \"/v1/gateway/funding-intents/{intentId}/confirm\");\nconsole.log(res);"
          },
          {
            "lang": "Python",
            "label": "Python",
            "source": "from kangopenbanking import KangOpenBanking\n\nkob = KangOpenBanking(api_key=os.environ[\"KOB_API_KEY\"])\nres = kob.request(\"POST\", \"/v1/gateway/funding-intents/{intentId}/confirm\")\nprint(res)"
          },
          {
            "lang": "PHP",
            "label": "PHP",
            "source": "<?php\n$kob = new KangOpenBanking\\KangOpenBanking(getenv('KOB_API_KEY'));\n$res = $kob->request('POST', '/v1/gateway/funding-intents/{intentId}/confirm');\nprint_r($res);"
          }
        ]
      }
    },
    "/v1/teller/transaction": {
      "post": {
        "tags": [
          "Banking Operations"
        ],
        "summary": "Teller transaction",
        "description": "Process a cash deposit or withdrawal at a bank branch by an authorized teller.",
        "operationId": "tellerTransaction",
        "security": [
          {
            "bearerAuth": []
          }
        ],
        "parameters": [
          {
            "name": "Idempotency-Key",
            "in": "header",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid"
            },
            "description": "Required on all POST/PUT endpoints. Unique key for idempotent request processing (UUID v4 recommended). Keys expire after 24 hours."
          },
          {
            "$ref": "#/components/parameters/RequestId"
          },
          {
            "$ref": "#/components/parameters/Traceparent"
          },
          {
            "$ref": "#/components/parameters/Tracestate"
          },
          {
            "$ref": "#/components/parameters/AcceptLanguage"
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "required": [
                  "account_id",
                  "amount",
                  "transaction_type"
                ],
                "properties": {
                  "account_id": {
                    "type": "string",
                    "format": "uuid"
                  },
                  "amount": {
                    "type": "string",
                    "example": "100000",
                    "pattern": "^[0-9]{1,15}$",
                    "description": "Represented as a string integer in the currency's minor unit (XAF has no subunits). Must be consistent with the currency field."
                  },
                  "currency": {
                    "type": "string",
                    "default": "XAF",
                    "enum": [
                      "XAF",
                      "XOF",
                      "USD",
                      "EUR",
                      "GBP",
                      "CNY",
                      "NGN",
                      "GHS",
                      "KES",
                      "ZAR"
                    ],
                    "description": "ISO 4217 currency code. Default is XAF (Central African CFA Franc)."
                  },
                  "transaction_type": {
                    "type": "string",
                    "enum": [
                      "deposit",
                      "withdrawal"
                    ]
                  },
                  "narration": {
                    "type": "string"
                  },
                  "branch_id": {
                    "type": "string",
                    "format": "uuid"
                  }
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Transaction processed",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "transaction_id": {
                      "type": "string",
                      "format": "uuid"
                    },
                    "status": {
                      "type": "string"
                    },
                    "amount": {
                      "type": "string",
                      "pattern": "^[0-9]{1,15}$",
                      "description": "Represented as a string integer in the currency's minor unit (XAF has no subunits)."
                    },
                    "balance_after": {
                      "type": "number"
                    }
                  }
                },
                "example": {
                  "transaction_id": "00000000-0000-4000-8000-000000000000",
                  "status": "string",
                  "amount": "1000",
                  "balance_after": 0
                }
              }
            },
            "headers": {
              "x-fapi-interaction-id": {
                "$ref": "#/components/headers/XFapiInteractionIdResponse"
              },
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/XRateLimitLimit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/XRateLimitRemaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/XRateLimitReset"
              },
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              },
              "X-Idempotent-Replay": {
                "$ref": "#/components/headers/X-Idempotent-Replay"
              },
              "X-Idempotency-Status": {
                "$ref": "#/components/headers/X-Idempotency-Status"
              },
              "traceparent": {
                "$ref": "#/components/headers/Traceparent"
              },
              "Content-Language": {
                "$ref": "#/components/headers/Content-Language"
              }
            }
          },
          "400": {
            "description": "Bad request",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              },
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                },
                "examples": {
                  "error": {
                    "$ref": "#/components/examples/ErrorBadRequest"
                  }
                }
              }
            },
            "headers": {
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/XRateLimitLimit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/XRateLimitRemaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/XRateLimitReset"
              },
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "403": {
            "$ref": "#/components/responses/Forbidden",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "404": {
            "$ref": "#/components/responses/NotFound",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "409": {
            "$ref": "#/components/responses/Conflict",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "429": {
            "$ref": "#/components/responses/TooManyRequests",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "500": {
            "$ref": "#/components/responses/InternalServerError",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          }
        },
        "x-codeSamples": [
          {
            "lang": "cURL",
            "label": "cURL",
            "source": "curl -X POST \"https://api.kangopenbanking.com/v1/teller/transaction\" \\\n  -H \"Authorization: Bearer $KOB_ACCESS_TOKEN\" \\\n  -H \"Content-Type: application/json\" \\\n  -d '{}'"
          },
          {
            "lang": "JavaScript",
            "label": "Node.js",
            "source": "import { KangOpenBanking } from \"@kangopenbanking/sdk\";\n\nconst kob = new KangOpenBanking({ apiKey: process.env.KOB_API_KEY });\nconst res = await kob.request(\"POST\", \"/v1/teller/transaction\", { /* payload */ });\nconsole.log(res);"
          },
          {
            "lang": "Python",
            "label": "Python",
            "source": "from kangopenbanking import KangOpenBanking\n\nkob = KangOpenBanking(api_key=os.environ[\"KOB_API_KEY\"])\nres = kob.request(\"POST\", \"/v1/teller/transaction\", json={})\nprint(res)"
          },
          {
            "lang": "PHP",
            "label": "PHP",
            "source": "<?php\n$kob = new KangOpenBanking\\KangOpenBanking(getenv('KOB_API_KEY'));\n$res = $kob->request('POST', '/v1/teller/transaction', []);\nprint_r($res);"
          }
        ]
      }
    },
    "/v1/admin/withdrawal-policies": {
      "get": {
        "tags": [
          "Operational Controls"
        ],
        "summary": "List withdrawal policies",
        "operationId": "listWithdrawalPolicies",
        "security": [
          {
            "bearerAuth": []
          }
        ],
        "parameters": [
          {
            "name": "institution_id",
            "in": "query",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          },
          {
            "$ref": "#/components/parameters/RequestId"
          },
          {
            "$ref": "#/components/parameters/Traceparent"
          },
          {
            "$ref": "#/components/parameters/Tracestate"
          },
          {
            "$ref": "#/components/parameters/AcceptLanguage"
          }
        ],
        "responses": {
          "200": {
            "description": "Withdrawal policies list",
            "content": {
              "application/json": {
                "schema": {
                  "allOf": [
                    {
                      "$ref": "#/components/schemas/PaginatedResponse"
                    },
                    {
                      "type": "object",
                      "properties": {
                        "data": {
                          "type": "array",
                          "items": {}
                        }
                      }
                    }
                  ]
                },
                "example": {
                  "data": [
                    {}
                  ],
                  "pagination": {
                    "page": 1,
                    "limit": 20,
                    "total": 150,
                    "has_next": true,
                    "next_cursor": "eyJpZCI6IjEyMyJ9"
                  },
                  "meta": {
                    "request_id": "550e8400-e29b-41d4-a716-446655440000",
                    "timestamp": "2025-03-27T12:00:00Z",
                    "api_version": "4.3.0"
                  }
                }
              }
            },
            "headers": {
              "x-fapi-interaction-id": {
                "$ref": "#/components/headers/XFapiInteractionIdResponse"
              },
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/XRateLimitLimit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/XRateLimitRemaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/XRateLimitReset"
              },
              "Cache-Control": {
                "$ref": "#/components/headers/CacheControl"
              },
              "ETag": {
                "$ref": "#/components/headers/ETag"
              },
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              },
              "traceparent": {
                "$ref": "#/components/headers/Traceparent"
              },
              "Content-Language": {
                "$ref": "#/components/headers/Content-Language"
              }
            }
          },
          "400": {
            "description": "Bad request",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              },
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                },
                "examples": {
                  "error": {
                    "$ref": "#/components/examples/ErrorBadRequest"
                  }
                }
              }
            },
            "headers": {
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/XRateLimitLimit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/XRateLimitRemaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/XRateLimitReset"
              },
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "403": {
            "$ref": "#/components/responses/Forbidden",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "404": {
            "$ref": "#/components/responses/NotFound",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "409": {
            "$ref": "#/components/responses/Conflict",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "429": {
            "$ref": "#/components/responses/TooManyRequests",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "500": {
            "$ref": "#/components/responses/InternalServerError",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          }
        },
        "x-codeSamples": [
          {
            "lang": "cURL",
            "label": "cURL",
            "source": "curl -X GET \"https://api.kangopenbanking.com/v1/admin/withdrawal-policies\" \\\n  -H \"Authorization: Bearer $KOB_ACCESS_TOKEN\" \\\n  -H \"Content-Type: application/json\""
          },
          {
            "lang": "JavaScript",
            "label": "Node.js",
            "source": "import { KangOpenBanking } from \"@kangopenbanking/sdk\";\n\nconst kob = new KangOpenBanking({ apiKey: process.env.KOB_API_KEY });\nconst res = await kob.request(\"GET\", \"/v1/admin/withdrawal-policies\");\nconsole.log(res);"
          },
          {
            "lang": "Python",
            "label": "Python",
            "source": "from kangopenbanking import KangOpenBanking\n\nkob = KangOpenBanking(api_key=os.environ[\"KOB_API_KEY\"])\nres = kob.request(\"GET\", \"/v1/admin/withdrawal-policies\")\nprint(res)"
          },
          {
            "lang": "PHP",
            "label": "PHP",
            "source": "<?php\n$kob = new KangOpenBanking\\KangOpenBanking(getenv('KOB_API_KEY'));\n$res = $kob->request('GET', '/v1/admin/withdrawal-policies');\nprint_r($res);"
          }
        ]
      },
      "post": {
        "tags": [
          "Operational Controls"
        ],
        "summary": "Create withdrawal policy",
        "operationId": "createWithdrawalPolicy",
        "security": [
          {
            "bearerAuth": []
          }
        ],
        "parameters": [
          {
            "name": "Idempotency-Key",
            "in": "header",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid"
            },
            "description": "Required on all POST/PUT endpoints. Unique key for idempotent request processing (UUID v4 recommended). Keys expire after 24 hours."
          },
          {
            "$ref": "#/components/parameters/RequestId"
          },
          {
            "$ref": "#/components/parameters/Traceparent"
          },
          {
            "$ref": "#/components/parameters/Tracestate"
          },
          {
            "$ref": "#/components/parameters/AcceptLanguage"
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "required": [
                  "institution_id",
                  "role_type",
                  "single_txn_limit",
                  "daily_total_limit"
                ],
                "properties": {
                  "institution_id": {
                    "type": "string",
                    "format": "uuid"
                  },
                  "branch_id": {
                    "type": "string",
                    "format": "uuid"
                  },
                  "currency": {
                    "type": "string",
                    "default": "XAF",
                    "enum": [
                      "XAF",
                      "XOF",
                      "USD",
                      "EUR",
                      "GBP",
                      "CNY",
                      "NGN",
                      "GHS",
                      "KES",
                      "ZAR"
                    ],
                    "description": "ISO 4217 currency code. Default is XAF (Central African CFA Franc)."
                  },
                  "channel": {
                    "type": "string"
                  },
                  "role_type": {
                    "type": "string",
                    "enum": [
                      "teller",
                      "assistant_manager",
                      "branch_manager",
                      "general_manager"
                    ]
                  },
                  "single_txn_limit": {
                    "type": "number",
                    "example": 500000
                  },
                  "daily_total_limit": {
                    "type": "number",
                    "example": 5000000
                  },
                  "auto_approve_threshold": {
                    "type": "number",
                    "example": 100000
                  },
                  "requires_dual_approval_above": {
                    "type": "number"
                  },
                  "escalation_target_role": {
                    "type": "string",
                    "enum": [
                      "assistant_manager",
                      "branch_manager",
                      "general_manager"
                    ]
                  },
                  "can_override_lower_role": {
                    "type": "boolean"
                  },
                  "effective_from": {
                    "type": "string",
                    "format": "date"
                  },
                  "effective_to": {
                    "type": "string",
                    "format": "date"
                  }
                }
              }
            }
          }
        },
        "responses": {
          "201": {
            "description": "Policy created",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "success": {
                      "type": "boolean",
                      "example": true
                    },
                    "message": {
                      "type": "string"
                    }
                  }
                },
                "example": {
                  "success": true,
                  "message": "string"
                }
              }
            },
            "headers": {
              "x-fapi-interaction-id": {
                "$ref": "#/components/headers/XFapiInteractionIdResponse"
              },
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/XRateLimitLimit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/XRateLimitRemaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/XRateLimitReset"
              },
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              },
              "traceparent": {
                "$ref": "#/components/headers/Traceparent"
              },
              "Content-Language": {
                "$ref": "#/components/headers/Content-Language"
              }
            }
          },
          "400": {
            "description": "Bad request",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              },
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                },
                "examples": {
                  "error": {
                    "$ref": "#/components/examples/ErrorBadRequest"
                  }
                }
              }
            },
            "headers": {
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/XRateLimitLimit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/XRateLimitRemaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/XRateLimitReset"
              },
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "403": {
            "$ref": "#/components/responses/Forbidden",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "404": {
            "$ref": "#/components/responses/NotFound",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "409": {
            "$ref": "#/components/responses/Conflict",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "429": {
            "$ref": "#/components/responses/TooManyRequests",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "500": {
            "$ref": "#/components/responses/InternalServerError",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          }
        },
        "x-codeSamples": [
          {
            "lang": "cURL",
            "label": "cURL",
            "source": "curl -X POST \"https://api.kangopenbanking.com/v1/admin/withdrawal-policies\" \\\n  -H \"Authorization: Bearer $KOB_ACCESS_TOKEN\" \\\n  -H \"Content-Type: application/json\" \\\n  -d '{}'"
          },
          {
            "lang": "JavaScript",
            "label": "Node.js",
            "source": "import { KangOpenBanking } from \"@kangopenbanking/sdk\";\n\nconst kob = new KangOpenBanking({ apiKey: process.env.KOB_API_KEY });\nconst res = await kob.request(\"POST\", \"/v1/admin/withdrawal-policies\", { /* payload */ });\nconsole.log(res);"
          },
          {
            "lang": "Python",
            "label": "Python",
            "source": "from kangopenbanking import KangOpenBanking\n\nkob = KangOpenBanking(api_key=os.environ[\"KOB_API_KEY\"])\nres = kob.request(\"POST\", \"/v1/admin/withdrawal-policies\", json={})\nprint(res)"
          },
          {
            "lang": "PHP",
            "label": "PHP",
            "source": "<?php\n$kob = new KangOpenBanking\\KangOpenBanking(getenv('KOB_API_KEY'));\n$res = $kob->request('POST', '/v1/admin/withdrawal-policies', []);\nprint_r($res);"
          }
        ]
      }
    },
    "/v1/admin/withdrawal-policies/{policyId}": {
      "get": {
        "tags": [
          "Operational Controls"
        ],
        "summary": "Get withdrawal policy",
        "operationId": "getWithdrawalPolicy",
        "security": [
          {
            "bearerAuth": []
          }
        ],
        "parameters": [
          {
            "name": "policyId",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "$ref": "#/components/parameters/RequestId"
          },
          {
            "$ref": "#/components/parameters/Traceparent"
          },
          {
            "$ref": "#/components/parameters/Tracestate"
          },
          {
            "$ref": "#/components/parameters/AcceptLanguage"
          }
        ],
        "responses": {
          "200": {
            "description": "Policy details",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "id": {
                      "type": "string"
                    },
                    "role_type": {
                      "type": "string"
                    },
                    "single_txn_limit": {
                      "type": "number"
                    },
                    "daily_total_limit": {
                      "type": "number"
                    },
                    "auto_approve_threshold": {
                      "type": "number"
                    },
                    "status": {
                      "type": "string"
                    }
                  }
                },
                "example": {
                  "id": "string",
                  "role_type": "string",
                  "single_txn_limit": 0,
                  "daily_total_limit": 0,
                  "auto_approve_threshold": 0,
                  "status": "string"
                }
              }
            },
            "headers": {
              "x-fapi-interaction-id": {
                "$ref": "#/components/headers/XFapiInteractionIdResponse"
              },
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/XRateLimitLimit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/XRateLimitRemaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/XRateLimitReset"
              },
              "Cache-Control": {
                "$ref": "#/components/headers/CacheControl"
              },
              "ETag": {
                "$ref": "#/components/headers/ETag"
              },
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              },
              "traceparent": {
                "$ref": "#/components/headers/Traceparent"
              },
              "Content-Language": {
                "$ref": "#/components/headers/Content-Language"
              }
            }
          },
          "400": {
            "description": "Bad request",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              },
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                },
                "examples": {
                  "error": {
                    "$ref": "#/components/examples/ErrorBadRequest"
                  }
                }
              }
            },
            "headers": {
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/XRateLimitLimit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/XRateLimitRemaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/XRateLimitReset"
              },
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "403": {
            "$ref": "#/components/responses/Forbidden",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "404": {
            "$ref": "#/components/responses/NotFound",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "409": {
            "$ref": "#/components/responses/Conflict",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "429": {
            "$ref": "#/components/responses/TooManyRequests",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "500": {
            "$ref": "#/components/responses/InternalServerError",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          }
        },
        "x-codeSamples": [
          {
            "lang": "cURL",
            "label": "cURL",
            "source": "curl -X GET \"https://api.kangopenbanking.com/v1/admin/withdrawal-policies/{policyId}\" \\\n  -H \"Authorization: Bearer $KOB_ACCESS_TOKEN\" \\\n  -H \"Content-Type: application/json\""
          },
          {
            "lang": "JavaScript",
            "label": "Node.js",
            "source": "import { KangOpenBanking } from \"@kangopenbanking/sdk\";\n\nconst kob = new KangOpenBanking({ apiKey: process.env.KOB_API_KEY });\nconst res = await kob.request(\"GET\", \"/v1/admin/withdrawal-policies/{policyId}\");\nconsole.log(res);"
          },
          {
            "lang": "Python",
            "label": "Python",
            "source": "from kangopenbanking import KangOpenBanking\n\nkob = KangOpenBanking(api_key=os.environ[\"KOB_API_KEY\"])\nres = kob.request(\"GET\", \"/v1/admin/withdrawal-policies/{policyId}\")\nprint(res)"
          },
          {
            "lang": "PHP",
            "label": "PHP",
            "source": "<?php\n$kob = new KangOpenBanking\\KangOpenBanking(getenv('KOB_API_KEY'));\n$res = $kob->request('GET', '/v1/admin/withdrawal-policies/{policyId}');\nprint_r($res);"
          }
        ]
      },
      "patch": {
        "tags": [
          "Operational Controls"
        ],
        "summary": "Update withdrawal policy",
        "operationId": "updateWithdrawalPolicy",
        "security": [
          {
            "bearerAuth": []
          }
        ],
        "parameters": [
          {
            "name": "policyId",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "$ref": "#/components/parameters/RequestId"
          },
          {
            "$ref": "#/components/parameters/Traceparent"
          },
          {
            "$ref": "#/components/parameters/Tracestate"
          },
          {
            "$ref": "#/components/parameters/AcceptLanguage"
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "single_txn_limit": {
                    "type": "number"
                  },
                  "daily_total_limit": {
                    "type": "number"
                  },
                  "status": {
                    "type": "string"
                  },
                  "effective_to": {
                    "type": "string",
                    "format": "date"
                  }
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Policy updated",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "success": {
                      "type": "boolean",
                      "example": true
                    },
                    "message": {
                      "type": "string"
                    }
                  }
                },
                "example": {
                  "success": true,
                  "message": "string"
                }
              }
            },
            "headers": {
              "x-fapi-interaction-id": {
                "$ref": "#/components/headers/XFapiInteractionIdResponse"
              },
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/XRateLimitLimit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/XRateLimitRemaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/XRateLimitReset"
              },
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              },
              "traceparent": {
                "$ref": "#/components/headers/Traceparent"
              },
              "Content-Language": {
                "$ref": "#/components/headers/Content-Language"
              }
            }
          },
          "400": {
            "description": "Bad request",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              },
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                },
                "examples": {
                  "error": {
                    "$ref": "#/components/examples/ErrorBadRequest"
                  }
                }
              }
            },
            "headers": {
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/XRateLimitLimit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/XRateLimitRemaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/XRateLimitReset"
              },
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "403": {
            "$ref": "#/components/responses/Forbidden",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "404": {
            "$ref": "#/components/responses/NotFound",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "409": {
            "$ref": "#/components/responses/Conflict",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "429": {
            "$ref": "#/components/responses/TooManyRequests",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "500": {
            "$ref": "#/components/responses/InternalServerError",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          }
        },
        "x-codeSamples": [
          {
            "lang": "cURL",
            "label": "cURL",
            "source": "curl -X PATCH \"https://api.kangopenbanking.com/v1/admin/withdrawal-policies/{policyId}\" \\\n  -H \"Authorization: Bearer $KOB_ACCESS_TOKEN\" \\\n  -H \"Content-Type: application/json\" \\\n  -d '{}'"
          },
          {
            "lang": "JavaScript",
            "label": "Node.js",
            "source": "import { KangOpenBanking } from \"@kangopenbanking/sdk\";\n\nconst kob = new KangOpenBanking({ apiKey: process.env.KOB_API_KEY });\nconst res = await kob.request(\"PATCH\", \"/v1/admin/withdrawal-policies/{policyId}\", { /* payload */ });\nconsole.log(res);"
          },
          {
            "lang": "Python",
            "label": "Python",
            "source": "from kangopenbanking import KangOpenBanking\n\nkob = KangOpenBanking(api_key=os.environ[\"KOB_API_KEY\"])\nres = kob.request(\"PATCH\", \"/v1/admin/withdrawal-policies/{policyId}\", json={})\nprint(res)"
          },
          {
            "lang": "PHP",
            "label": "PHP",
            "source": "<?php\n$kob = new KangOpenBanking\\KangOpenBanking(getenv('KOB_API_KEY'));\n$res = $kob->request('PATCH', '/v1/admin/withdrawal-policies/{policyId}', []);\nprint_r($res);"
          }
        ]
      }
    },
    "/v1/admin/staff/authorizations": {
      "get": {
        "tags": [
          "Operational Controls"
        ],
        "summary": "List staff authorizations",
        "operationId": "listStaffAuthorizations",
        "security": [
          {
            "bearerAuth": []
          }
        ],
        "parameters": [
          {
            "name": "institution_id",
            "in": "query",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          },
          {
            "$ref": "#/components/parameters/RequestId"
          },
          {
            "$ref": "#/components/parameters/Traceparent"
          },
          {
            "$ref": "#/components/parameters/Tracestate"
          },
          {
            "$ref": "#/components/parameters/AcceptLanguage"
          }
        ],
        "responses": {
          "200": {
            "description": "Staff authorizations",
            "content": {
              "application/json": {
                "schema": {
                  "allOf": [
                    {
                      "$ref": "#/components/schemas/PaginatedResponse"
                    },
                    {
                      "type": "object",
                      "properties": {
                        "data": {
                          "type": "array",
                          "items": {}
                        }
                      }
                    }
                  ]
                },
                "example": {
                  "data": [
                    {}
                  ],
                  "pagination": {
                    "page": 1,
                    "limit": 20,
                    "total": 150,
                    "has_next": true,
                    "next_cursor": "eyJpZCI6IjEyMyJ9"
                  },
                  "meta": {
                    "request_id": "550e8400-e29b-41d4-a716-446655440000",
                    "timestamp": "2025-03-27T12:00:00Z",
                    "api_version": "4.3.0"
                  }
                }
              }
            },
            "headers": {
              "x-fapi-interaction-id": {
                "$ref": "#/components/headers/XFapiInteractionIdResponse"
              },
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/XRateLimitLimit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/XRateLimitRemaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/XRateLimitReset"
              },
              "Cache-Control": {
                "$ref": "#/components/headers/CacheControl"
              },
              "ETag": {
                "$ref": "#/components/headers/ETag"
              },
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              },
              "traceparent": {
                "$ref": "#/components/headers/Traceparent"
              },
              "Content-Language": {
                "$ref": "#/components/headers/Content-Language"
              }
            }
          },
          "400": {
            "description": "Bad request",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              },
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                },
                "examples": {
                  "error": {
                    "$ref": "#/components/examples/ErrorBadRequest"
                  }
                }
              }
            },
            "headers": {
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/XRateLimitLimit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/XRateLimitRemaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/XRateLimitReset"
              },
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "403": {
            "$ref": "#/components/responses/Forbidden",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "404": {
            "$ref": "#/components/responses/NotFound",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "409": {
            "$ref": "#/components/responses/Conflict",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "429": {
            "$ref": "#/components/responses/TooManyRequests",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "500": {
            "$ref": "#/components/responses/InternalServerError",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          }
        },
        "x-codeSamples": [
          {
            "lang": "cURL",
            "label": "cURL",
            "source": "curl -X GET \"https://api.kangopenbanking.com/v1/admin/staff/authorizations\" \\\n  -H \"Authorization: Bearer $KOB_ACCESS_TOKEN\" \\\n  -H \"Content-Type: application/json\""
          },
          {
            "lang": "JavaScript",
            "label": "Node.js",
            "source": "import { KangOpenBanking } from \"@kangopenbanking/sdk\";\n\nconst kob = new KangOpenBanking({ apiKey: process.env.KOB_API_KEY });\nconst res = await kob.request(\"GET\", \"/v1/admin/staff/authorizations\");\nconsole.log(res);"
          },
          {
            "lang": "Python",
            "label": "Python",
            "source": "from kangopenbanking import KangOpenBanking\n\nkob = KangOpenBanking(api_key=os.environ[\"KOB_API_KEY\"])\nres = kob.request(\"GET\", \"/v1/admin/staff/authorizations\")\nprint(res)"
          },
          {
            "lang": "PHP",
            "label": "PHP",
            "source": "<?php\n$kob = new KangOpenBanking\\KangOpenBanking(getenv('KOB_API_KEY'));\n$res = $kob->request('GET', '/v1/admin/staff/authorizations');\nprint_r($res);"
          }
        ]
      },
      "post": {
        "tags": [
          "Operational Controls"
        ],
        "summary": "Create staff authorization",
        "operationId": "createStaffAuthorization",
        "security": [
          {
            "bearerAuth": []
          }
        ],
        "parameters": [
          {
            "name": "Idempotency-Key",
            "in": "header",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid"
            },
            "description": "Required on all POST/PUT endpoints. Unique key for idempotent request processing (UUID v4 recommended). Keys expire after 24 hours."
          },
          {
            "$ref": "#/components/parameters/RequestId"
          },
          {
            "$ref": "#/components/parameters/Traceparent"
          },
          {
            "$ref": "#/components/parameters/Tracestate"
          },
          {
            "$ref": "#/components/parameters/AcceptLanguage"
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "required": [
                  "institution_id",
                  "user_id",
                  "role_type"
                ],
                "properties": {
                  "institution_id": {
                    "type": "string",
                    "format": "uuid"
                  },
                  "branch_id": {
                    "type": "string",
                    "format": "uuid"
                  },
                  "user_id": {
                    "type": "string",
                    "format": "uuid"
                  },
                  "role_type": {
                    "type": "string",
                    "enum": [
                      "teller",
                      "assistant_manager",
                      "branch_manager",
                      "general_manager"
                    ]
                  },
                  "max_override_limit": {
                    "type": "number"
                  },
                  "can_approve_overdraft": {
                    "type": "boolean"
                  },
                  "can_approve_withdrawal_override": {
                    "type": "boolean"
                  },
                  "can_suspend_overdraft": {
                    "type": "boolean"
                  }
                }
              }
            }
          }
        },
        "responses": {
          "201": {
            "description": "Authorization created",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "success": {
                      "type": "boolean",
                      "example": true
                    },
                    "message": {
                      "type": "string"
                    }
                  }
                },
                "example": {
                  "success": true,
                  "message": "string"
                }
              }
            },
            "headers": {
              "x-fapi-interaction-id": {
                "$ref": "#/components/headers/XFapiInteractionIdResponse"
              },
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/XRateLimitLimit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/XRateLimitRemaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/XRateLimitReset"
              },
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              },
              "traceparent": {
                "$ref": "#/components/headers/Traceparent"
              },
              "Content-Language": {
                "$ref": "#/components/headers/Content-Language"
              }
            }
          },
          "400": {
            "description": "Bad request",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              },
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                },
                "examples": {
                  "error": {
                    "$ref": "#/components/examples/ErrorBadRequest"
                  }
                }
              }
            },
            "headers": {
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/XRateLimitLimit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/XRateLimitRemaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/XRateLimitReset"
              },
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "403": {
            "$ref": "#/components/responses/Forbidden",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "404": {
            "$ref": "#/components/responses/NotFound",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "409": {
            "$ref": "#/components/responses/Conflict",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "429": {
            "$ref": "#/components/responses/TooManyRequests",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "500": {
            "$ref": "#/components/responses/InternalServerError",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          }
        },
        "x-codeSamples": [
          {
            "lang": "cURL",
            "label": "cURL",
            "source": "curl -X POST \"https://api.kangopenbanking.com/v1/admin/staff/authorizations\" \\\n  -H \"Authorization: Bearer $KOB_ACCESS_TOKEN\" \\\n  -H \"Content-Type: application/json\" \\\n  -d '{}'"
          },
          {
            "lang": "JavaScript",
            "label": "Node.js",
            "source": "import { KangOpenBanking } from \"@kangopenbanking/sdk\";\n\nconst kob = new KangOpenBanking({ apiKey: process.env.KOB_API_KEY });\nconst res = await kob.request(\"POST\", \"/v1/admin/staff/authorizations\", { /* payload */ });\nconsole.log(res);"
          },
          {
            "lang": "Python",
            "label": "Python",
            "source": "from kangopenbanking import KangOpenBanking\n\nkob = KangOpenBanking(api_key=os.environ[\"KOB_API_KEY\"])\nres = kob.request(\"POST\", \"/v1/admin/staff/authorizations\", json={})\nprint(res)"
          },
          {
            "lang": "PHP",
            "label": "PHP",
            "source": "<?php\n$kob = new KangOpenBanking\\KangOpenBanking(getenv('KOB_API_KEY'));\n$res = $kob->request('POST', '/v1/admin/staff/authorizations', []);\nprint_r($res);"
          }
        ]
      }
    },
    "/v1/admin/staff/authorizations/{authorizationId}": {
      "get": {
        "tags": [
          "Operational Controls"
        ],
        "summary": "Get staff authorization",
        "operationId": "getStaffAuthorization",
        "security": [
          {
            "bearerAuth": []
          }
        ],
        "parameters": [
          {
            "name": "authorizationId",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "$ref": "#/components/parameters/RequestId"
          },
          {
            "$ref": "#/components/parameters/Traceparent"
          },
          {
            "$ref": "#/components/parameters/Tracestate"
          },
          {
            "$ref": "#/components/parameters/AcceptLanguage"
          }
        ],
        "responses": {
          "200": {
            "description": "Authorization details",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "id": {
                      "type": "string"
                    },
                    "user_id": {
                      "type": "string"
                    },
                    "role_type": {
                      "type": "string"
                    },
                    "max_override_limit": {
                      "type": "number"
                    },
                    "status": {
                      "type": "string"
                    }
                  }
                },
                "example": {
                  "id": "string",
                  "user_id": "string",
                  "role_type": "string",
                  "max_override_limit": 0,
                  "status": "string"
                }
              }
            },
            "headers": {
              "x-fapi-interaction-id": {
                "$ref": "#/components/headers/XFapiInteractionIdResponse"
              },
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/XRateLimitLimit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/XRateLimitRemaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/XRateLimitReset"
              },
              "Cache-Control": {
                "$ref": "#/components/headers/CacheControl"
              },
              "ETag": {
                "$ref": "#/components/headers/ETag"
              },
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              },
              "traceparent": {
                "$ref": "#/components/headers/Traceparent"
              },
              "Content-Language": {
                "$ref": "#/components/headers/Content-Language"
              }
            }
          },
          "400": {
            "description": "Bad request",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              },
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                },
                "examples": {
                  "error": {
                    "$ref": "#/components/examples/ErrorBadRequest"
                  }
                }
              }
            },
            "headers": {
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/XRateLimitLimit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/XRateLimitRemaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/XRateLimitReset"
              },
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "403": {
            "$ref": "#/components/responses/Forbidden",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "404": {
            "$ref": "#/components/responses/NotFound",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "409": {
            "$ref": "#/components/responses/Conflict",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "429": {
            "$ref": "#/components/responses/TooManyRequests",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "500": {
            "$ref": "#/components/responses/InternalServerError",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          }
        },
        "x-codeSamples": [
          {
            "lang": "cURL",
            "label": "cURL",
            "source": "curl -X GET \"https://api.kangopenbanking.com/v1/admin/staff/authorizations/{authorizationId}\" \\\n  -H \"Authorization: Bearer $KOB_ACCESS_TOKEN\" \\\n  -H \"Content-Type: application/json\""
          },
          {
            "lang": "JavaScript",
            "label": "Node.js",
            "source": "import { KangOpenBanking } from \"@kangopenbanking/sdk\";\n\nconst kob = new KangOpenBanking({ apiKey: process.env.KOB_API_KEY });\nconst res = await kob.request(\"GET\", \"/v1/admin/staff/authorizations/{authorizationId}\");\nconsole.log(res);"
          },
          {
            "lang": "Python",
            "label": "Python",
            "source": "from kangopenbanking import KangOpenBanking\n\nkob = KangOpenBanking(api_key=os.environ[\"KOB_API_KEY\"])\nres = kob.request(\"GET\", \"/v1/admin/staff/authorizations/{authorizationId}\")\nprint(res)"
          },
          {
            "lang": "PHP",
            "label": "PHP",
            "source": "<?php\n$kob = new KangOpenBanking\\KangOpenBanking(getenv('KOB_API_KEY'));\n$res = $kob->request('GET', '/v1/admin/staff/authorizations/{authorizationId}');\nprint_r($res);"
          }
        ]
      },
      "patch": {
        "tags": [
          "Operational Controls"
        ],
        "summary": "Update staff authorization",
        "operationId": "updateStaffAuthorization",
        "security": [
          {
            "bearerAuth": []
          }
        ],
        "parameters": [
          {
            "name": "authorizationId",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "$ref": "#/components/parameters/RequestId"
          },
          {
            "$ref": "#/components/parameters/Traceparent"
          },
          {
            "$ref": "#/components/parameters/Tracestate"
          },
          {
            "$ref": "#/components/parameters/AcceptLanguage"
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "max_override_limit": {
                    "type": "number"
                  },
                  "can_approve_overdraft": {
                    "type": "boolean"
                  },
                  "can_approve_withdrawal_override": {
                    "type": "boolean"
                  },
                  "status": {
                    "type": "string"
                  }
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Authorization updated",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "success": {
                      "type": "boolean",
                      "example": true
                    },
                    "message": {
                      "type": "string"
                    }
                  }
                },
                "example": {
                  "success": true,
                  "message": "string"
                }
              }
            },
            "headers": {
              "x-fapi-interaction-id": {
                "$ref": "#/components/headers/XFapiInteractionIdResponse"
              },
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/XRateLimitLimit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/XRateLimitRemaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/XRateLimitReset"
              },
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              },
              "traceparent": {
                "$ref": "#/components/headers/Traceparent"
              },
              "Content-Language": {
                "$ref": "#/components/headers/Content-Language"
              }
            }
          },
          "400": {
            "description": "Bad request",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              },
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                },
                "examples": {
                  "error": {
                    "$ref": "#/components/examples/ErrorBadRequest"
                  }
                }
              }
            },
            "headers": {
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/XRateLimitLimit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/XRateLimitRemaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/XRateLimitReset"
              },
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "403": {
            "$ref": "#/components/responses/Forbidden",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "404": {
            "$ref": "#/components/responses/NotFound",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "409": {
            "$ref": "#/components/responses/Conflict",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "429": {
            "$ref": "#/components/responses/TooManyRequests",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "500": {
            "$ref": "#/components/responses/InternalServerError",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          }
        },
        "x-codeSamples": [
          {
            "lang": "cURL",
            "label": "cURL",
            "source": "curl -X PATCH \"https://api.kangopenbanking.com/v1/admin/staff/authorizations/{authorizationId}\" \\\n  -H \"Authorization: Bearer $KOB_ACCESS_TOKEN\" \\\n  -H \"Content-Type: application/json\" \\\n  -d '{}'"
          },
          {
            "lang": "JavaScript",
            "label": "Node.js",
            "source": "import { KangOpenBanking } from \"@kangopenbanking/sdk\";\n\nconst kob = new KangOpenBanking({ apiKey: process.env.KOB_API_KEY });\nconst res = await kob.request(\"PATCH\", \"/v1/admin/staff/authorizations/{authorizationId}\", { /* payload */ });\nconsole.log(res);"
          },
          {
            "lang": "Python",
            "label": "Python",
            "source": "from kangopenbanking import KangOpenBanking\n\nkob = KangOpenBanking(api_key=os.environ[\"KOB_API_KEY\"])\nres = kob.request(\"PATCH\", \"/v1/admin/staff/authorizations/{authorizationId}\", json={})\nprint(res)"
          },
          {
            "lang": "PHP",
            "label": "PHP",
            "source": "<?php\n$kob = new KangOpenBanking\\KangOpenBanking(getenv('KOB_API_KEY'));\n$res = $kob->request('PATCH', '/v1/admin/staff/authorizations/{authorizationId}', []);\nprint_r($res);"
          }
        ]
      }
    },
    "/v1/banking/withdrawal-requests": {
      "post": {
        "tags": [
          "Approval Workflows"
        ],
        "summary": "Create withdrawal request",
        "description": "Create a withdrawal request. If the amount exceeds the staff member's policy limit, the request is automatically routed into the approval workflow.",
        "operationId": "createWithdrawalRequest",
        "security": [
          {
            "bearerAuth": []
          }
        ],
        "parameters": [
          {
            "name": "Idempotency-Key",
            "in": "header",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid"
            },
            "description": "Required on all POST/PUT endpoints. Unique key for idempotent request processing (UUID v4 recommended). Keys expire after 24 hours."
          },
          {
            "$ref": "#/components/parameters/RequestId"
          },
          {
            "$ref": "#/components/parameters/Traceparent"
          },
          {
            "$ref": "#/components/parameters/Tracestate"
          },
          {
            "$ref": "#/components/parameters/AcceptLanguage"
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "required": [
                  "institution_id",
                  "account_id",
                  "amount"
                ],
                "properties": {
                  "institution_id": {
                    "type": "string",
                    "format": "uuid"
                  },
                  "branch_id": {
                    "type": "string",
                    "format": "uuid"
                  },
                  "account_id": {
                    "type": "string",
                    "format": "uuid"
                  },
                  "amount": {
                    "type": "string",
                    "example": "2000000",
                    "pattern": "^[0-9]{1,15}$",
                    "description": "Represented as a string integer in the currency's minor unit (XAF has no subunits). Must be consistent with the currency field."
                  },
                  "currency": {
                    "type": "string",
                    "default": "XAF",
                    "enum": [
                      "XAF",
                      "XOF",
                      "USD",
                      "EUR",
                      "GBP",
                      "CNY",
                      "NGN",
                      "GHS",
                      "KES",
                      "ZAR"
                    ],
                    "description": "ISO 4217 currency code. Default is XAF (Central African CFA Franc)."
                  },
                  "channel": {
                    "type": "string",
                    "default": "branch"
                  },
                  "reason": {
                    "type": "string"
                  }
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Request auto-approved and executed",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "id": {
                      "type": "string",
                      "format": "uuid"
                    },
                    "status": {
                      "type": "string",
                      "example": "approved"
                    },
                    "amount": {
                      "type": "string",
                      "example": "500000",
                      "pattern": "^[0-9]{1,15}$",
                      "description": "Represented as a string integer in the currency's minor unit (XAF has no subunits). Must be consistent with the currency field."
                    },
                    "currency": {
                      "type": "string",
                      "example": "XAF",
                      "enum": [
                        "XAF",
                        "XOF",
                        "USD",
                        "EUR",
                        "GBP",
                        "CNY",
                        "NGN",
                        "GHS",
                        "KES",
                        "ZAR"
                      ],
                      "default": "XAF",
                      "description": "ISO 4217 currency code. Default is XAF (Central African CFA Franc)."
                    },
                    "account_id": {
                      "type": "string",
                      "format": "uuid"
                    },
                    "approved_at": {
                      "type": "string",
                      "format": "date-time"
                    },
                    "requires_approval": {
                      "type": "boolean",
                      "example": false
                    }
                  }
                },
                "example": {
                  "id": "00000000-0000-4000-8000-000000000000",
                  "status": "approved",
                  "amount": "500000",
                  "currency": "XAF",
                  "account_id": "00000000-0000-4000-8000-000000000000",
                  "approved_at": "2026-01-01T00:00:00Z",
                  "requires_approval": false
                }
              }
            },
            "headers": {
              "x-fapi-interaction-id": {
                "$ref": "#/components/headers/XFapiInteractionIdResponse"
              },
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/XRateLimitLimit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/XRateLimitRemaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/XRateLimitReset"
              },
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              },
              "traceparent": {
                "$ref": "#/components/headers/Traceparent"
              },
              "Content-Language": {
                "$ref": "#/components/headers/Content-Language"
              }
            }
          },
          "202": {
            "description": "Request requires manager approval",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "requires_approval": {
                      "type": "boolean",
                      "example": true
                    },
                    "withdrawal_request_id": {
                      "type": "string",
                      "format": "uuid"
                    },
                    "approval_status": {
                      "type": "string"
                    },
                    "pending_role": {
                      "type": "string"
                    }
                  }
                },
                "example": {
                  "requires_approval": true,
                  "withdrawal_request_id": "00000000-0000-4000-8000-000000000000",
                  "approval_status": "string",
                  "pending_role": "string"
                }
              }
            },
            "headers": {
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/XRateLimitLimit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/XRateLimitRemaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/XRateLimitReset"
              },
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              },
              "traceparent": {
                "$ref": "#/components/headers/Traceparent"
              },
              "Content-Language": {
                "$ref": "#/components/headers/Content-Language"
              }
            }
          },
          "400": {
            "description": "Bad request",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              },
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                },
                "examples": {
                  "error": {
                    "$ref": "#/components/examples/ErrorBadRequest"
                  }
                }
              }
            },
            "headers": {
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/XRateLimitLimit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/XRateLimitRemaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/XRateLimitReset"
              },
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "403": {
            "$ref": "#/components/responses/Forbidden",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "404": {
            "$ref": "#/components/responses/NotFound",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "409": {
            "$ref": "#/components/responses/Conflict",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "429": {
            "$ref": "#/components/responses/TooManyRequests",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "500": {
            "$ref": "#/components/responses/InternalServerError",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          }
        },
        "x-codeSamples": [
          {
            "lang": "cURL",
            "label": "cURL",
            "source": "curl -X POST \"https://api.kangopenbanking.com/v1/banking/withdrawal-requests\" \\\n  -H \"Authorization: Bearer $KOB_ACCESS_TOKEN\" \\\n  -H \"Content-Type: application/json\" \\\n  -d '{}'"
          },
          {
            "lang": "JavaScript",
            "label": "Node.js",
            "source": "import { KangOpenBanking } from \"@kangopenbanking/sdk\";\n\nconst kob = new KangOpenBanking({ apiKey: process.env.KOB_API_KEY });\nconst res = await kob.request(\"POST\", \"/v1/banking/withdrawal-requests\", { /* payload */ });\nconsole.log(res);"
          },
          {
            "lang": "Python",
            "label": "Python",
            "source": "from kangopenbanking import KangOpenBanking\n\nkob = KangOpenBanking(api_key=os.environ[\"KOB_API_KEY\"])\nres = kob.request(\"POST\", \"/v1/banking/withdrawal-requests\", json={})\nprint(res)"
          },
          {
            "lang": "PHP",
            "label": "PHP",
            "source": "<?php\n$kob = new KangOpenBanking\\KangOpenBanking(getenv('KOB_API_KEY'));\n$res = $kob->request('POST', '/v1/banking/withdrawal-requests', []);\nprint_r($res);"
          }
        ]
      },
      "get": {
        "tags": [
          "Approval Workflows"
        ],
        "summary": "List withdrawal requests",
        "operationId": "listWithdrawalRequests",
        "security": [
          {
            "bearerAuth": []
          }
        ],
        "parameters": [
          {
            "name": "institution_id",
            "in": "query",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          },
          {
            "name": "status",
            "in": "query",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "limit",
            "in": "query",
            "schema": {
              "type": "integer",
              "default": 25,
              "maximum": 100
            },
            "description": "Items per page"
          },
          {
            "name": "offset",
            "in": "query",
            "schema": {
              "type": "integer",
              "default": 0
            },
            "description": "Items to skip"
          },
          {
            "name": "sort_by",
            "in": "query",
            "schema": {
              "type": "string",
              "default": "created_at"
            },
            "description": "Sort field"
          },
          {
            "name": "sort_order",
            "in": "query",
            "schema": {
              "type": "string",
              "enum": [
                "asc",
                "desc"
              ],
              "default": "desc"
            },
            "description": "Sort direction"
          },
          {
            "$ref": "#/components/parameters/StartingAfter"
          },
          {
            "$ref": "#/components/parameters/EndingBefore"
          },
          {
            "$ref": "#/components/parameters/RequestId"
          },
          {
            "$ref": "#/components/parameters/Traceparent"
          },
          {
            "$ref": "#/components/parameters/Tracestate"
          },
          {
            "$ref": "#/components/parameters/AcceptLanguage"
          }
        ],
        "responses": {
          "200": {
            "description": "Withdrawal requests",
            "content": {
              "application/json": {
                "schema": {
                  "allOf": [
                    {
                      "$ref": "#/components/schemas/PaginatedResponse"
                    },
                    {
                      "type": "object",
                      "properties": {
                        "data": {
                          "type": "array",
                          "items": {}
                        }
                      }
                    }
                  ]
                },
                "example": {
                  "data": [
                    {}
                  ],
                  "pagination": {
                    "page": 1,
                    "limit": 20,
                    "total": 150,
                    "has_next": true,
                    "next_cursor": "eyJpZCI6IjEyMyJ9"
                  },
                  "meta": {
                    "request_id": "550e8400-e29b-41d4-a716-446655440000",
                    "timestamp": "2025-03-27T12:00:00Z",
                    "api_version": "4.3.0"
                  }
                }
              }
            },
            "headers": {
              "x-fapi-interaction-id": {
                "$ref": "#/components/headers/XFapiInteractionIdResponse"
              },
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/XRateLimitLimit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/XRateLimitRemaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/XRateLimitReset"
              },
              "Cache-Control": {
                "$ref": "#/components/headers/CacheControl"
              },
              "ETag": {
                "$ref": "#/components/headers/ETag"
              },
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              },
              "traceparent": {
                "$ref": "#/components/headers/Traceparent"
              },
              "Content-Language": {
                "$ref": "#/components/headers/Content-Language"
              }
            }
          },
          "400": {
            "description": "Bad request",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              },
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                },
                "examples": {
                  "error": {
                    "$ref": "#/components/examples/ErrorBadRequest"
                  }
                }
              }
            },
            "headers": {
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/XRateLimitLimit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/XRateLimitRemaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/XRateLimitReset"
              },
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "403": {
            "$ref": "#/components/responses/Forbidden",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "404": {
            "$ref": "#/components/responses/NotFound",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "409": {
            "$ref": "#/components/responses/Conflict",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "429": {
            "$ref": "#/components/responses/TooManyRequests",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "500": {
            "$ref": "#/components/responses/InternalServerError",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          }
        },
        "x-codeSamples": [
          {
            "lang": "cURL",
            "label": "cURL",
            "source": "curl -X GET \"https://api.kangopenbanking.com/v1/banking/withdrawal-requests\" \\\n  -H \"Authorization: Bearer $KOB_ACCESS_TOKEN\" \\\n  -H \"Content-Type: application/json\""
          },
          {
            "lang": "JavaScript",
            "label": "Node.js",
            "source": "import { KangOpenBanking } from \"@kangopenbanking/sdk\";\n\nconst kob = new KangOpenBanking({ apiKey: process.env.KOB_API_KEY });\nconst res = await kob.request(\"GET\", \"/v1/banking/withdrawal-requests\");\nconsole.log(res);"
          },
          {
            "lang": "Python",
            "label": "Python",
            "source": "from kangopenbanking import KangOpenBanking\n\nkob = KangOpenBanking(api_key=os.environ[\"KOB_API_KEY\"])\nres = kob.request(\"GET\", \"/v1/banking/withdrawal-requests\")\nprint(res)"
          },
          {
            "lang": "PHP",
            "label": "PHP",
            "source": "<?php\n$kob = new KangOpenBanking\\KangOpenBanking(getenv('KOB_API_KEY'));\n$res = $kob->request('GET', '/v1/banking/withdrawal-requests');\nprint_r($res);"
          }
        ]
      }
    },
    "/v1/banking/withdrawal-requests/{requestId}": {
      "get": {
        "tags": [
          "Approval Workflows"
        ],
        "summary": "Get withdrawal request",
        "operationId": "getWithdrawalRequest",
        "security": [
          {
            "bearerAuth": []
          }
        ],
        "parameters": [
          {
            "name": "requestId",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "$ref": "#/components/parameters/RequestId"
          },
          {
            "$ref": "#/components/parameters/Traceparent"
          },
          {
            "$ref": "#/components/parameters/Tracestate"
          },
          {
            "$ref": "#/components/parameters/AcceptLanguage"
          }
        ],
        "responses": {
          "200": {
            "description": "Withdrawal request details",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "id": {
                      "type": "string"
                    },
                    "account_id": {
                      "type": "string"
                    },
                    "amount": {
                      "type": "string",
                      "pattern": "^[0-9]{1,15}$",
                      "description": "Represented as a string integer in the currency's minor unit (XAF has no subunits). Must be consistent with the currency field."
                    },
                    "currency": {
                      "type": "string",
                      "enum": [
                        "XAF",
                        "XOF",
                        "USD",
                        "EUR",
                        "GBP",
                        "CNY",
                        "NGN",
                        "GHS",
                        "KES",
                        "ZAR"
                      ],
                      "default": "XAF",
                      "description": "ISO 4217 currency code. Default is XAF (Central African CFA Franc)."
                    },
                    "status": {
                      "type": "string"
                    },
                    "approval_id": {
                      "type": "string"
                    },
                    "created_at": {
                      "type": "string",
                      "format": "date-time"
                    }
                  }
                },
                "example": {
                  "id": "string",
                  "account_id": "string",
                  "amount": "1000",
                  "currency": "XAF",
                  "status": "string",
                  "approval_id": "string",
                  "created_at": "2026-01-01T00:00:00Z"
                }
              }
            },
            "headers": {
              "x-fapi-interaction-id": {
                "$ref": "#/components/headers/XFapiInteractionIdResponse"
              },
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/XRateLimitLimit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/XRateLimitRemaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/XRateLimitReset"
              },
              "Cache-Control": {
                "$ref": "#/components/headers/CacheControl"
              },
              "ETag": {
                "$ref": "#/components/headers/ETag"
              },
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              },
              "traceparent": {
                "$ref": "#/components/headers/Traceparent"
              },
              "Content-Language": {
                "$ref": "#/components/headers/Content-Language"
              }
            }
          },
          "400": {
            "description": "Bad request",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              },
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                },
                "examples": {
                  "error": {
                    "$ref": "#/components/examples/ErrorBadRequest"
                  }
                }
              }
            },
            "headers": {
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/XRateLimitLimit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/XRateLimitRemaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/XRateLimitReset"
              },
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "403": {
            "$ref": "#/components/responses/Forbidden",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "404": {
            "$ref": "#/components/responses/NotFound",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "409": {
            "$ref": "#/components/responses/Conflict",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "429": {
            "$ref": "#/components/responses/TooManyRequests",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "500": {
            "$ref": "#/components/responses/InternalServerError",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          }
        },
        "x-codeSamples": [
          {
            "lang": "cURL",
            "label": "cURL",
            "source": "curl -X GET \"https://api.kangopenbanking.com/v1/banking/withdrawal-requests/{requestId}\" \\\n  -H \"Authorization: Bearer $KOB_ACCESS_TOKEN\" \\\n  -H \"Content-Type: application/json\""
          },
          {
            "lang": "JavaScript",
            "label": "Node.js",
            "source": "import { KangOpenBanking } from \"@kangopenbanking/sdk\";\n\nconst kob = new KangOpenBanking({ apiKey: process.env.KOB_API_KEY });\nconst res = await kob.request(\"GET\", \"/v1/banking/withdrawal-requests/{requestId}\");\nconsole.log(res);"
          },
          {
            "lang": "Python",
            "label": "Python",
            "source": "from kangopenbanking import KangOpenBanking\n\nkob = KangOpenBanking(api_key=os.environ[\"KOB_API_KEY\"])\nres = kob.request(\"GET\", \"/v1/banking/withdrawal-requests/{requestId}\")\nprint(res)"
          },
          {
            "lang": "PHP",
            "label": "PHP",
            "source": "<?php\n$kob = new KangOpenBanking\\KangOpenBanking(getenv('KOB_API_KEY'));\n$res = $kob->request('GET', '/v1/banking/withdrawal-requests/{requestId}');\nprint_r($res);"
          }
        ]
      }
    },
    "/v1/banking/withdrawal-requests/{requestId}/submit": {
      "post": {
        "tags": [
          "Approval Workflows"
        ],
        "summary": "Submit draft withdrawal request",
        "operationId": "submitWithdrawalRequest",
        "security": [
          {
            "bearerAuth": []
          }
        ],
        "parameters": [
          {
            "name": "requestId",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "$ref": "#/components/parameters/IdempotencyKey"
          },
          {
            "$ref": "#/components/parameters/RequestId"
          },
          {
            "$ref": "#/components/parameters/Traceparent"
          },
          {
            "$ref": "#/components/parameters/Tracestate"
          },
          {
            "$ref": "#/components/parameters/AcceptLanguage"
          }
        ],
        "responses": {
          "200": {
            "description": "Request submitted",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "success": {
                      "type": "boolean",
                      "example": true
                    },
                    "message": {
                      "type": "string"
                    }
                  }
                },
                "example": {
                  "success": true,
                  "message": "string"
                }
              }
            },
            "headers": {
              "x-fapi-interaction-id": {
                "$ref": "#/components/headers/XFapiInteractionIdResponse"
              },
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/XRateLimitLimit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/XRateLimitRemaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/XRateLimitReset"
              },
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              },
              "traceparent": {
                "$ref": "#/components/headers/Traceparent"
              },
              "Content-Language": {
                "$ref": "#/components/headers/Content-Language"
              }
            }
          },
          "400": {
            "description": "Bad request",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              },
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                },
                "examples": {
                  "error": {
                    "$ref": "#/components/examples/ErrorBadRequest"
                  }
                }
              }
            },
            "headers": {
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/XRateLimitLimit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/XRateLimitRemaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/XRateLimitReset"
              },
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "403": {
            "$ref": "#/components/responses/Forbidden",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "404": {
            "$ref": "#/components/responses/NotFound",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "409": {
            "$ref": "#/components/responses/Conflict",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "429": {
            "$ref": "#/components/responses/TooManyRequests",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "500": {
            "$ref": "#/components/responses/InternalServerError",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          }
        },
        "x-codeSamples": [
          {
            "lang": "cURL",
            "label": "cURL",
            "source": "curl -X POST \"https://api.kangopenbanking.com/v1/banking/withdrawal-requests/{requestId}/submit\" \\\n  -H \"Authorization: Bearer $KOB_ACCESS_TOKEN\" \\\n  -H \"Content-Type: application/json\""
          },
          {
            "lang": "JavaScript",
            "label": "Node.js",
            "source": "import { KangOpenBanking } from \"@kangopenbanking/sdk\";\n\nconst kob = new KangOpenBanking({ apiKey: process.env.KOB_API_KEY });\nconst res = await kob.request(\"POST\", \"/v1/banking/withdrawal-requests/{requestId}/submit\");\nconsole.log(res);"
          },
          {
            "lang": "Python",
            "label": "Python",
            "source": "from kangopenbanking import KangOpenBanking\n\nkob = KangOpenBanking(api_key=os.environ[\"KOB_API_KEY\"])\nres = kob.request(\"POST\", \"/v1/banking/withdrawal-requests/{requestId}/submit\")\nprint(res)"
          },
          {
            "lang": "PHP",
            "label": "PHP",
            "source": "<?php\n$kob = new KangOpenBanking\\KangOpenBanking(getenv('KOB_API_KEY'));\n$res = $kob->request('POST', '/v1/banking/withdrawal-requests/{requestId}/submit');\nprint_r($res);"
          }
        ]
      }
    },
    "/v1/banking/withdrawal-requests/{requestId}/cancel": {
      "post": {
        "tags": [
          "Approval Workflows"
        ],
        "summary": "Cancel withdrawal request",
        "operationId": "cancelWithdrawalRequest",
        "security": [
          {
            "bearerAuth": []
          }
        ],
        "parameters": [
          {
            "name": "requestId",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "$ref": "#/components/parameters/IdempotencyKey"
          },
          {
            "$ref": "#/components/parameters/RequestId"
          },
          {
            "$ref": "#/components/parameters/Traceparent"
          },
          {
            "$ref": "#/components/parameters/Tracestate"
          },
          {
            "$ref": "#/components/parameters/AcceptLanguage"
          }
        ],
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "reason": {
                    "type": "string"
                  }
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Request cancelled",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "success": {
                      "type": "boolean",
                      "example": true
                    },
                    "message": {
                      "type": "string"
                    }
                  }
                },
                "example": {
                  "success": true,
                  "message": "string"
                }
              }
            },
            "headers": {
              "x-fapi-interaction-id": {
                "$ref": "#/components/headers/XFapiInteractionIdResponse"
              },
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/XRateLimitLimit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/XRateLimitRemaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/XRateLimitReset"
              },
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              },
              "traceparent": {
                "$ref": "#/components/headers/Traceparent"
              },
              "Content-Language": {
                "$ref": "#/components/headers/Content-Language"
              }
            }
          },
          "400": {
            "description": "Bad request",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              },
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                },
                "examples": {
                  "error": {
                    "$ref": "#/components/examples/ErrorBadRequest"
                  }
                }
              }
            },
            "headers": {
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/XRateLimitLimit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/XRateLimitRemaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/XRateLimitReset"
              },
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "403": {
            "$ref": "#/components/responses/Forbidden",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "404": {
            "$ref": "#/components/responses/NotFound",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "409": {
            "$ref": "#/components/responses/Conflict",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "429": {
            "$ref": "#/components/responses/TooManyRequests",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "500": {
            "$ref": "#/components/responses/InternalServerError",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          }
        },
        "x-codeSamples": [
          {
            "lang": "cURL",
            "label": "cURL",
            "source": "curl -X POST \"https://api.kangopenbanking.com/v1/banking/withdrawal-requests/{requestId}/cancel\" \\\n  -H \"Authorization: Bearer $KOB_ACCESS_TOKEN\" \\\n  -H \"Content-Type: application/json\" \\\n  -d '{}'"
          },
          {
            "lang": "JavaScript",
            "label": "Node.js",
            "source": "import { KangOpenBanking } from \"@kangopenbanking/sdk\";\n\nconst kob = new KangOpenBanking({ apiKey: process.env.KOB_API_KEY });\nconst res = await kob.request(\"POST\", \"/v1/banking/withdrawal-requests/{requestId}/cancel\", { /* payload */ });\nconsole.log(res);"
          },
          {
            "lang": "Python",
            "label": "Python",
            "source": "from kangopenbanking import KangOpenBanking\n\nkob = KangOpenBanking(api_key=os.environ[\"KOB_API_KEY\"])\nres = kob.request(\"POST\", \"/v1/banking/withdrawal-requests/{requestId}/cancel\", json={})\nprint(res)"
          },
          {
            "lang": "PHP",
            "label": "PHP",
            "source": "<?php\n$kob = new KangOpenBanking\\KangOpenBanking(getenv('KOB_API_KEY'));\n$res = $kob->request('POST', '/v1/banking/withdrawal-requests/{requestId}/cancel', []);\nprint_r($res);"
          }
        ]
      }
    },
    "/v1/banking/approvals": {
      "get": {
        "tags": [
          "Approval Workflows"
        ],
        "summary": "List approval requests",
        "operationId": "listApprovals",
        "security": [
          {
            "bearerAuth": []
          }
        ],
        "parameters": [
          {
            "name": "institution_id",
            "in": "query",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          },
          {
            "name": "status",
            "in": "query",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "limit",
            "in": "query",
            "schema": {
              "type": "integer",
              "default": 25,
              "maximum": 100
            },
            "description": "Items per page"
          },
          {
            "name": "offset",
            "in": "query",
            "schema": {
              "type": "integer",
              "default": 0
            },
            "description": "Items to skip"
          },
          {
            "name": "sort_by",
            "in": "query",
            "schema": {
              "type": "string",
              "default": "created_at"
            },
            "description": "Sort field"
          },
          {
            "name": "sort_order",
            "in": "query",
            "schema": {
              "type": "string",
              "enum": [
                "asc",
                "desc"
              ],
              "default": "desc"
            },
            "description": "Sort direction"
          },
          {
            "$ref": "#/components/parameters/StartingAfter"
          },
          {
            "$ref": "#/components/parameters/EndingBefore"
          },
          {
            "$ref": "#/components/parameters/RequestId"
          },
          {
            "$ref": "#/components/parameters/Traceparent"
          },
          {
            "$ref": "#/components/parameters/Tracestate"
          },
          {
            "$ref": "#/components/parameters/AcceptLanguage"
          }
        ],
        "responses": {
          "200": {
            "description": "Approval requests with action history",
            "content": {
              "application/json": {
                "schema": {
                  "allOf": [
                    {
                      "$ref": "#/components/schemas/PaginatedResponse"
                    },
                    {
                      "type": "object",
                      "properties": {
                        "data": {
                          "type": "array",
                          "items": {}
                        }
                      }
                    }
                  ]
                },
                "example": {
                  "data": [
                    {}
                  ],
                  "pagination": {
                    "page": 1,
                    "limit": 20,
                    "total": 150,
                    "has_next": true,
                    "next_cursor": "eyJpZCI6IjEyMyJ9"
                  },
                  "meta": {
                    "request_id": "550e8400-e29b-41d4-a716-446655440000",
                    "timestamp": "2025-03-27T12:00:00Z",
                    "api_version": "4.3.0"
                  }
                }
              }
            },
            "headers": {
              "x-fapi-interaction-id": {
                "$ref": "#/components/headers/XFapiInteractionIdResponse"
              },
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/XRateLimitLimit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/XRateLimitRemaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/XRateLimitReset"
              },
              "Cache-Control": {
                "$ref": "#/components/headers/CacheControl"
              },
              "ETag": {
                "$ref": "#/components/headers/ETag"
              },
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              },
              "traceparent": {
                "$ref": "#/components/headers/Traceparent"
              },
              "Content-Language": {
                "$ref": "#/components/headers/Content-Language"
              }
            }
          },
          "400": {
            "description": "Bad request",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              },
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                },
                "examples": {
                  "error": {
                    "$ref": "#/components/examples/ErrorBadRequest"
                  }
                }
              }
            },
            "headers": {
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/XRateLimitLimit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/XRateLimitRemaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/XRateLimitReset"
              },
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "403": {
            "$ref": "#/components/responses/Forbidden",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "404": {
            "$ref": "#/components/responses/NotFound",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "409": {
            "$ref": "#/components/responses/Conflict",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "429": {
            "$ref": "#/components/responses/TooManyRequests",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "500": {
            "$ref": "#/components/responses/InternalServerError",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          }
        },
        "x-codeSamples": [
          {
            "lang": "cURL",
            "label": "cURL",
            "source": "curl -X GET \"https://api.kangopenbanking.com/v1/banking/approvals\" \\\n  -H \"Authorization: Bearer $KOB_ACCESS_TOKEN\" \\\n  -H \"Content-Type: application/json\""
          },
          {
            "lang": "JavaScript",
            "label": "Node.js",
            "source": "import { KangOpenBanking } from \"@kangopenbanking/sdk\";\n\nconst kob = new KangOpenBanking({ apiKey: process.env.KOB_API_KEY });\nconst res = await kob.request(\"GET\", \"/v1/banking/approvals\");\nconsole.log(res);"
          },
          {
            "lang": "Python",
            "label": "Python",
            "source": "from kangopenbanking import KangOpenBanking\n\nkob = KangOpenBanking(api_key=os.environ[\"KOB_API_KEY\"])\nres = kob.request(\"GET\", \"/v1/banking/approvals\")\nprint(res)"
          },
          {
            "lang": "PHP",
            "label": "PHP",
            "source": "<?php\n$kob = new KangOpenBanking\\KangOpenBanking(getenv('KOB_API_KEY'));\n$res = $kob->request('GET', '/v1/banking/approvals');\nprint_r($res);"
          }
        ]
      }
    },
    "/v1/banking/approvals/{approvalId}": {
      "get": {
        "tags": [
          "Approval Workflows"
        ],
        "summary": "Get approval request",
        "operationId": "getApproval",
        "security": [
          {
            "bearerAuth": []
          }
        ],
        "parameters": [
          {
            "name": "approvalId",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "$ref": "#/components/parameters/RequestId"
          },
          {
            "$ref": "#/components/parameters/Traceparent"
          },
          {
            "$ref": "#/components/parameters/Tracestate"
          },
          {
            "$ref": "#/components/parameters/AcceptLanguage"
          }
        ],
        "responses": {
          "200": {
            "description": "Approval with full action audit trail",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "id": {
                      "type": "string"
                    },
                    "entity_type": {
                      "type": "string"
                    },
                    "entity_id": {
                      "type": "string"
                    },
                    "status": {
                      "type": "string"
                    },
                    "actions": {
                      "type": "array",
                      "items": {
                        "type": "object",
                        "properties": {
                          "action": {
                            "type": "string"
                          },
                          "acted_by": {
                            "type": "string"
                          },
                          "comments": {
                            "type": "string"
                          },
                          "created_at": {
                            "type": "string",
                            "format": "date-time"
                          }
                        }
                      }
                    }
                  }
                },
                "example": {
                  "id": "string",
                  "entity_type": "string",
                  "entity_id": "string",
                  "status": "string",
                  "actions": [
                    {
                      "action": "string",
                      "acted_by": "string",
                      "comments": "string",
                      "created_at": "2026-01-01T00:00:00Z"
                    }
                  ]
                }
              }
            },
            "headers": {
              "x-fapi-interaction-id": {
                "$ref": "#/components/headers/XFapiInteractionIdResponse"
              },
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/XRateLimitLimit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/XRateLimitRemaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/XRateLimitReset"
              },
              "Cache-Control": {
                "$ref": "#/components/headers/CacheControl"
              },
              "ETag": {
                "$ref": "#/components/headers/ETag"
              },
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              },
              "traceparent": {
                "$ref": "#/components/headers/Traceparent"
              },
              "Content-Language": {
                "$ref": "#/components/headers/Content-Language"
              }
            }
          },
          "400": {
            "description": "Bad request",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              },
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                },
                "examples": {
                  "error": {
                    "$ref": "#/components/examples/ErrorBadRequest"
                  }
                }
              }
            },
            "headers": {
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/XRateLimitLimit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/XRateLimitRemaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/XRateLimitReset"
              },
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "403": {
            "$ref": "#/components/responses/Forbidden",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "404": {
            "$ref": "#/components/responses/NotFound",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "409": {
            "$ref": "#/components/responses/Conflict",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "429": {
            "$ref": "#/components/responses/TooManyRequests",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "500": {
            "$ref": "#/components/responses/InternalServerError",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          }
        },
        "x-codeSamples": [
          {
            "lang": "cURL",
            "label": "cURL",
            "source": "curl -X GET \"https://api.kangopenbanking.com/v1/banking/approvals/{approvalId}\" \\\n  -H \"Authorization: Bearer $KOB_ACCESS_TOKEN\" \\\n  -H \"Content-Type: application/json\""
          },
          {
            "lang": "JavaScript",
            "label": "Node.js",
            "source": "import { KangOpenBanking } from \"@kangopenbanking/sdk\";\n\nconst kob = new KangOpenBanking({ apiKey: process.env.KOB_API_KEY });\nconst res = await kob.request(\"GET\", \"/v1/banking/approvals/{approvalId}\");\nconsole.log(res);"
          },
          {
            "lang": "Python",
            "label": "Python",
            "source": "from kangopenbanking import KangOpenBanking\n\nkob = KangOpenBanking(api_key=os.environ[\"KOB_API_KEY\"])\nres = kob.request(\"GET\", \"/v1/banking/approvals/{approvalId}\")\nprint(res)"
          },
          {
            "lang": "PHP",
            "label": "PHP",
            "source": "<?php\n$kob = new KangOpenBanking\\KangOpenBanking(getenv('KOB_API_KEY'));\n$res = $kob->request('GET', '/v1/banking/approvals/{approvalId}');\nprint_r($res);"
          }
        ]
      }
    },
    "/v1/banking/approvals/{approvalId}/approve": {
      "post": {
        "tags": [
          "Approval Workflows"
        ],
        "summary": "Approve request",
        "description": "Approve a pending request. The approver must have the required operational role. If the entity is a withdrawal, it is automatically executed after approval.",
        "operationId": "approveRequest",
        "security": [
          {
            "bearerAuth": []
          }
        ],
        "parameters": [
          {
            "name": "approvalId",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "Idempotency-Key",
            "in": "header",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid"
            },
            "description": "Required on all POST/PUT endpoints. Unique key for idempotent request processing (UUID v4 recommended). Keys expire after 24 hours."
          },
          {
            "$ref": "#/components/parameters/RequestId"
          },
          {
            "$ref": "#/components/parameters/Traceparent"
          },
          {
            "$ref": "#/components/parameters/Tracestate"
          },
          {
            "$ref": "#/components/parameters/AcceptLanguage"
          }
        ],
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "comments": {
                    "type": "string"
                  }
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Approved (and executed if withdrawal)",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "success": {
                      "type": "boolean",
                      "example": true
                    },
                    "message": {
                      "type": "string"
                    }
                  }
                },
                "example": {
                  "success": true,
                  "message": "string"
                }
              }
            },
            "headers": {
              "x-fapi-interaction-id": {
                "$ref": "#/components/headers/XFapiInteractionIdResponse"
              },
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/XRateLimitLimit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/XRateLimitRemaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/XRateLimitReset"
              },
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              },
              "traceparent": {
                "$ref": "#/components/headers/Traceparent"
              },
              "Content-Language": {
                "$ref": "#/components/headers/Content-Language"
              }
            }
          },
          "400": {
            "description": "Bad request",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              },
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                },
                "examples": {
                  "error": {
                    "$ref": "#/components/examples/ErrorBadRequest"
                  }
                }
              }
            },
            "headers": {
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/XRateLimitLimit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/XRateLimitRemaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/XRateLimitReset"
              },
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "403": {
            "$ref": "#/components/responses/Forbidden",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "404": {
            "$ref": "#/components/responses/NotFound",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "409": {
            "$ref": "#/components/responses/Conflict",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "429": {
            "$ref": "#/components/responses/TooManyRequests",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "500": {
            "$ref": "#/components/responses/InternalServerError",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          }
        },
        "x-codeSamples": [
          {
            "lang": "cURL",
            "label": "cURL",
            "source": "curl -X POST \"https://api.kangopenbanking.com/v1/banking/approvals/{approvalId}/approve\" \\\n  -H \"Authorization: Bearer $KOB_ACCESS_TOKEN\" \\\n  -H \"Content-Type: application/json\" \\\n  -d '{}'"
          },
          {
            "lang": "JavaScript",
            "label": "Node.js",
            "source": "import { KangOpenBanking } from \"@kangopenbanking/sdk\";\n\nconst kob = new KangOpenBanking({ apiKey: process.env.KOB_API_KEY });\nconst res = await kob.request(\"POST\", \"/v1/banking/approvals/{approvalId}/approve\", { /* payload */ });\nconsole.log(res);"
          },
          {
            "lang": "Python",
            "label": "Python",
            "source": "from kangopenbanking import KangOpenBanking\n\nkob = KangOpenBanking(api_key=os.environ[\"KOB_API_KEY\"])\nres = kob.request(\"POST\", \"/v1/banking/approvals/{approvalId}/approve\", json={})\nprint(res)"
          },
          {
            "lang": "PHP",
            "label": "PHP",
            "source": "<?php\n$kob = new KangOpenBanking\\KangOpenBanking(getenv('KOB_API_KEY'));\n$res = $kob->request('POST', '/v1/banking/approvals/{approvalId}/approve', []);\nprint_r($res);"
          }
        ]
      }
    },
    "/v1/banking/approvals/{approvalId}/reject": {
      "post": {
        "tags": [
          "Approval Workflows"
        ],
        "summary": "Reject request",
        "operationId": "rejectRequest",
        "security": [
          {
            "bearerAuth": []
          }
        ],
        "parameters": [
          {
            "name": "approvalId",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "$ref": "#/components/parameters/RequestId"
          },
          {
            "$ref": "#/components/parameters/Traceparent"
          },
          {
            "$ref": "#/components/parameters/Tracestate"
          },
          {
            "$ref": "#/components/parameters/AcceptLanguage"
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "required": [
                  "reason"
                ],
                "properties": {
                  "reason": {
                    "type": "string"
                  },
                  "comments": {
                    "type": "string"
                  }
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Rejected",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "success": {
                      "type": "boolean",
                      "example": true
                    },
                    "message": {
                      "type": "string"
                    }
                  }
                },
                "example": {
                  "success": true,
                  "message": "string"
                }
              }
            },
            "headers": {
              "x-fapi-interaction-id": {
                "$ref": "#/components/headers/XFapiInteractionIdResponse"
              },
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/XRateLimitLimit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/XRateLimitRemaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/XRateLimitReset"
              },
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              },
              "traceparent": {
                "$ref": "#/components/headers/Traceparent"
              },
              "Content-Language": {
                "$ref": "#/components/headers/Content-Language"
              }
            }
          },
          "400": {
            "description": "Bad request",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              },
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                },
                "examples": {
                  "error": {
                    "$ref": "#/components/examples/ErrorBadRequest"
                  }
                }
              }
            },
            "headers": {
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/XRateLimitLimit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/XRateLimitRemaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/XRateLimitReset"
              },
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "403": {
            "$ref": "#/components/responses/Forbidden",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "404": {
            "$ref": "#/components/responses/NotFound",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "409": {
            "$ref": "#/components/responses/Conflict",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "429": {
            "$ref": "#/components/responses/TooManyRequests",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "500": {
            "$ref": "#/components/responses/InternalServerError",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          }
        },
        "x-codeSamples": [
          {
            "lang": "cURL",
            "label": "cURL",
            "source": "curl -X POST \"https://api.kangopenbanking.com/v1/banking/approvals/{approvalId}/reject\" \\\n  -H \"Authorization: Bearer $KOB_ACCESS_TOKEN\" \\\n  -H \"Content-Type: application/json\" \\\n  -d '{}'"
          },
          {
            "lang": "JavaScript",
            "label": "Node.js",
            "source": "import { KangOpenBanking } from \"@kangopenbanking/sdk\";\n\nconst kob = new KangOpenBanking({ apiKey: process.env.KOB_API_KEY });\nconst res = await kob.request(\"POST\", \"/v1/banking/approvals/{approvalId}/reject\", { /* payload */ });\nconsole.log(res);"
          },
          {
            "lang": "Python",
            "label": "Python",
            "source": "from kangopenbanking import KangOpenBanking\n\nkob = KangOpenBanking(api_key=os.environ[\"KOB_API_KEY\"])\nres = kob.request(\"POST\", \"/v1/banking/approvals/{approvalId}/reject\", json={})\nprint(res)"
          },
          {
            "lang": "PHP",
            "label": "PHP",
            "source": "<?php\n$kob = new KangOpenBanking\\KangOpenBanking(getenv('KOB_API_KEY'));\n$res = $kob->request('POST', '/v1/banking/approvals/{approvalId}/reject', []);\nprint_r($res);"
          }
        ]
      }
    },
    "/v1/banking/approvals/{approvalId}/escalate": {
      "post": {
        "tags": [
          "Approval Workflows"
        ],
        "summary": "Escalate to higher authority",
        "operationId": "escalateRequest",
        "security": [
          {
            "bearerAuth": []
          }
        ],
        "parameters": [
          {
            "name": "approvalId",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "$ref": "#/components/parameters/RequestId"
          },
          {
            "$ref": "#/components/parameters/Traceparent"
          },
          {
            "$ref": "#/components/parameters/Tracestate"
          },
          {
            "$ref": "#/components/parameters/AcceptLanguage"
          }
        ],
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "target_role": {
                    "type": "string",
                    "enum": [
                      "branch_manager",
                      "general_manager"
                    ]
                  },
                  "comments": {
                    "type": "string"
                  }
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Escalated",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "success": {
                      "type": "boolean",
                      "example": true
                    },
                    "message": {
                      "type": "string"
                    }
                  }
                },
                "example": {
                  "success": true,
                  "message": "string"
                }
              }
            },
            "headers": {
              "x-fapi-interaction-id": {
                "$ref": "#/components/headers/XFapiInteractionIdResponse"
              },
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/XRateLimitLimit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/XRateLimitRemaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/XRateLimitReset"
              },
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              },
              "traceparent": {
                "$ref": "#/components/headers/Traceparent"
              },
              "Content-Language": {
                "$ref": "#/components/headers/Content-Language"
              }
            }
          },
          "400": {
            "description": "Bad request",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              },
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                },
                "examples": {
                  "error": {
                    "$ref": "#/components/examples/ErrorBadRequest"
                  }
                }
              }
            },
            "headers": {
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/XRateLimitLimit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/XRateLimitRemaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/XRateLimitReset"
              },
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "403": {
            "$ref": "#/components/responses/Forbidden",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "404": {
            "$ref": "#/components/responses/NotFound",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "409": {
            "$ref": "#/components/responses/Conflict",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "429": {
            "$ref": "#/components/responses/TooManyRequests",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "500": {
            "$ref": "#/components/responses/InternalServerError",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          }
        },
        "x-codeSamples": [
          {
            "lang": "cURL",
            "label": "cURL",
            "source": "curl -X POST \"https://api.kangopenbanking.com/v1/banking/approvals/{approvalId}/escalate\" \\\n  -H \"Authorization: Bearer $KOB_ACCESS_TOKEN\" \\\n  -H \"Content-Type: application/json\" \\\n  -d '{}'"
          },
          {
            "lang": "JavaScript",
            "label": "Node.js",
            "source": "import { KangOpenBanking } from \"@kangopenbanking/sdk\";\n\nconst kob = new KangOpenBanking({ apiKey: process.env.KOB_API_KEY });\nconst res = await kob.request(\"POST\", \"/v1/banking/approvals/{approvalId}/escalate\", { /* payload */ });\nconsole.log(res);"
          },
          {
            "lang": "Python",
            "label": "Python",
            "source": "from kangopenbanking import KangOpenBanking\n\nkob = KangOpenBanking(api_key=os.environ[\"KOB_API_KEY\"])\nres = kob.request(\"POST\", \"/v1/banking/approvals/{approvalId}/escalate\", json={})\nprint(res)"
          },
          {
            "lang": "PHP",
            "label": "PHP",
            "source": "<?php\n$kob = new KangOpenBanking\\KangOpenBanking(getenv('KOB_API_KEY'));\n$res = $kob->request('POST', '/v1/banking/approvals/{approvalId}/escalate', []);\nprint_r($res);"
          }
        ]
      }
    },
    "/v1/accounts/{accountId}/overdraft": {
      "get": {
        "tags": [
          "Overdraft"
        ],
        "summary": "Get overdraft profile",
        "description": "Returns overdraft eligibility, approved limit, utilised and available amounts, risk band, and score factors.",
        "operationId": "getOverdraftProfile",
        "security": [
          {
            "bearerAuth": []
          }
        ],
        "parameters": [
          {
            "name": "accountId",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "$ref": "#/components/parameters/RequestId"
          },
          {
            "$ref": "#/components/parameters/Traceparent"
          },
          {
            "$ref": "#/components/parameters/Tracestate"
          },
          {
            "$ref": "#/components/parameters/AcceptLanguage"
          }
        ],
        "responses": {
          "200": {
            "description": "Overdraft profile with score factors",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "eligible": {
                      "type": "boolean"
                    },
                    "recommended_limit": {
                      "type": "string",
                      "example": "250000",
                      "pattern": "^[0-9]{1,15}$",
                      "description": "Represented as a string integer in the currency's minor unit (XAF has no subunits)."
                    },
                    "approved_limit": {
                      "type": "string",
                      "example": "200000",
                      "pattern": "^[0-9]{1,15}$",
                      "description": "Represented as a string integer in the currency's minor unit (XAF has no subunits)."
                    },
                    "utilised_amount": {
                      "type": "string",
                      "example": "50000",
                      "pattern": "^[0-9]{1,15}$",
                      "description": "Represented as a string integer in the currency's minor unit (XAF has no subunits)."
                    },
                    "available_amount": {
                      "type": "string",
                      "example": "150000",
                      "pattern": "^[0-9]{1,15}$",
                      "description": "Represented as a string integer in the currency's minor unit (XAF has no subunits)."
                    },
                    "risk_band": {
                      "type": "string",
                      "enum": [
                        "A",
                        "B",
                        "C",
                        "D",
                        "F"
                      ]
                    },
                    "status": {
                      "type": "string",
                      "enum": [
                        "active",
                        "suspended",
                        "revoked",
                        "pending_approval",
                        "inactive"
                      ]
                    }
                  }
                },
                "example": {
                  "eligible": true,
                  "recommended_limit": "250000",
                  "approved_limit": "200000",
                  "utilised_amount": "50000",
                  "available_amount": "150000",
                  "risk_band": "A",
                  "status": "active"
                }
              }
            },
            "headers": {
              "x-fapi-interaction-id": {
                "$ref": "#/components/headers/XFapiInteractionIdResponse"
              },
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/XRateLimitLimit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/XRateLimitRemaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/XRateLimitReset"
              },
              "Cache-Control": {
                "$ref": "#/components/headers/CacheControl"
              },
              "ETag": {
                "$ref": "#/components/headers/ETag"
              },
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              },
              "traceparent": {
                "$ref": "#/components/headers/Traceparent"
              },
              "Content-Language": {
                "$ref": "#/components/headers/Content-Language"
              }
            }
          },
          "400": {
            "description": "Bad request",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              },
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                },
                "examples": {
                  "error": {
                    "$ref": "#/components/examples/ErrorBadRequest"
                  }
                }
              }
            },
            "headers": {
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/XRateLimitLimit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/XRateLimitRemaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/XRateLimitReset"
              },
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "403": {
            "$ref": "#/components/responses/Forbidden",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "404": {
            "$ref": "#/components/responses/NotFound",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "409": {
            "$ref": "#/components/responses/Conflict",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "429": {
            "$ref": "#/components/responses/TooManyRequests",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "500": {
            "$ref": "#/components/responses/InternalServerError",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          }
        },
        "x-codeSamples": [
          {
            "lang": "cURL",
            "label": "cURL",
            "source": "curl -X GET \"https://api.kangopenbanking.com/v1/accounts/{accountId}/overdraft\" \\\n  -H \"Authorization: Bearer $KOB_ACCESS_TOKEN\" \\\n  -H \"Content-Type: application/json\""
          },
          {
            "lang": "JavaScript",
            "label": "Node.js",
            "source": "import { KangOpenBanking } from \"@kangopenbanking/sdk\";\n\nconst kob = new KangOpenBanking({ apiKey: process.env.KOB_API_KEY });\nconst res = await kob.request(\"GET\", \"/v1/accounts/{accountId}/overdraft\");\nconsole.log(res);"
          },
          {
            "lang": "Python",
            "label": "Python",
            "source": "from kangopenbanking import KangOpenBanking\n\nkob = KangOpenBanking(api_key=os.environ[\"KOB_API_KEY\"])\nres = kob.request(\"GET\", \"/v1/accounts/{accountId}/overdraft\")\nprint(res)"
          },
          {
            "lang": "PHP",
            "label": "PHP",
            "source": "<?php\n$kob = new KangOpenBanking\\KangOpenBanking(getenv('KOB_API_KEY'));\n$res = $kob->request('GET', '/v1/accounts/{accountId}/overdraft');\nprint_r($res);"
          }
        ]
      }
    },
    "/v1/accounts/{accountId}/overdraft/recalculate": {
      "post": {
        "tags": [
          "Overdraft"
        ],
        "summary": "Recalculate overdraft eligibility",
        "description": "Re-evaluates account behavior (salary consistency, savings, balance, tenure, activity, repayment history, credit score) and produces an explainable overdraft recommendation.",
        "operationId": "recalculateOverdraft",
        "security": [
          {
            "bearerAuth": []
          }
        ],
        "parameters": [
          {
            "name": "accountId",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "$ref": "#/components/parameters/RequestId"
          },
          {
            "$ref": "#/components/parameters/Traceparent"
          },
          {
            "$ref": "#/components/parameters/Tracestate"
          },
          {
            "$ref": "#/components/parameters/AcceptLanguage"
          }
        ],
        "responses": {
          "200": {
            "description": "Recalculated overdraft profile with score factor breakdown",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "eligible": {
                      "type": "boolean"
                    },
                    "recommended_limit": {
                      "type": "string",
                      "pattern": "^[0-9]{1,15}$",
                      "description": "Represented as a string integer in the currency's minor unit (XAF has no subunits)."
                    },
                    "risk_band": {
                      "type": "string"
                    },
                    "score_factors": {
                      "type": "object"
                    }
                  }
                },
                "example": {
                  "eligible": true,
                  "recommended_limit": "1000",
                  "risk_band": "string",
                  "score_factors": {}
                }
              }
            },
            "headers": {
              "x-fapi-interaction-id": {
                "$ref": "#/components/headers/XFapiInteractionIdResponse"
              },
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/XRateLimitLimit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/XRateLimitRemaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/XRateLimitReset"
              },
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              },
              "traceparent": {
                "$ref": "#/components/headers/Traceparent"
              },
              "Content-Language": {
                "$ref": "#/components/headers/Content-Language"
              }
            }
          },
          "400": {
            "description": "Bad request",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              },
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                },
                "examples": {
                  "error": {
                    "$ref": "#/components/examples/ErrorBadRequest"
                  }
                }
              }
            },
            "headers": {
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/XRateLimitLimit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/XRateLimitRemaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/XRateLimitReset"
              },
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "403": {
            "$ref": "#/components/responses/Forbidden",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "404": {
            "$ref": "#/components/responses/NotFound",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "409": {
            "$ref": "#/components/responses/Conflict",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "429": {
            "$ref": "#/components/responses/TooManyRequests",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "500": {
            "$ref": "#/components/responses/InternalServerError",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          }
        },
        "x-codeSamples": [
          {
            "lang": "cURL",
            "label": "cURL",
            "source": "curl -X POST \"https://api.kangopenbanking.com/v1/accounts/{accountId}/overdraft/recalculate\" \\\n  -H \"Authorization: Bearer $KOB_ACCESS_TOKEN\" \\\n  -H \"Content-Type: application/json\""
          },
          {
            "lang": "JavaScript",
            "label": "Node.js",
            "source": "import { KangOpenBanking } from \"@kangopenbanking/sdk\";\n\nconst kob = new KangOpenBanking({ apiKey: process.env.KOB_API_KEY });\nconst res = await kob.request(\"POST\", \"/v1/accounts/{accountId}/overdraft/recalculate\");\nconsole.log(res);"
          },
          {
            "lang": "Python",
            "label": "Python",
            "source": "from kangopenbanking import KangOpenBanking\n\nkob = KangOpenBanking(api_key=os.environ[\"KOB_API_KEY\"])\nres = kob.request(\"POST\", \"/v1/accounts/{accountId}/overdraft/recalculate\")\nprint(res)"
          },
          {
            "lang": "PHP",
            "label": "PHP",
            "source": "<?php\n$kob = new KangOpenBanking\\KangOpenBanking(getenv('KOB_API_KEY'));\n$res = $kob->request('POST', '/v1/accounts/{accountId}/overdraft/recalculate');\nprint_r($res);"
          }
        ]
      }
    },
    "/v1/accounts/{accountId}/overdraft/request": {
      "post": {
        "tags": [
          "Overdraft"
        ],
        "summary": "Request overdraft facility",
        "description": "Request an overdraft. Automatically scores the account and either auto-approves (high score) or routes to manager approval.",
        "operationId": "requestOverdraft",
        "security": [
          {
            "bearerAuth": []
          }
        ],
        "parameters": [
          {
            "name": "accountId",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "Idempotency-Key",
            "in": "header",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid"
            },
            "description": "Required on all POST/PUT endpoints. Unique key for idempotent request processing (UUID v4 recommended). Keys expire after 24 hours."
          },
          {
            "$ref": "#/components/parameters/RequestId"
          },
          {
            "$ref": "#/components/parameters/Traceparent"
          },
          {
            "$ref": "#/components/parameters/Tracestate"
          },
          {
            "$ref": "#/components/parameters/AcceptLanguage"
          }
        ],
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "requested_limit": {
                    "type": "number",
                    "example": 300000
                  }
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Overdraft auto-approved",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "success": {
                      "type": "boolean",
                      "example": true
                    },
                    "message": {
                      "type": "string"
                    }
                  }
                },
                "example": {
                  "success": true,
                  "message": "string"
                }
              }
            },
            "headers": {
              "x-fapi-interaction-id": {
                "$ref": "#/components/headers/XFapiInteractionIdResponse"
              },
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/XRateLimitLimit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/XRateLimitRemaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/XRateLimitReset"
              },
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              },
              "X-Idempotent-Replay": {
                "$ref": "#/components/headers/X-Idempotent-Replay"
              },
              "X-Idempotency-Status": {
                "$ref": "#/components/headers/X-Idempotency-Status"
              },
              "traceparent": {
                "$ref": "#/components/headers/Traceparent"
              },
              "Content-Language": {
                "$ref": "#/components/headers/Content-Language"
              }
            }
          },
          "202": {
            "description": "Pending manager approval",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "status": {
                      "type": "string",
                      "example": "pending_approval"
                    },
                    "overdraft_id": {
                      "type": "string"
                    }
                  }
                },
                "example": {
                  "status": "pending_approval",
                  "overdraft_id": "string"
                }
              }
            },
            "headers": {
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/XRateLimitLimit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/XRateLimitRemaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/XRateLimitReset"
              },
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              },
              "X-Idempotent-Replay": {
                "$ref": "#/components/headers/X-Idempotent-Replay"
              },
              "X-Idempotency-Status": {
                "$ref": "#/components/headers/X-Idempotency-Status"
              },
              "traceparent": {
                "$ref": "#/components/headers/Traceparent"
              },
              "Content-Language": {
                "$ref": "#/components/headers/Content-Language"
              }
            }
          },
          "400": {
            "description": "Bad request",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              },
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                },
                "examples": {
                  "error": {
                    "$ref": "#/components/examples/ErrorBadRequest"
                  }
                }
              }
            },
            "headers": {
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/XRateLimitLimit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/XRateLimitRemaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/XRateLimitReset"
              },
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "403": {
            "$ref": "#/components/responses/Forbidden",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "404": {
            "$ref": "#/components/responses/NotFound",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "409": {
            "$ref": "#/components/responses/Conflict",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "429": {
            "$ref": "#/components/responses/TooManyRequests",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "500": {
            "$ref": "#/components/responses/InternalServerError",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          }
        },
        "x-codeSamples": [
          {
            "lang": "cURL",
            "label": "cURL",
            "source": "curl -X POST \"https://api.kangopenbanking.com/v1/accounts/{accountId}/overdraft/request\" \\\n  -H \"Authorization: Bearer $KOB_ACCESS_TOKEN\" \\\n  -H \"Content-Type: application/json\" \\\n  -d '{}'"
          },
          {
            "lang": "JavaScript",
            "label": "Node.js",
            "source": "import { KangOpenBanking } from \"@kangopenbanking/sdk\";\n\nconst kob = new KangOpenBanking({ apiKey: process.env.KOB_API_KEY });\nconst res = await kob.request(\"POST\", \"/v1/accounts/{accountId}/overdraft/request\", { /* payload */ });\nconsole.log(res);"
          },
          {
            "lang": "Python",
            "label": "Python",
            "source": "from kangopenbanking import KangOpenBanking\n\nkob = KangOpenBanking(api_key=os.environ[\"KOB_API_KEY\"])\nres = kob.request(\"POST\", \"/v1/accounts/{accountId}/overdraft/request\", json={})\nprint(res)"
          },
          {
            "lang": "PHP",
            "label": "PHP",
            "source": "<?php\n$kob = new KangOpenBanking\\KangOpenBanking(getenv('KOB_API_KEY'));\n$res = $kob->request('POST', '/v1/accounts/{accountId}/overdraft/request', []);\nprint_r($res);"
          }
        ]
      }
    },
    "/v1/accounts/{accountId}/overdraft/approve": {
      "post": {
        "tags": [
          "Overdraft"
        ],
        "summary": "Approve overdraft",
        "operationId": "approveOverdraft",
        "security": [
          {
            "bearerAuth": []
          }
        ],
        "parameters": [
          {
            "name": "accountId",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "Idempotency-Key",
            "in": "header",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid"
            },
            "description": "Required on all POST/PUT endpoints. Unique key for idempotent request processing (UUID v4 recommended). Keys expire after 24 hours."
          },
          {
            "$ref": "#/components/parameters/RequestId"
          },
          {
            "$ref": "#/components/parameters/Traceparent"
          },
          {
            "$ref": "#/components/parameters/Tracestate"
          },
          {
            "$ref": "#/components/parameters/AcceptLanguage"
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "required": [
                  "approved_limit"
                ],
                "properties": {
                  "approved_limit": {
                    "type": "string",
                    "example": "200000",
                    "pattern": "^[0-9]{1,15}$",
                    "description": "Represented as a string integer in the currency's minor unit (XAF has no subunits)."
                  },
                  "comments": {
                    "type": "string"
                  }
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Overdraft approved and activated",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "success": {
                      "type": "boolean",
                      "example": true
                    },
                    "message": {
                      "type": "string"
                    }
                  }
                },
                "example": {
                  "success": true,
                  "message": "string"
                }
              }
            },
            "headers": {
              "x-fapi-interaction-id": {
                "$ref": "#/components/headers/XFapiInteractionIdResponse"
              },
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/XRateLimitLimit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/XRateLimitRemaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/XRateLimitReset"
              },
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              },
              "X-Idempotent-Replay": {
                "$ref": "#/components/headers/X-Idempotent-Replay"
              },
              "X-Idempotency-Status": {
                "$ref": "#/components/headers/X-Idempotency-Status"
              },
              "traceparent": {
                "$ref": "#/components/headers/Traceparent"
              },
              "Content-Language": {
                "$ref": "#/components/headers/Content-Language"
              }
            }
          },
          "400": {
            "description": "Bad request",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              },
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                },
                "examples": {
                  "error": {
                    "$ref": "#/components/examples/ErrorBadRequest"
                  }
                }
              }
            },
            "headers": {
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/XRateLimitLimit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/XRateLimitRemaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/XRateLimitReset"
              },
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "403": {
            "$ref": "#/components/responses/Forbidden",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "404": {
            "$ref": "#/components/responses/NotFound",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "409": {
            "$ref": "#/components/responses/Conflict",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "429": {
            "$ref": "#/components/responses/TooManyRequests",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "500": {
            "$ref": "#/components/responses/InternalServerError",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          }
        },
        "x-codeSamples": [
          {
            "lang": "cURL",
            "label": "cURL",
            "source": "curl -X POST \"https://api.kangopenbanking.com/v1/accounts/{accountId}/overdraft/approve\" \\\n  -H \"Authorization: Bearer $KOB_ACCESS_TOKEN\" \\\n  -H \"Content-Type: application/json\" \\\n  -d '{}'"
          },
          {
            "lang": "JavaScript",
            "label": "Node.js",
            "source": "import { KangOpenBanking } from \"@kangopenbanking/sdk\";\n\nconst kob = new KangOpenBanking({ apiKey: process.env.KOB_API_KEY });\nconst res = await kob.request(\"POST\", \"/v1/accounts/{accountId}/overdraft/approve\", { /* payload */ });\nconsole.log(res);"
          },
          {
            "lang": "Python",
            "label": "Python",
            "source": "from kangopenbanking import KangOpenBanking\n\nkob = KangOpenBanking(api_key=os.environ[\"KOB_API_KEY\"])\nres = kob.request(\"POST\", \"/v1/accounts/{accountId}/overdraft/approve\", json={})\nprint(res)"
          },
          {
            "lang": "PHP",
            "label": "PHP",
            "source": "<?php\n$kob = new KangOpenBanking\\KangOpenBanking(getenv('KOB_API_KEY'));\n$res = $kob->request('POST', '/v1/accounts/{accountId}/overdraft/approve', []);\nprint_r($res);"
          }
        ]
      }
    },
    "/v1/accounts/{accountId}/overdraft/suspend": {
      "post": {
        "tags": [
          "Overdraft"
        ],
        "summary": "Suspend overdraft",
        "operationId": "suspendOverdraft",
        "security": [
          {
            "bearerAuth": []
          }
        ],
        "parameters": [
          {
            "name": "accountId",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "$ref": "#/components/parameters/RequestId"
          },
          {
            "$ref": "#/components/parameters/Traceparent"
          },
          {
            "$ref": "#/components/parameters/Tracestate"
          },
          {
            "$ref": "#/components/parameters/AcceptLanguage"
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "required": [
                  "reason"
                ],
                "properties": {
                  "reason": {
                    "type": "string"
                  }
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Overdraft suspended",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "success": {
                      "type": "boolean",
                      "example": true
                    },
                    "message": {
                      "type": "string"
                    }
                  }
                },
                "example": {
                  "success": true,
                  "message": "string"
                }
              }
            },
            "headers": {
              "x-fapi-interaction-id": {
                "$ref": "#/components/headers/XFapiInteractionIdResponse"
              },
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/XRateLimitLimit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/XRateLimitRemaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/XRateLimitReset"
              },
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              },
              "traceparent": {
                "$ref": "#/components/headers/Traceparent"
              },
              "Content-Language": {
                "$ref": "#/components/headers/Content-Language"
              }
            }
          },
          "400": {
            "description": "Bad request",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              },
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                },
                "examples": {
                  "error": {
                    "$ref": "#/components/examples/ErrorBadRequest"
                  }
                }
              }
            },
            "headers": {
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/XRateLimitLimit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/XRateLimitRemaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/XRateLimitReset"
              },
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "403": {
            "$ref": "#/components/responses/Forbidden",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "404": {
            "$ref": "#/components/responses/NotFound",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "409": {
            "$ref": "#/components/responses/Conflict",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "429": {
            "$ref": "#/components/responses/TooManyRequests",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "500": {
            "$ref": "#/components/responses/InternalServerError",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          }
        },
        "x-codeSamples": [
          {
            "lang": "cURL",
            "label": "cURL",
            "source": "curl -X POST \"https://api.kangopenbanking.com/v1/accounts/{accountId}/overdraft/suspend\" \\\n  -H \"Authorization: Bearer $KOB_ACCESS_TOKEN\" \\\n  -H \"Content-Type: application/json\" \\\n  -d '{}'"
          },
          {
            "lang": "JavaScript",
            "label": "Node.js",
            "source": "import { KangOpenBanking } from \"@kangopenbanking/sdk\";\n\nconst kob = new KangOpenBanking({ apiKey: process.env.KOB_API_KEY });\nconst res = await kob.request(\"POST\", \"/v1/accounts/{accountId}/overdraft/suspend\", { /* payload */ });\nconsole.log(res);"
          },
          {
            "lang": "Python",
            "label": "Python",
            "source": "from kangopenbanking import KangOpenBanking\n\nkob = KangOpenBanking(api_key=os.environ[\"KOB_API_KEY\"])\nres = kob.request(\"POST\", \"/v1/accounts/{accountId}/overdraft/suspend\", json={})\nprint(res)"
          },
          {
            "lang": "PHP",
            "label": "PHP",
            "source": "<?php\n$kob = new KangOpenBanking\\KangOpenBanking(getenv('KOB_API_KEY'));\n$res = $kob->request('POST', '/v1/accounts/{accountId}/overdraft/suspend', []);\nprint_r($res);"
          }
        ]
      }
    },
    "/v1/accounts/{accountId}/overdraft/revoke": {
      "post": {
        "tags": [
          "Overdraft"
        ],
        "summary": "Revoke overdraft",
        "operationId": "revokeOverdraft",
        "security": [
          {
            "bearerAuth": []
          }
        ],
        "parameters": [
          {
            "name": "accountId",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "$ref": "#/components/parameters/RequestId"
          },
          {
            "$ref": "#/components/parameters/Traceparent"
          },
          {
            "$ref": "#/components/parameters/Tracestate"
          },
          {
            "$ref": "#/components/parameters/AcceptLanguage"
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "required": [
                  "reason"
                ],
                "properties": {
                  "reason": {
                    "type": "string"
                  }
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Overdraft revoked",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "success": {
                      "type": "boolean",
                      "example": true
                    },
                    "message": {
                      "type": "string"
                    }
                  }
                },
                "example": {
                  "success": true,
                  "message": "string"
                }
              }
            },
            "headers": {
              "x-fapi-interaction-id": {
                "$ref": "#/components/headers/XFapiInteractionIdResponse"
              },
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/XRateLimitLimit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/XRateLimitRemaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/XRateLimitReset"
              },
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              },
              "traceparent": {
                "$ref": "#/components/headers/Traceparent"
              },
              "Content-Language": {
                "$ref": "#/components/headers/Content-Language"
              }
            }
          },
          "400": {
            "description": "Bad request",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              },
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                },
                "examples": {
                  "error": {
                    "$ref": "#/components/examples/ErrorBadRequest"
                  }
                }
              }
            },
            "headers": {
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/XRateLimitLimit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/XRateLimitRemaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/XRateLimitReset"
              },
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "403": {
            "$ref": "#/components/responses/Forbidden",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "404": {
            "$ref": "#/components/responses/NotFound",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "409": {
            "$ref": "#/components/responses/Conflict",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "429": {
            "$ref": "#/components/responses/TooManyRequests",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "500": {
            "$ref": "#/components/responses/InternalServerError",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          }
        },
        "x-codeSamples": [
          {
            "lang": "cURL",
            "label": "cURL",
            "source": "curl -X POST \"https://api.kangopenbanking.com/v1/accounts/{accountId}/overdraft/revoke\" \\\n  -H \"Authorization: Bearer $KOB_ACCESS_TOKEN\" \\\n  -H \"Content-Type: application/json\" \\\n  -d '{}'"
          },
          {
            "lang": "JavaScript",
            "label": "Node.js",
            "source": "import { KangOpenBanking } from \"@kangopenbanking/sdk\";\n\nconst kob = new KangOpenBanking({ apiKey: process.env.KOB_API_KEY });\nconst res = await kob.request(\"POST\", \"/v1/accounts/{accountId}/overdraft/revoke\", { /* payload */ });\nconsole.log(res);"
          },
          {
            "lang": "Python",
            "label": "Python",
            "source": "from kangopenbanking import KangOpenBanking\n\nkob = KangOpenBanking(api_key=os.environ[\"KOB_API_KEY\"])\nres = kob.request(\"POST\", \"/v1/accounts/{accountId}/overdraft/revoke\", json={})\nprint(res)"
          },
          {
            "lang": "PHP",
            "label": "PHP",
            "source": "<?php\n$kob = new KangOpenBanking\\KangOpenBanking(getenv('KOB_API_KEY'));\n$res = $kob->request('POST', '/v1/accounts/{accountId}/overdraft/revoke', []);\nprint_r($res);"
          }
        ]
      }
    },
    "/v1/accounts/{accountId}/overdraft/reinstate": {
      "post": {
        "tags": [
          "Overdraft"
        ],
        "summary": "Reinstate overdraft",
        "operationId": "reinstateOverdraft",
        "security": [
          {
            "bearerAuth": []
          }
        ],
        "parameters": [
          {
            "name": "accountId",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "Idempotency-Key",
            "in": "header",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid"
            },
            "description": "Required on all POST/PUT endpoints. Unique key for idempotent request processing (UUID v4 recommended). Keys expire after 24 hours."
          },
          {
            "$ref": "#/components/parameters/RequestId"
          },
          {
            "$ref": "#/components/parameters/Traceparent"
          },
          {
            "$ref": "#/components/parameters/Tracestate"
          },
          {
            "$ref": "#/components/parameters/AcceptLanguage"
          }
        ],
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "new_limit": {
                    "type": "number"
                  },
                  "comments": {
                    "type": "string"
                  }
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Overdraft reinstated",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "success": {
                      "type": "boolean",
                      "example": true
                    },
                    "message": {
                      "type": "string"
                    }
                  }
                },
                "example": {
                  "success": true,
                  "message": "string"
                }
              }
            },
            "headers": {
              "x-fapi-interaction-id": {
                "$ref": "#/components/headers/XFapiInteractionIdResponse"
              },
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/XRateLimitLimit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/XRateLimitRemaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/XRateLimitReset"
              },
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              },
              "X-Idempotent-Replay": {
                "$ref": "#/components/headers/X-Idempotent-Replay"
              },
              "X-Idempotency-Status": {
                "$ref": "#/components/headers/X-Idempotency-Status"
              },
              "traceparent": {
                "$ref": "#/components/headers/Traceparent"
              },
              "Content-Language": {
                "$ref": "#/components/headers/Content-Language"
              }
            }
          },
          "400": {
            "description": "Bad request",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              },
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                },
                "examples": {
                  "error": {
                    "$ref": "#/components/examples/ErrorBadRequest"
                  }
                }
              }
            },
            "headers": {
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/XRateLimitLimit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/XRateLimitRemaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/XRateLimitReset"
              },
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "403": {
            "$ref": "#/components/responses/Forbidden",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "404": {
            "$ref": "#/components/responses/NotFound",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "409": {
            "$ref": "#/components/responses/Conflict",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "429": {
            "$ref": "#/components/responses/TooManyRequests",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "500": {
            "$ref": "#/components/responses/InternalServerError",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          }
        },
        "x-codeSamples": [
          {
            "lang": "cURL",
            "label": "cURL",
            "source": "curl -X POST \"https://api.kangopenbanking.com/v1/accounts/{accountId}/overdraft/reinstate\" \\\n  -H \"Authorization: Bearer $KOB_ACCESS_TOKEN\" \\\n  -H \"Content-Type: application/json\" \\\n  -d '{}'"
          },
          {
            "lang": "JavaScript",
            "label": "Node.js",
            "source": "import { KangOpenBanking } from \"@kangopenbanking/sdk\";\n\nconst kob = new KangOpenBanking({ apiKey: process.env.KOB_API_KEY });\nconst res = await kob.request(\"POST\", \"/v1/accounts/{accountId}/overdraft/reinstate\", { /* payload */ });\nconsole.log(res);"
          },
          {
            "lang": "Python",
            "label": "Python",
            "source": "from kangopenbanking import KangOpenBanking\n\nkob = KangOpenBanking(api_key=os.environ[\"KOB_API_KEY\"])\nres = kob.request(\"POST\", \"/v1/accounts/{accountId}/overdraft/reinstate\", json={})\nprint(res)"
          },
          {
            "lang": "PHP",
            "label": "PHP",
            "source": "<?php\n$kob = new KangOpenBanking\\KangOpenBanking(getenv('KOB_API_KEY'));\n$res = $kob->request('POST', '/v1/accounts/{accountId}/overdraft/reinstate', []);\nprint_r($res);"
          }
        ]
      }
    },
    "/v1/wallets": {
      "post": {
        "tags": [
          "Payment Gateway"
        ],
        "summary": "Create custodial wallet",
        "operationId": "walletCreate",
        "security": [
          {
            "bearerAuth": []
          }
        ],
        "parameters": [
          {
            "name": "Idempotency-Key",
            "in": "header",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid"
            },
            "description": "Required on all POST/PUT endpoints. Unique key for idempotent request processing (UUID v4 recommended). Keys expire after 24 hours."
          },
          {
            "$ref": "#/components/parameters/RequestId"
          },
          {
            "$ref": "#/components/parameters/Traceparent"
          },
          {
            "$ref": "#/components/parameters/Tracestate"
          },
          {
            "$ref": "#/components/parameters/AcceptLanguage"
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "required": [
                  "currency"
                ],
                "properties": {
                  "currency": {
                    "type": "string",
                    "default": "XAF",
                    "enum": [
                      "XAF",
                      "XOF",
                      "USD",
                      "EUR",
                      "GBP",
                      "CNY",
                      "NGN",
                      "GHS",
                      "KES",
                      "ZAR"
                    ],
                    "description": "ISO 4217 currency code. Default is XAF (Central African CFA Franc)."
                  },
                  "label": {
                    "type": "string"
                  },
                  "metadata": {
                    "type": "object"
                  }
                }
              }
            }
          }
        },
        "responses": {
          "201": {
            "description": "Wallet created",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "id": {
                      "type": "string"
                    },
                    "currency": {
                      "type": "string",
                      "enum": [
                        "XAF",
                        "XOF",
                        "USD",
                        "EUR",
                        "GBP",
                        "CNY",
                        "NGN",
                        "GHS",
                        "KES",
                        "ZAR"
                      ],
                      "default": "XAF",
                      "description": "ISO 4217 currency code. Default is XAF (Central African CFA Franc)."
                    },
                    "available_balance": {
                      "type": "string",
                      "pattern": "^[0-9]{1,15}$",
                      "description": "Represented as a string integer in the currency's minor unit (XAF has no subunits). Must be consistent with the currency field."
                    },
                    "status": {
                      "type": "string"
                    },
                    "created_at": {
                      "type": "string",
                      "format": "date-time"
                    }
                  }
                },
                "example": {
                  "id": "string",
                  "currency": "XAF",
                  "available_balance": "1000",
                  "status": "string",
                  "created_at": "2026-01-01T00:00:00Z"
                }
              }
            },
            "headers": {
              "x-fapi-interaction-id": {
                "$ref": "#/components/headers/XFapiInteractionIdResponse"
              },
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/XRateLimitLimit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/XRateLimitRemaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/XRateLimitReset"
              },
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              },
              "X-Idempotent-Replay": {
                "$ref": "#/components/headers/X-Idempotent-Replay"
              },
              "X-Idempotency-Status": {
                "$ref": "#/components/headers/X-Idempotency-Status"
              },
              "traceparent": {
                "$ref": "#/components/headers/Traceparent"
              },
              "Content-Language": {
                "$ref": "#/components/headers/Content-Language"
              }
            }
          },
          "400": {
            "description": "Bad request",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              },
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                },
                "examples": {
                  "error": {
                    "$ref": "#/components/examples/ErrorBadRequest"
                  }
                }
              }
            },
            "headers": {
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/XRateLimitLimit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/XRateLimitRemaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/XRateLimitReset"
              },
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "403": {
            "$ref": "#/components/responses/Forbidden",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "404": {
            "$ref": "#/components/responses/NotFound",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "409": {
            "$ref": "#/components/responses/Conflict",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "429": {
            "$ref": "#/components/responses/TooManyRequests",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "500": {
            "$ref": "#/components/responses/InternalServerError",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          }
        },
        "x-codeSamples": [
          {
            "lang": "cURL",
            "label": "cURL",
            "source": "curl -X POST \"https://api.kangopenbanking.com/v1/wallets\" \\\n  -H \"Authorization: Bearer $KOB_ACCESS_TOKEN\" \\\n  -H \"Content-Type: application/json\" \\\n  -d '{}'"
          },
          {
            "lang": "JavaScript",
            "label": "Node.js",
            "source": "import { KangOpenBanking } from \"@kangopenbanking/sdk\";\n\nconst kob = new KangOpenBanking({ apiKey: process.env.KOB_API_KEY });\nconst res = await kob.request(\"POST\", \"/v1/wallets\", { /* payload */ });\nconsole.log(res);"
          },
          {
            "lang": "Python",
            "label": "Python",
            "source": "from kangopenbanking import KangOpenBanking\n\nkob = KangOpenBanking(api_key=os.environ[\"KOB_API_KEY\"])\nres = kob.request(\"POST\", \"/v1/wallets\", json={})\nprint(res)"
          },
          {
            "lang": "PHP",
            "label": "PHP",
            "source": "<?php\n$kob = new KangOpenBanking\\KangOpenBanking(getenv('KOB_API_KEY'));\n$res = $kob->request('POST', '/v1/wallets', []);\nprint_r($res);"
          }
        ]
      },
      "get": {
        "tags": [
          "Payment Gateway"
        ],
        "summary": "List wallets",
        "operationId": "walletList",
        "security": [
          {
            "bearerAuth": []
          }
        ],
        "parameters": [
          {
            "name": "limit",
            "in": "query",
            "schema": {
              "type": "integer",
              "default": 25,
              "maximum": 100
            },
            "description": "Items per page"
          },
          {
            "name": "offset",
            "in": "query",
            "schema": {
              "type": "integer",
              "default": 0
            },
            "description": "Items to skip"
          },
          {
            "name": "sort_by",
            "in": "query",
            "schema": {
              "type": "string",
              "default": "created_at"
            },
            "description": "Sort field"
          },
          {
            "name": "sort_order",
            "in": "query",
            "schema": {
              "type": "string",
              "enum": [
                "asc",
                "desc"
              ],
              "default": "desc"
            },
            "description": "Sort direction"
          },
          {
            "$ref": "#/components/parameters/StartingAfter"
          },
          {
            "$ref": "#/components/parameters/EndingBefore"
          },
          {
            "$ref": "#/components/parameters/RequestId"
          },
          {
            "$ref": "#/components/parameters/Traceparent"
          },
          {
            "$ref": "#/components/parameters/Tracestate"
          },
          {
            "$ref": "#/components/parameters/AcceptLanguage"
          }
        ],
        "responses": {
          "200": {
            "description": "Wallets list",
            "content": {
              "application/json": {
                "schema": {
                  "allOf": [
                    {
                      "$ref": "#/components/schemas/PaginatedResponse"
                    },
                    {
                      "type": "object",
                      "properties": {
                        "data": {
                          "type": "array",
                          "items": {
                            "$ref": "#/components/schemas/GatewayMerchantWallet"
                          }
                        }
                      }
                    }
                  ]
                },
                "example": {
                  "data": [
                    {
                      "id": "f1d6f4a0-1d4e-4a3a-9e0a-1a2b3c4d5e6f",
                      "merchant_id": "f1d6f4a0-1d4e-4a3a-9e0a-1a2b3c4d5e6f",
                      "currency": "XAF",
                      "available_balance": "500000",
                      "pending_balance": 25000,
                      "ledger_balance": 525000,
                      "updated_at": "2026-01-31T12:00:00Z"
                    }
                  ],
                  "pagination": {
                    "page": 1,
                    "limit": 20,
                    "total": 150,
                    "has_next": true,
                    "next_cursor": "eyJpZCI6IjEyMyJ9"
                  },
                  "meta": {
                    "request_id": "550e8400-e29b-41d4-a716-446655440000",
                    "timestamp": "2025-03-27T12:00:00Z",
                    "api_version": "4.3.0"
                  }
                }
              }
            },
            "headers": {
              "x-fapi-interaction-id": {
                "$ref": "#/components/headers/XFapiInteractionIdResponse"
              },
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/XRateLimitLimit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/XRateLimitRemaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/XRateLimitReset"
              },
              "Cache-Control": {
                "$ref": "#/components/headers/CacheControl"
              },
              "ETag": {
                "$ref": "#/components/headers/ETag"
              },
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              },
              "traceparent": {
                "$ref": "#/components/headers/Traceparent"
              },
              "Content-Language": {
                "$ref": "#/components/headers/Content-Language"
              }
            }
          },
          "400": {
            "description": "Bad request",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              },
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                },
                "examples": {
                  "error": {
                    "$ref": "#/components/examples/ErrorBadRequest"
                  }
                }
              }
            },
            "headers": {
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/XRateLimitLimit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/XRateLimitRemaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/XRateLimitReset"
              },
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "403": {
            "$ref": "#/components/responses/Forbidden",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "404": {
            "$ref": "#/components/responses/NotFound",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "409": {
            "$ref": "#/components/responses/Conflict",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "429": {
            "$ref": "#/components/responses/TooManyRequests",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "500": {
            "$ref": "#/components/responses/InternalServerError",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          }
        },
        "x-codeSamples": [
          {
            "lang": "cURL",
            "label": "cURL",
            "source": "curl -X GET \"https://api.kangopenbanking.com/v1/wallets\" \\\n  -H \"Authorization: Bearer $KOB_ACCESS_TOKEN\" \\\n  -H \"Content-Type: application/json\""
          },
          {
            "lang": "JavaScript",
            "label": "Node.js",
            "source": "import { KangOpenBanking } from \"@kangopenbanking/sdk\";\n\nconst kob = new KangOpenBanking({ apiKey: process.env.KOB_API_KEY });\nconst res = await kob.request(\"GET\", \"/v1/wallets\");\nconsole.log(res);"
          },
          {
            "lang": "Python",
            "label": "Python",
            "source": "from kangopenbanking import KangOpenBanking\n\nkob = KangOpenBanking(api_key=os.environ[\"KOB_API_KEY\"])\nres = kob.request(\"GET\", \"/v1/wallets\")\nprint(res)"
          },
          {
            "lang": "PHP",
            "label": "PHP",
            "source": "<?php\n$kob = new KangOpenBanking\\KangOpenBanking(getenv('KOB_API_KEY'));\n$res = $kob->request('GET', '/v1/wallets');\nprint_r($res);"
          }
        ]
      }
    },
    "/v1/wallets/{walletId}": {
      "get": {
        "tags": [
          "Payment Gateway"
        ],
        "summary": "Get wallet balance",
        "operationId": "walletGet",
        "security": [
          {
            "bearerAuth": []
          }
        ],
        "parameters": [
          {
            "name": "walletId",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "$ref": "#/components/parameters/RequestId"
          },
          {
            "$ref": "#/components/parameters/Traceparent"
          },
          {
            "$ref": "#/components/parameters/Tracestate"
          },
          {
            "$ref": "#/components/parameters/AcceptLanguage"
          }
        ],
        "responses": {
          "200": {
            "description": "Wallet with Available, Pending, Ledger balances",
            "content": {
              "application/json": {
                "schema": {
                  "allOf": [
                    {
                      "$ref": "#/components/schemas/StandardResponse"
                    },
                    {
                      "type": "object",
                      "properties": {
                        "data": {
                          "$ref": "#/components/schemas/GatewayMerchantWallet"
                        }
                      }
                    }
                  ]
                },
                "example": {
                  "data": {
                    "id": "00000000-0000-4000-8000-000000000000",
                    "merchant_id": "00000000-0000-4000-8000-000000000000",
                    "currency": "XAF",
                    "available_balance": "500000",
                    "pending_balance": 25000,
                    "ledger_balance": 525000,
                    "updated_at": "2026-01-01T00:00:00Z"
                  },
                  "meta": {
                    "request_id": "550e8400-e29b-41d4-a716-446655440000",
                    "timestamp": "2025-03-27T12:00:00Z",
                    "api_version": "4.3.0"
                  }
                }
              }
            },
            "headers": {
              "x-fapi-interaction-id": {
                "$ref": "#/components/headers/XFapiInteractionIdResponse"
              },
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/XRateLimitLimit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/XRateLimitRemaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/XRateLimitReset"
              },
              "Cache-Control": {
                "$ref": "#/components/headers/CacheControl"
              },
              "ETag": {
                "$ref": "#/components/headers/ETag"
              },
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              },
              "traceparent": {
                "$ref": "#/components/headers/Traceparent"
              },
              "Content-Language": {
                "$ref": "#/components/headers/Content-Language"
              }
            }
          },
          "400": {
            "description": "Bad request",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              },
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                },
                "examples": {
                  "error": {
                    "$ref": "#/components/examples/ErrorBadRequest"
                  }
                }
              }
            },
            "headers": {
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/XRateLimitLimit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/XRateLimitRemaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/XRateLimitReset"
              },
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "403": {
            "$ref": "#/components/responses/Forbidden",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "404": {
            "$ref": "#/components/responses/NotFound",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "409": {
            "$ref": "#/components/responses/Conflict",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "429": {
            "$ref": "#/components/responses/TooManyRequests",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "500": {
            "$ref": "#/components/responses/InternalServerError",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          }
        },
        "x-codeSamples": [
          {
            "lang": "cURL",
            "label": "cURL",
            "source": "curl -X GET \"https://api.kangopenbanking.com/v1/wallets/{walletId}\" \\\n  -H \"Authorization: Bearer $KOB_ACCESS_TOKEN\" \\\n  -H \"Content-Type: application/json\""
          },
          {
            "lang": "JavaScript",
            "label": "Node.js",
            "source": "import { KangOpenBanking } from \"@kangopenbanking/sdk\";\n\nconst kob = new KangOpenBanking({ apiKey: process.env.KOB_API_KEY });\nconst res = await kob.request(\"GET\", \"/v1/wallets/{walletId}\");\nconsole.log(res);"
          },
          {
            "lang": "Python",
            "label": "Python",
            "source": "from kangopenbanking import KangOpenBanking\n\nkob = KangOpenBanking(api_key=os.environ[\"KOB_API_KEY\"])\nres = kob.request(\"GET\", \"/v1/wallets/{walletId}\")\nprint(res)"
          },
          {
            "lang": "PHP",
            "label": "PHP",
            "source": "<?php\n$kob = new KangOpenBanking\\KangOpenBanking(getenv('KOB_API_KEY'));\n$res = $kob->request('GET', '/v1/wallets/{walletId}');\nprint_r($res);"
          }
        ]
      }
    },
    "/v1/wallets/{walletId}/credit": {
      "post": {
        "tags": [
          "Payment Gateway"
        ],
        "summary": "Credit wallet",
        "operationId": "walletCredit",
        "security": [
          {
            "bearerAuth": []
          }
        ],
        "parameters": [
          {
            "name": "walletId",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "Idempotency-Key",
            "in": "header",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid"
            },
            "description": "Required on all POST/PUT endpoints. Unique key for idempotent request processing (UUID v4 recommended). Keys expire after 24 hours."
          },
          {
            "$ref": "#/components/parameters/RequestId"
          },
          {
            "$ref": "#/components/parameters/Traceparent"
          },
          {
            "$ref": "#/components/parameters/Tracestate"
          },
          {
            "$ref": "#/components/parameters/AcceptLanguage"
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "required": [
                  "amount",
                  "currency"
                ],
                "properties": {
                  "amount": {
                    "type": "string",
                    "pattern": "^[0-9]{1,15}$",
                    "description": "Represented as a string integer in the currency's minor unit (XAF has no subunits). Must be consistent with the currency field."
                  },
                  "currency": {
                    "type": "string",
                    "enum": [
                      "XAF",
                      "XOF",
                      "USD",
                      "EUR",
                      "GBP",
                      "CNY",
                      "NGN",
                      "GHS",
                      "KES",
                      "ZAR"
                    ],
                    "default": "XAF",
                    "description": "ISO 4217 currency code. Default is XAF (Central African CFA Franc)."
                  },
                  "description": {
                    "type": "string"
                  }
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Wallet credited",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "success": {
                      "type": "boolean",
                      "example": true
                    },
                    "message": {
                      "type": "string"
                    }
                  }
                },
                "example": {
                  "success": true,
                  "message": "string"
                }
              }
            },
            "headers": {
              "x-fapi-interaction-id": {
                "$ref": "#/components/headers/XFapiInteractionIdResponse"
              },
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/XRateLimitLimit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/XRateLimitRemaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/XRateLimitReset"
              },
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              },
              "X-Idempotent-Replay": {
                "$ref": "#/components/headers/X-Idempotent-Replay"
              },
              "X-Idempotency-Status": {
                "$ref": "#/components/headers/X-Idempotency-Status"
              },
              "traceparent": {
                "$ref": "#/components/headers/Traceparent"
              },
              "Content-Language": {
                "$ref": "#/components/headers/Content-Language"
              }
            }
          },
          "400": {
            "description": "Bad request",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              },
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                },
                "examples": {
                  "error": {
                    "$ref": "#/components/examples/ErrorBadRequest"
                  }
                }
              }
            },
            "headers": {
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/XRateLimitLimit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/XRateLimitRemaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/XRateLimitReset"
              },
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "403": {
            "$ref": "#/components/responses/Forbidden",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "404": {
            "$ref": "#/components/responses/NotFound",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "409": {
            "$ref": "#/components/responses/Conflict",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "429": {
            "$ref": "#/components/responses/TooManyRequests",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "500": {
            "$ref": "#/components/responses/InternalServerError",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          }
        },
        "x-codeSamples": [
          {
            "lang": "cURL",
            "label": "cURL",
            "source": "curl -X POST \"https://api.kangopenbanking.com/v1/wallets/{walletId}/credit\" \\\n  -H \"Authorization: Bearer $KOB_ACCESS_TOKEN\" \\\n  -H \"Content-Type: application/json\" \\\n  -d '{}'"
          },
          {
            "lang": "JavaScript",
            "label": "Node.js",
            "source": "import { KangOpenBanking } from \"@kangopenbanking/sdk\";\n\nconst kob = new KangOpenBanking({ apiKey: process.env.KOB_API_KEY });\nconst res = await kob.request(\"POST\", \"/v1/wallets/{walletId}/credit\", { /* payload */ });\nconsole.log(res);"
          },
          {
            "lang": "Python",
            "label": "Python",
            "source": "from kangopenbanking import KangOpenBanking\n\nkob = KangOpenBanking(api_key=os.environ[\"KOB_API_KEY\"])\nres = kob.request(\"POST\", \"/v1/wallets/{walletId}/credit\", json={})\nprint(res)"
          },
          {
            "lang": "PHP",
            "label": "PHP",
            "source": "<?php\n$kob = new KangOpenBanking\\KangOpenBanking(getenv('KOB_API_KEY'));\n$res = $kob->request('POST', '/v1/wallets/{walletId}/credit', []);\nprint_r($res);"
          }
        ]
      }
    },
    "/v1/wallets/{walletId}/debit": {
      "post": {
        "tags": [
          "Payment Gateway"
        ],
        "summary": "Debit wallet",
        "operationId": "walletDebit",
        "security": [
          {
            "bearerAuth": []
          }
        ],
        "parameters": [
          {
            "name": "walletId",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "Idempotency-Key",
            "in": "header",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid"
            },
            "description": "Required on all POST/PUT endpoints. Unique key for idempotent request processing (UUID v4 recommended). Keys expire after 24 hours."
          },
          {
            "$ref": "#/components/parameters/RequestId"
          },
          {
            "$ref": "#/components/parameters/Traceparent"
          },
          {
            "$ref": "#/components/parameters/Tracestate"
          },
          {
            "$ref": "#/components/parameters/AcceptLanguage"
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "required": [
                  "amount",
                  "currency"
                ],
                "properties": {
                  "amount": {
                    "type": "string",
                    "pattern": "^[0-9]{1,15}$",
                    "description": "Represented as a string integer in the currency's minor unit (XAF has no subunits). Must be consistent with the currency field."
                  },
                  "currency": {
                    "type": "string",
                    "enum": [
                      "XAF",
                      "XOF",
                      "USD",
                      "EUR",
                      "GBP",
                      "CNY",
                      "NGN",
                      "GHS",
                      "KES",
                      "ZAR"
                    ],
                    "default": "XAF",
                    "description": "ISO 4217 currency code. Default is XAF (Central African CFA Franc)."
                  },
                  "description": {
                    "type": "string"
                  }
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Wallet debited",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "success": {
                      "type": "boolean",
                      "example": true
                    },
                    "message": {
                      "type": "string"
                    }
                  }
                },
                "example": {
                  "success": true,
                  "message": "string"
                }
              }
            },
            "headers": {
              "x-fapi-interaction-id": {
                "$ref": "#/components/headers/XFapiInteractionIdResponse"
              },
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/XRateLimitLimit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/XRateLimitRemaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/XRateLimitReset"
              },
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              },
              "X-Idempotent-Replay": {
                "$ref": "#/components/headers/X-Idempotent-Replay"
              },
              "X-Idempotency-Status": {
                "$ref": "#/components/headers/X-Idempotency-Status"
              },
              "traceparent": {
                "$ref": "#/components/headers/Traceparent"
              },
              "Content-Language": {
                "$ref": "#/components/headers/Content-Language"
              }
            }
          },
          "400": {
            "description": "Bad request",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              },
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                },
                "examples": {
                  "error": {
                    "$ref": "#/components/examples/ErrorBadRequest"
                  }
                }
              }
            },
            "headers": {
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/XRateLimitLimit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/XRateLimitRemaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/XRateLimitReset"
              },
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "403": {
            "$ref": "#/components/responses/Forbidden",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "404": {
            "$ref": "#/components/responses/NotFound",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "409": {
            "$ref": "#/components/responses/Conflict",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "429": {
            "$ref": "#/components/responses/TooManyRequests",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "500": {
            "$ref": "#/components/responses/InternalServerError",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          }
        },
        "x-codeSamples": [
          {
            "lang": "cURL",
            "label": "cURL",
            "source": "curl -X POST \"https://api.kangopenbanking.com/v1/wallets/{walletId}/debit\" \\\n  -H \"Authorization: Bearer $KOB_ACCESS_TOKEN\" \\\n  -H \"Content-Type: application/json\" \\\n  -d '{}'"
          },
          {
            "lang": "JavaScript",
            "label": "Node.js",
            "source": "import { KangOpenBanking } from \"@kangopenbanking/sdk\";\n\nconst kob = new KangOpenBanking({ apiKey: process.env.KOB_API_KEY });\nconst res = await kob.request(\"POST\", \"/v1/wallets/{walletId}/debit\", { /* payload */ });\nconsole.log(res);"
          },
          {
            "lang": "Python",
            "label": "Python",
            "source": "from kangopenbanking import KangOpenBanking\n\nkob = KangOpenBanking(api_key=os.environ[\"KOB_API_KEY\"])\nres = kob.request(\"POST\", \"/v1/wallets/{walletId}/debit\", json={})\nprint(res)"
          },
          {
            "lang": "PHP",
            "label": "PHP",
            "source": "<?php\n$kob = new KangOpenBanking\\KangOpenBanking(getenv('KOB_API_KEY'));\n$res = $kob->request('POST', '/v1/wallets/{walletId}/debit', []);\nprint_r($res);"
          }
        ]
      }
    },
    "/v1/wallets/{walletId}/freeze": {
      "post": {
        "tags": [
          "Payment Gateway"
        ],
        "summary": "Freeze/unfreeze wallet",
        "operationId": "walletFreeze",
        "security": [
          {
            "bearerAuth": []
          }
        ],
        "parameters": [
          {
            "name": "walletId",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "$ref": "#/components/parameters/IdempotencyKey"
          },
          {
            "$ref": "#/components/parameters/RequestId"
          },
          {
            "$ref": "#/components/parameters/Traceparent"
          },
          {
            "$ref": "#/components/parameters/Tracestate"
          },
          {
            "$ref": "#/components/parameters/AcceptLanguage"
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "required": [
                  "action"
                ],
                "properties": {
                  "action": {
                    "type": "string",
                    "enum": [
                      "freeze",
                      "unfreeze"
                    ]
                  },
                  "reason": {
                    "type": "string"
                  }
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Wallet frozen/unfrozen",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "success": {
                      "type": "boolean",
                      "example": true
                    },
                    "message": {
                      "type": "string"
                    }
                  }
                },
                "example": {
                  "success": true,
                  "message": "string"
                }
              }
            },
            "headers": {
              "x-fapi-interaction-id": {
                "$ref": "#/components/headers/XFapiInteractionIdResponse"
              },
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/XRateLimitLimit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/XRateLimitRemaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/XRateLimitReset"
              },
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              },
              "X-Idempotent-Replay": {
                "$ref": "#/components/headers/X-Idempotent-Replay"
              },
              "X-Idempotency-Status": {
                "$ref": "#/components/headers/X-Idempotency-Status"
              },
              "traceparent": {
                "$ref": "#/components/headers/Traceparent"
              },
              "Content-Language": {
                "$ref": "#/components/headers/Content-Language"
              }
            }
          },
          "400": {
            "description": "Bad request",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              },
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                },
                "examples": {
                  "error": {
                    "$ref": "#/components/examples/ErrorBadRequest"
                  }
                }
              }
            },
            "headers": {
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/XRateLimitLimit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/XRateLimitRemaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/XRateLimitReset"
              },
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "403": {
            "$ref": "#/components/responses/Forbidden",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "404": {
            "$ref": "#/components/responses/NotFound",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "409": {
            "$ref": "#/components/responses/Conflict",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "429": {
            "$ref": "#/components/responses/TooManyRequests",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "500": {
            "$ref": "#/components/responses/InternalServerError",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          }
        },
        "x-codeSamples": [
          {
            "lang": "cURL",
            "label": "cURL",
            "source": "curl -X POST \"https://api.kangopenbanking.com/v1/wallets/{walletId}/freeze\" \\\n  -H \"Authorization: Bearer $KOB_ACCESS_TOKEN\" \\\n  -H \"Content-Type: application/json\" \\\n  -d '{}'"
          },
          {
            "lang": "JavaScript",
            "label": "Node.js",
            "source": "import { KangOpenBanking } from \"@kangopenbanking/sdk\";\n\nconst kob = new KangOpenBanking({ apiKey: process.env.KOB_API_KEY });\nconst res = await kob.request(\"POST\", \"/v1/wallets/{walletId}/freeze\", { /* payload */ });\nconsole.log(res);"
          },
          {
            "lang": "Python",
            "label": "Python",
            "source": "from kangopenbanking import KangOpenBanking\n\nkob = KangOpenBanking(api_key=os.environ[\"KOB_API_KEY\"])\nres = kob.request(\"POST\", \"/v1/wallets/{walletId}/freeze\", json={})\nprint(res)"
          },
          {
            "lang": "PHP",
            "label": "PHP",
            "source": "<?php\n$kob = new KangOpenBanking\\KangOpenBanking(getenv('KOB_API_KEY'));\n$res = $kob->request('POST', '/v1/wallets/{walletId}/freeze', []);\nprint_r($res);"
          }
        ]
      }
    },
    "/v1/wallets/{walletId}/statement": {
      "get": {
        "tags": [
          "Payment Gateway"
        ],
        "summary": "Wallet statement",
        "operationId": "walletStatement",
        "security": [
          {
            "bearerAuth": []
          }
        ],
        "parameters": [
          {
            "name": "walletId",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "from",
            "in": "query",
            "schema": {
              "type": "string",
              "format": "date"
            }
          },
          {
            "name": "to",
            "in": "query",
            "schema": {
              "type": "string",
              "format": "date"
            }
          },
          {
            "name": "limit",
            "in": "query",
            "schema": {
              "type": "integer",
              "default": 25,
              "maximum": 100
            },
            "description": "Items per page"
          },
          {
            "name": "offset",
            "in": "query",
            "schema": {
              "type": "integer",
              "default": 0
            },
            "description": "Items to skip"
          },
          {
            "name": "sort_by",
            "in": "query",
            "schema": {
              "type": "string",
              "default": "created_at"
            },
            "description": "Sort field"
          },
          {
            "name": "sort_order",
            "in": "query",
            "schema": {
              "type": "string",
              "enum": [
                "asc",
                "desc"
              ],
              "default": "desc"
            },
            "description": "Sort direction"
          },
          {
            "$ref": "#/components/parameters/StartingAfter"
          },
          {
            "$ref": "#/components/parameters/EndingBefore"
          },
          {
            "$ref": "#/components/parameters/RequestId"
          },
          {
            "$ref": "#/components/parameters/Traceparent"
          },
          {
            "$ref": "#/components/parameters/Tracestate"
          },
          {
            "$ref": "#/components/parameters/AcceptLanguage"
          }
        ],
        "responses": {
          "200": {
            "description": "Wallet transaction history",
            "content": {
              "application/json": {
                "schema": {
                  "allOf": [
                    {
                      "$ref": "#/components/schemas/PaginatedResponse"
                    },
                    {
                      "type": "object",
                      "properties": {
                        "data": {
                          "type": "array",
                          "items": {}
                        }
                      }
                    }
                  ]
                },
                "example": {
                  "data": [
                    {}
                  ],
                  "pagination": {
                    "page": 1,
                    "limit": 20,
                    "total": 150,
                    "has_next": true,
                    "next_cursor": "eyJpZCI6IjEyMyJ9"
                  },
                  "meta": {
                    "request_id": "550e8400-e29b-41d4-a716-446655440000",
                    "timestamp": "2025-03-27T12:00:00Z",
                    "api_version": "4.3.0"
                  }
                }
              }
            },
            "headers": {
              "x-fapi-interaction-id": {
                "$ref": "#/components/headers/XFapiInteractionIdResponse"
              },
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/XRateLimitLimit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/XRateLimitRemaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/XRateLimitReset"
              },
              "Cache-Control": {
                "$ref": "#/components/headers/CacheControl"
              },
              "ETag": {
                "$ref": "#/components/headers/ETag"
              },
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              },
              "traceparent": {
                "$ref": "#/components/headers/Traceparent"
              },
              "Content-Language": {
                "$ref": "#/components/headers/Content-Language"
              }
            }
          },
          "400": {
            "description": "Bad request",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              },
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                },
                "examples": {
                  "error": {
                    "$ref": "#/components/examples/ErrorBadRequest"
                  }
                }
              }
            },
            "headers": {
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/XRateLimitLimit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/XRateLimitRemaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/XRateLimitReset"
              },
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "403": {
            "$ref": "#/components/responses/Forbidden",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "404": {
            "$ref": "#/components/responses/NotFound",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "409": {
            "$ref": "#/components/responses/Conflict",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "429": {
            "$ref": "#/components/responses/TooManyRequests",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "500": {
            "$ref": "#/components/responses/InternalServerError",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          }
        },
        "x-codeSamples": [
          {
            "lang": "cURL",
            "label": "cURL",
            "source": "curl -X GET \"https://api.kangopenbanking.com/v1/wallets/{walletId}/statement\" \\\n  -H \"Authorization: Bearer $KOB_ACCESS_TOKEN\" \\\n  -H \"Content-Type: application/json\""
          },
          {
            "lang": "JavaScript",
            "label": "Node.js",
            "source": "import { KangOpenBanking } from \"@kangopenbanking/sdk\";\n\nconst kob = new KangOpenBanking({ apiKey: process.env.KOB_API_KEY });\nconst res = await kob.request(\"GET\", \"/v1/wallets/{walletId}/statement\");\nconsole.log(res);"
          },
          {
            "lang": "Python",
            "label": "Python",
            "source": "from kangopenbanking import KangOpenBanking\n\nkob = KangOpenBanking(api_key=os.environ[\"KOB_API_KEY\"])\nres = kob.request(\"GET\", \"/v1/wallets/{walletId}/statement\")\nprint(res)"
          },
          {
            "lang": "PHP",
            "label": "PHP",
            "source": "<?php\n$kob = new KangOpenBanking\\KangOpenBanking(getenv('KOB_API_KEY'));\n$res = $kob->request('GET', '/v1/wallets/{walletId}/statement');\nprint_r($res);"
          }
        ]
      }
    },
    "/v1/escrow": {
      "post": {
        "tags": [
          "Payment Gateway"
        ],
        "summary": "Create escrow hold",
        "operationId": "escrowCreate",
        "security": [
          {
            "bearerAuth": []
          }
        ],
        "parameters": [
          {
            "name": "Idempotency-Key",
            "in": "header",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid"
            },
            "description": "Required on all POST/PUT endpoints. Unique key for idempotent request processing (UUID v4 recommended). Keys expire after 24 hours."
          },
          {
            "$ref": "#/components/parameters/RequestId"
          },
          {
            "$ref": "#/components/parameters/Traceparent"
          },
          {
            "$ref": "#/components/parameters/Tracestate"
          },
          {
            "$ref": "#/components/parameters/AcceptLanguage"
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "required": [
                  "merchant_id",
                  "amount",
                  "currency"
                ],
                "properties": {
                  "merchant_id": {
                    "type": "string",
                    "format": "uuid"
                  },
                  "amount": {
                    "type": "string",
                    "pattern": "^[0-9]{1,15}$",
                    "description": "Represented as a string integer in the currency's minor unit (XAF has no subunits). Must be consistent with the currency field."
                  },
                  "currency": {
                    "type": "string",
                    "default": "XAF",
                    "enum": [
                      "XAF",
                      "XOF",
                      "USD",
                      "EUR",
                      "GBP",
                      "CNY",
                      "NGN",
                      "GHS",
                      "KES",
                      "ZAR"
                    ],
                    "description": "ISO 4217 currency code. Default is XAF (Central African CFA Franc)."
                  },
                  "description": {
                    "type": "string"
                  },
                  "release_conditions": {
                    "type": "object",
                    "description": "Structured conditions that must be satisfied before the escrow can be released",
                    "properties": {
                      "type": {
                        "type": "string",
                        "enum": [
                          "time_based",
                          "confirmation_based",
                          "milestone_based",
                          "manual"
                        ],
                        "description": "The type of release trigger"
                      },
                      "release_after_date": {
                        "type": "string",
                        "format": "date-time",
                        "description": "For time_based: UTC datetime after which auto-release is permitted"
                      },
                      "required_confirmations": {
                        "type": "integer",
                        "description": "For confirmation_based: number of parties that must confirm before release",
                        "minimum": 1,
                        "maximum": 10
                      },
                      "milestones": {
                        "type": "array",
                        "description": "For milestone_based: list of milestone descriptions that must be marked complete",
                        "items": {
                          "type": "object",
                          "properties": {
                            "id": {
                              "type": "string"
                            },
                            "description": {
                              "type": "string"
                            },
                            "completed": {
                              "type": "boolean",
                              "default": false
                            }
                          }
                        }
                      },
                      "human_readable_summary": {
                        "type": "string",
                        "description": "Plain English description of the release conditions for audit and display purposes"
                      }
                    },
                    "required": [
                      "type",
                      "human_readable_summary"
                    ]
                  },
                  "expires_at": {
                    "type": "string",
                    "format": "date-time"
                  }
                }
              }
            }
          }
        },
        "responses": {
          "201": {
            "description": "Escrow created",
            "content": {
              "application/json": {
                "schema": {
                  "allOf": [
                    {
                      "$ref": "#/components/schemas/StandardResponse"
                    },
                    {
                      "type": "object",
                      "properties": {
                        "data": {
                          "type": "object",
                          "properties": {
                            "id": {
                              "type": "string"
                            },
                            "amount": {
                              "type": "string",
                              "pattern": "^[0-9]{1,15}$",
                              "description": "Represented as a string integer in the currency's minor unit (XAF has no subunits). Must be consistent with the currency field."
                            },
                            "currency": {
                              "type": "string",
                              "enum": [
                                "XAF",
                                "XOF",
                                "USD",
                                "EUR",
                                "GBP",
                                "CNY",
                                "NGN",
                                "GHS",
                                "KES",
                                "ZAR"
                              ],
                              "default": "XAF",
                              "description": "ISO 4217 currency code. Default is XAF (Central African CFA Franc)."
                            },
                            "status": {
                              "type": "string",
                              "example": "active"
                            },
                            "created_at": {
                              "type": "string",
                              "format": "date-time"
                            }
                          }
                        }
                      }
                    }
                  ]
                },
                "example": {
                  "data": {
                    "id": "string",
                    "amount": "1000",
                    "currency": "XAF",
                    "status": "active",
                    "created_at": "2026-01-01T00:00:00Z"
                  },
                  "meta": {
                    "request_id": "550e8400-e29b-41d4-a716-446655440000",
                    "timestamp": "2025-03-27T12:00:00Z",
                    "api_version": "4.3.0"
                  }
                }
              }
            },
            "headers": {
              "x-fapi-interaction-id": {
                "$ref": "#/components/headers/XFapiInteractionIdResponse"
              },
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/XRateLimitLimit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/XRateLimitRemaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/XRateLimitReset"
              },
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              },
              "X-Idempotent-Replay": {
                "$ref": "#/components/headers/X-Idempotent-Replay"
              },
              "X-Idempotency-Status": {
                "$ref": "#/components/headers/X-Idempotency-Status"
              },
              "traceparent": {
                "$ref": "#/components/headers/Traceparent"
              },
              "Content-Language": {
                "$ref": "#/components/headers/Content-Language"
              }
            }
          },
          "400": {
            "description": "Bad request",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              },
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                },
                "examples": {
                  "error": {
                    "$ref": "#/components/examples/ErrorBadRequest"
                  }
                }
              }
            },
            "headers": {
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/XRateLimitLimit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/XRateLimitRemaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/XRateLimitReset"
              },
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "403": {
            "$ref": "#/components/responses/Forbidden",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "404": {
            "$ref": "#/components/responses/NotFound",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "409": {
            "$ref": "#/components/responses/Conflict",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "429": {
            "$ref": "#/components/responses/TooManyRequests",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "500": {
            "$ref": "#/components/responses/InternalServerError",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          }
        },
        "x-codeSamples": [
          {
            "lang": "cURL",
            "label": "cURL",
            "source": "curl -X POST \"https://api.kangopenbanking.com/v1/escrow\" \\\n  -H \"Authorization: Bearer $KOB_ACCESS_TOKEN\" \\\n  -H \"Content-Type: application/json\" \\\n  -d '{}'"
          },
          {
            "lang": "JavaScript",
            "label": "Node.js",
            "source": "import { KangOpenBanking } from \"@kangopenbanking/sdk\";\n\nconst kob = new KangOpenBanking({ apiKey: process.env.KOB_API_KEY });\nconst res = await kob.request(\"POST\", \"/v1/escrow\", { /* payload */ });\nconsole.log(res);"
          },
          {
            "lang": "Python",
            "label": "Python",
            "source": "from kangopenbanking import KangOpenBanking\n\nkob = KangOpenBanking(api_key=os.environ[\"KOB_API_KEY\"])\nres = kob.request(\"POST\", \"/v1/escrow\", json={})\nprint(res)"
          },
          {
            "lang": "PHP",
            "label": "PHP",
            "source": "<?php\n$kob = new KangOpenBanking\\KangOpenBanking(getenv('KOB_API_KEY'));\n$res = $kob->request('POST', '/v1/escrow', []);\nprint_r($res);"
          }
        ]
      },
      "get": {
        "tags": [
          "Payment Gateway"
        ],
        "summary": "List escrow holds",
        "operationId": "escrowList",
        "security": [
          {
            "bearerAuth": []
          }
        ],
        "parameters": [
          {
            "name": "merchant_id",
            "in": "query",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "status",
            "in": "query",
            "schema": {
              "type": "string",
              "enum": [
                "active",
                "released",
                "refunded",
                "frozen",
                "expired"
              ]
            }
          },
          {
            "name": "limit",
            "in": "query",
            "schema": {
              "type": "integer",
              "default": 25,
              "maximum": 100
            },
            "description": "Items per page"
          },
          {
            "name": "offset",
            "in": "query",
            "schema": {
              "type": "integer",
              "default": 0
            },
            "description": "Items to skip"
          },
          {
            "name": "sort_by",
            "in": "query",
            "schema": {
              "type": "string",
              "default": "created_at"
            },
            "description": "Sort field"
          },
          {
            "name": "sort_order",
            "in": "query",
            "schema": {
              "type": "string",
              "enum": [
                "asc",
                "desc"
              ],
              "default": "desc"
            },
            "description": "Sort direction"
          },
          {
            "$ref": "#/components/parameters/StartingAfter"
          },
          {
            "$ref": "#/components/parameters/EndingBefore"
          },
          {
            "$ref": "#/components/parameters/RequestId"
          },
          {
            "$ref": "#/components/parameters/Traceparent"
          },
          {
            "$ref": "#/components/parameters/Tracestate"
          },
          {
            "$ref": "#/components/parameters/AcceptLanguage"
          }
        ],
        "responses": {
          "200": {
            "description": "Escrow holds",
            "content": {
              "application/json": {
                "schema": {
                  "allOf": [
                    {
                      "$ref": "#/components/schemas/PaginatedResponse"
                    },
                    {
                      "type": "object",
                      "properties": {
                        "data": {
                          "type": "array",
                          "items": {}
                        }
                      }
                    }
                  ]
                },
                "example": {
                  "data": [
                    {}
                  ],
                  "pagination": {
                    "page": 1,
                    "limit": 20,
                    "total": 150,
                    "has_next": true,
                    "next_cursor": "eyJpZCI6IjEyMyJ9"
                  },
                  "meta": {
                    "request_id": "550e8400-e29b-41d4-a716-446655440000",
                    "timestamp": "2025-03-27T12:00:00Z",
                    "api_version": "4.3.0"
                  }
                }
              }
            },
            "headers": {
              "x-fapi-interaction-id": {
                "$ref": "#/components/headers/XFapiInteractionIdResponse"
              },
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/XRateLimitLimit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/XRateLimitRemaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/XRateLimitReset"
              },
              "Cache-Control": {
                "$ref": "#/components/headers/CacheControl"
              },
              "ETag": {
                "$ref": "#/components/headers/ETag"
              },
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              },
              "traceparent": {
                "$ref": "#/components/headers/Traceparent"
              },
              "Content-Language": {
                "$ref": "#/components/headers/Content-Language"
              }
            }
          },
          "400": {
            "description": "Bad request",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              },
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                },
                "examples": {
                  "error": {
                    "$ref": "#/components/examples/ErrorBadRequest"
                  }
                }
              }
            },
            "headers": {
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/XRateLimitLimit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/XRateLimitRemaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/XRateLimitReset"
              },
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "403": {
            "$ref": "#/components/responses/Forbidden",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "404": {
            "$ref": "#/components/responses/NotFound",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "409": {
            "$ref": "#/components/responses/Conflict",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "429": {
            "$ref": "#/components/responses/TooManyRequests",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "500": {
            "$ref": "#/components/responses/InternalServerError",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          }
        },
        "x-codeSamples": [
          {
            "lang": "cURL",
            "label": "cURL",
            "source": "curl -X GET \"https://api.kangopenbanking.com/v1/escrow\" \\\n  -H \"Authorization: Bearer $KOB_ACCESS_TOKEN\" \\\n  -H \"Content-Type: application/json\""
          },
          {
            "lang": "JavaScript",
            "label": "Node.js",
            "source": "import { KangOpenBanking } from \"@kangopenbanking/sdk\";\n\nconst kob = new KangOpenBanking({ apiKey: process.env.KOB_API_KEY });\nconst res = await kob.request(\"GET\", \"/v1/escrow\");\nconsole.log(res);"
          },
          {
            "lang": "Python",
            "label": "Python",
            "source": "from kangopenbanking import KangOpenBanking\n\nkob = KangOpenBanking(api_key=os.environ[\"KOB_API_KEY\"])\nres = kob.request(\"GET\", \"/v1/escrow\")\nprint(res)"
          },
          {
            "lang": "PHP",
            "label": "PHP",
            "source": "<?php\n$kob = new KangOpenBanking\\KangOpenBanking(getenv('KOB_API_KEY'));\n$res = $kob->request('GET', '/v1/escrow');\nprint_r($res);"
          }
        ]
      }
    },
    "/v1/escrow/{escrowId}/fund": {
      "post": {
        "tags": [
          "Payment Gateway"
        ],
        "summary": "Fund escrow",
        "operationId": "escrowFund",
        "security": [
          {
            "bearerAuth": []
          }
        ],
        "parameters": [
          {
            "name": "escrowId",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "Idempotency-Key",
            "in": "header",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid"
            },
            "description": "Required on all POST/PUT endpoints. Unique key for idempotent request processing (UUID v4 recommended). Keys expire after 24 hours."
          },
          {
            "$ref": "#/components/parameters/RequestId"
          },
          {
            "$ref": "#/components/parameters/Traceparent"
          },
          {
            "$ref": "#/components/parameters/Tracestate"
          },
          {
            "$ref": "#/components/parameters/AcceptLanguage"
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "required": [
                  "amount"
                ],
                "properties": {
                  "amount": {
                    "type": "string",
                    "pattern": "^[0-9]{1,15}$",
                    "description": "Represented as a string integer in the currency's minor unit (XAF has no subunits)."
                  },
                  "source_wallet_id": {
                    "type": "string"
                  }
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Escrow funded",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "success": {
                      "type": "boolean",
                      "example": true
                    },
                    "message": {
                      "type": "string"
                    }
                  }
                },
                "example": {
                  "success": true,
                  "message": "string"
                }
              }
            },
            "headers": {
              "x-fapi-interaction-id": {
                "$ref": "#/components/headers/XFapiInteractionIdResponse"
              },
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/XRateLimitLimit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/XRateLimitRemaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/XRateLimitReset"
              },
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              },
              "X-Idempotent-Replay": {
                "$ref": "#/components/headers/X-Idempotent-Replay"
              },
              "X-Idempotency-Status": {
                "$ref": "#/components/headers/X-Idempotency-Status"
              },
              "traceparent": {
                "$ref": "#/components/headers/Traceparent"
              },
              "Content-Language": {
                "$ref": "#/components/headers/Content-Language"
              }
            }
          },
          "400": {
            "description": "Bad request",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              },
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                },
                "examples": {
                  "error": {
                    "$ref": "#/components/examples/ErrorBadRequest"
                  }
                }
              }
            },
            "headers": {
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/XRateLimitLimit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/XRateLimitRemaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/XRateLimitReset"
              },
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "403": {
            "$ref": "#/components/responses/Forbidden",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "404": {
            "$ref": "#/components/responses/NotFound",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "409": {
            "$ref": "#/components/responses/Conflict",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "429": {
            "$ref": "#/components/responses/TooManyRequests",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "500": {
            "$ref": "#/components/responses/InternalServerError",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          }
        },
        "x-codeSamples": [
          {
            "lang": "cURL",
            "label": "cURL",
            "source": "curl -X POST \"https://api.kangopenbanking.com/v1/escrow/{escrowId}/fund\" \\\n  -H \"Authorization: Bearer $KOB_ACCESS_TOKEN\" \\\n  -H \"Content-Type: application/json\" \\\n  -d '{}'"
          },
          {
            "lang": "JavaScript",
            "label": "Node.js",
            "source": "import { KangOpenBanking } from \"@kangopenbanking/sdk\";\n\nconst kob = new KangOpenBanking({ apiKey: process.env.KOB_API_KEY });\nconst res = await kob.request(\"POST\", \"/v1/escrow/{escrowId}/fund\", { /* payload */ });\nconsole.log(res);"
          },
          {
            "lang": "Python",
            "label": "Python",
            "source": "from kangopenbanking import KangOpenBanking\n\nkob = KangOpenBanking(api_key=os.environ[\"KOB_API_KEY\"])\nres = kob.request(\"POST\", \"/v1/escrow/{escrowId}/fund\", json={})\nprint(res)"
          },
          {
            "lang": "PHP",
            "label": "PHP",
            "source": "<?php\n$kob = new KangOpenBanking\\KangOpenBanking(getenv('KOB_API_KEY'));\n$res = $kob->request('POST', '/v1/escrow/{escrowId}/fund', []);\nprint_r($res);"
          }
        ]
      }
    },
    "/v1/escrow/{escrowId}/release": {
      "post": {
        "tags": [
          "Payment Gateway"
        ],
        "summary": "Release escrow",
        "operationId": "escrowRelease",
        "security": [
          {
            "bearerAuth": []
          }
        ],
        "parameters": [
          {
            "name": "escrowId",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "Idempotency-Key",
            "in": "header",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid"
            },
            "description": "Required on all POST/PUT endpoints. Unique key for idempotent request processing (UUID v4 recommended). Keys expire after 24 hours."
          },
          {
            "$ref": "#/components/parameters/RequestId"
          },
          {
            "$ref": "#/components/parameters/Traceparent"
          },
          {
            "$ref": "#/components/parameters/Tracestate"
          },
          {
            "$ref": "#/components/parameters/AcceptLanguage"
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "amount": {
                    "type": "string",
                    "description": "Partial release amount (omit for full) Represented as a string integer in the currency's minor unit (XAF has no subunits).",
                    "pattern": "^[0-9]{1,15}$"
                  },
                  "recipient_wallet_id": {
                    "type": "string"
                  }
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Escrow released",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "success": {
                      "type": "boolean",
                      "example": true
                    },
                    "message": {
                      "type": "string"
                    }
                  }
                },
                "example": {
                  "success": true,
                  "message": "string"
                }
              }
            },
            "headers": {
              "x-fapi-interaction-id": {
                "$ref": "#/components/headers/XFapiInteractionIdResponse"
              },
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/XRateLimitLimit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/XRateLimitRemaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/XRateLimitReset"
              },
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              },
              "X-Idempotent-Replay": {
                "$ref": "#/components/headers/X-Idempotent-Replay"
              },
              "X-Idempotency-Status": {
                "$ref": "#/components/headers/X-Idempotency-Status"
              },
              "traceparent": {
                "$ref": "#/components/headers/Traceparent"
              },
              "Content-Language": {
                "$ref": "#/components/headers/Content-Language"
              }
            }
          },
          "400": {
            "description": "Bad request",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              },
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                },
                "examples": {
                  "error": {
                    "$ref": "#/components/examples/ErrorBadRequest"
                  }
                }
              }
            },
            "headers": {
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/XRateLimitLimit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/XRateLimitRemaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/XRateLimitReset"
              },
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "403": {
            "$ref": "#/components/responses/Forbidden",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "404": {
            "$ref": "#/components/responses/NotFound",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "409": {
            "$ref": "#/components/responses/Conflict",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "429": {
            "$ref": "#/components/responses/TooManyRequests",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "500": {
            "$ref": "#/components/responses/InternalServerError",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          }
        },
        "x-codeSamples": [
          {
            "lang": "cURL",
            "label": "cURL",
            "source": "curl -X POST \"https://api.kangopenbanking.com/v1/escrow/{escrowId}/release\" \\\n  -H \"Authorization: Bearer $KOB_ACCESS_TOKEN\" \\\n  -H \"Content-Type: application/json\" \\\n  -d '{}'"
          },
          {
            "lang": "JavaScript",
            "label": "Node.js",
            "source": "import { KangOpenBanking } from \"@kangopenbanking/sdk\";\n\nconst kob = new KangOpenBanking({ apiKey: process.env.KOB_API_KEY });\nconst res = await kob.request(\"POST\", \"/v1/escrow/{escrowId}/release\", { /* payload */ });\nconsole.log(res);"
          },
          {
            "lang": "Python",
            "label": "Python",
            "source": "from kangopenbanking import KangOpenBanking\n\nkob = KangOpenBanking(api_key=os.environ[\"KOB_API_KEY\"])\nres = kob.request(\"POST\", \"/v1/escrow/{escrowId}/release\", json={})\nprint(res)"
          },
          {
            "lang": "PHP",
            "label": "PHP",
            "source": "<?php\n$kob = new KangOpenBanking\\KangOpenBanking(getenv('KOB_API_KEY'));\n$res = $kob->request('POST', '/v1/escrow/{escrowId}/release', []);\nprint_r($res);"
          }
        ]
      }
    },
    "/v1/escrow/{escrowId}/refund": {
      "post": {
        "tags": [
          "Payment Gateway"
        ],
        "summary": "Refund escrow",
        "operationId": "escrowRefund",
        "security": [
          {
            "bearerAuth": []
          }
        ],
        "parameters": [
          {
            "name": "escrowId",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "Idempotency-Key",
            "in": "header",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid"
            },
            "description": "Required on all POST/PUT endpoints. Unique key for idempotent request processing (UUID v4 recommended). Keys expire after 24 hours."
          },
          {
            "$ref": "#/components/parameters/RequestId"
          },
          {
            "$ref": "#/components/parameters/Traceparent"
          },
          {
            "$ref": "#/components/parameters/Tracestate"
          },
          {
            "$ref": "#/components/parameters/AcceptLanguage"
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "reason": {
                    "type": "string"
                  }
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Escrow refunded",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "success": {
                      "type": "boolean",
                      "example": true
                    },
                    "message": {
                      "type": "string"
                    }
                  }
                },
                "example": {
                  "success": true,
                  "message": "string"
                }
              }
            },
            "headers": {
              "x-fapi-interaction-id": {
                "$ref": "#/components/headers/XFapiInteractionIdResponse"
              },
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/XRateLimitLimit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/XRateLimitRemaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/XRateLimitReset"
              },
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              },
              "X-Idempotent-Replay": {
                "$ref": "#/components/headers/X-Idempotent-Replay"
              },
              "X-Idempotency-Status": {
                "$ref": "#/components/headers/X-Idempotency-Status"
              },
              "traceparent": {
                "$ref": "#/components/headers/Traceparent"
              },
              "Content-Language": {
                "$ref": "#/components/headers/Content-Language"
              }
            }
          },
          "400": {
            "description": "Bad request",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              },
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                },
                "examples": {
                  "error": {
                    "$ref": "#/components/examples/ErrorBadRequest"
                  }
                }
              }
            },
            "headers": {
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/XRateLimitLimit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/XRateLimitRemaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/XRateLimitReset"
              },
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "403": {
            "$ref": "#/components/responses/Forbidden",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "404": {
            "$ref": "#/components/responses/NotFound",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "409": {
            "$ref": "#/components/responses/Conflict",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "429": {
            "$ref": "#/components/responses/TooManyRequests",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "500": {
            "$ref": "#/components/responses/InternalServerError",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          }
        },
        "x-codeSamples": [
          {
            "lang": "cURL",
            "label": "cURL",
            "source": "curl -X POST \"https://api.kangopenbanking.com/v1/escrow/{escrowId}/refund\" \\\n  -H \"Authorization: Bearer $KOB_ACCESS_TOKEN\" \\\n  -H \"Content-Type: application/json\" \\\n  -d '{}'"
          },
          {
            "lang": "JavaScript",
            "label": "Node.js",
            "source": "import { KangOpenBanking } from \"@kangopenbanking/sdk\";\n\nconst kob = new KangOpenBanking({ apiKey: process.env.KOB_API_KEY });\nconst res = await kob.request(\"POST\", \"/v1/escrow/{escrowId}/refund\", { /* payload */ });\nconsole.log(res);"
          },
          {
            "lang": "Python",
            "label": "Python",
            "source": "from kangopenbanking import KangOpenBanking\n\nkob = KangOpenBanking(api_key=os.environ[\"KOB_API_KEY\"])\nres = kob.request(\"POST\", \"/v1/escrow/{escrowId}/refund\", json={})\nprint(res)"
          },
          {
            "lang": "PHP",
            "label": "PHP",
            "source": "<?php\n$kob = new KangOpenBanking\\KangOpenBanking(getenv('KOB_API_KEY'));\n$res = $kob->request('POST', '/v1/escrow/{escrowId}/refund', []);\nprint_r($res);"
          }
        ]
      }
    },
    "/v1/escrow/{escrowId}/freeze": {
      "post": {
        "tags": [
          "Payment Gateway"
        ],
        "summary": "Freeze escrow",
        "operationId": "escrowFreeze",
        "security": [
          {
            "bearerAuth": []
          }
        ],
        "parameters": [
          {
            "name": "escrowId",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "$ref": "#/components/parameters/IdempotencyKey"
          },
          {
            "$ref": "#/components/parameters/RequestId"
          },
          {
            "$ref": "#/components/parameters/Traceparent"
          },
          {
            "$ref": "#/components/parameters/Tracestate"
          },
          {
            "$ref": "#/components/parameters/AcceptLanguage"
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "required": [
                  "action"
                ],
                "properties": {
                  "action": {
                    "type": "string",
                    "enum": [
                      "freeze",
                      "unfreeze"
                    ]
                  },
                  "reason": {
                    "type": "string"
                  }
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Escrow frozen/unfrozen",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "success": {
                      "type": "boolean",
                      "example": true
                    },
                    "message": {
                      "type": "string"
                    }
                  }
                },
                "example": {
                  "success": true,
                  "message": "string"
                }
              }
            },
            "headers": {
              "x-fapi-interaction-id": {
                "$ref": "#/components/headers/XFapiInteractionIdResponse"
              },
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/XRateLimitLimit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/XRateLimitRemaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/XRateLimitReset"
              },
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              },
              "X-Idempotent-Replay": {
                "$ref": "#/components/headers/X-Idempotent-Replay"
              },
              "X-Idempotency-Status": {
                "$ref": "#/components/headers/X-Idempotency-Status"
              },
              "traceparent": {
                "$ref": "#/components/headers/Traceparent"
              },
              "Content-Language": {
                "$ref": "#/components/headers/Content-Language"
              }
            }
          },
          "400": {
            "description": "Bad request",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              },
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                },
                "examples": {
                  "error": {
                    "$ref": "#/components/examples/ErrorBadRequest"
                  }
                }
              }
            },
            "headers": {
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/XRateLimitLimit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/XRateLimitRemaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/XRateLimitReset"
              },
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "403": {
            "$ref": "#/components/responses/Forbidden",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "404": {
            "$ref": "#/components/responses/NotFound",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "409": {
            "$ref": "#/components/responses/Conflict",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "429": {
            "$ref": "#/components/responses/TooManyRequests",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "500": {
            "$ref": "#/components/responses/InternalServerError",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          }
        },
        "x-codeSamples": [
          {
            "lang": "cURL",
            "label": "cURL",
            "source": "curl -X POST \"https://api.kangopenbanking.com/v1/escrow/{escrowId}/freeze\" \\\n  -H \"Authorization: Bearer $KOB_ACCESS_TOKEN\" \\\n  -H \"Content-Type: application/json\" \\\n  -d '{}'"
          },
          {
            "lang": "JavaScript",
            "label": "Node.js",
            "source": "import { KangOpenBanking } from \"@kangopenbanking/sdk\";\n\nconst kob = new KangOpenBanking({ apiKey: process.env.KOB_API_KEY });\nconst res = await kob.request(\"POST\", \"/v1/escrow/{escrowId}/freeze\", { /* payload */ });\nconsole.log(res);"
          },
          {
            "lang": "Python",
            "label": "Python",
            "source": "from kangopenbanking import KangOpenBanking\n\nkob = KangOpenBanking(api_key=os.environ[\"KOB_API_KEY\"])\nres = kob.request(\"POST\", \"/v1/escrow/{escrowId}/freeze\", json={})\nprint(res)"
          },
          {
            "lang": "PHP",
            "label": "PHP",
            "source": "<?php\n$kob = new KangOpenBanking\\KangOpenBanking(getenv('KOB_API_KEY'));\n$res = $kob->request('POST', '/v1/escrow/{escrowId}/freeze', []);\nprint_r($res);"
          }
        ]
      }
    },
    "/v1/compliance/screen": {
      "post": {
        "tags": [
          "KYC & Compliance"
        ],
        "summary": "Pre-payout compliance screen",
        "description": "Evaluate transaction against KYC risk scores, sanctions, PEP status, and velocity limits. Returns approve/review/deny.",
        "operationId": "complianceScreen",
        "security": [
          {
            "bearerAuth": []
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "required": [
                  "user_id",
                  "amount",
                  "currency"
                ],
                "properties": {
                  "user_id": {
                    "type": "string",
                    "format": "uuid"
                  },
                  "amount": {
                    "type": "string",
                    "pattern": "^[0-9]{1,15}$",
                    "description": "Represented as a string integer in the currency's minor unit (XAF has no subunits). Must be consistent with the currency field."
                  },
                  "currency": {
                    "type": "string",
                    "enum": [
                      "XAF",
                      "XOF",
                      "USD",
                      "EUR",
                      "GBP",
                      "CNY",
                      "NGN",
                      "GHS",
                      "KES",
                      "ZAR"
                    ],
                    "default": "XAF",
                    "description": "ISO 4217 currency code. Default is XAF (Central African CFA Franc)."
                  },
                  "destination_type": {
                    "type": "string"
                  },
                  "destination_country": {
                    "type": "string"
                  }
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Screening decision",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "decision": {
                      "type": "string",
                      "enum": [
                        "approve",
                        "review",
                        "deny"
                      ]
                    },
                    "risk_score": {
                      "type": "integer"
                    },
                    "checks": {
                      "type": "object"
                    }
                  }
                },
                "example": {
                  "decision": "approve",
                  "risk_score": 0,
                  "checks": {}
                }
              }
            },
            "headers": {
              "x-fapi-interaction-id": {
                "$ref": "#/components/headers/XFapiInteractionIdResponse"
              },
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/XRateLimitLimit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/XRateLimitRemaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/XRateLimitReset"
              },
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              },
              "traceparent": {
                "$ref": "#/components/headers/Traceparent"
              },
              "Content-Language": {
                "$ref": "#/components/headers/Content-Language"
              }
            }
          },
          "400": {
            "description": "Bad request",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              },
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                },
                "examples": {
                  "error": {
                    "$ref": "#/components/examples/ErrorBadRequest"
                  }
                }
              }
            },
            "headers": {
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/XRateLimitLimit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/XRateLimitRemaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/XRateLimitReset"
              },
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "403": {
            "$ref": "#/components/responses/Forbidden",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "404": {
            "$ref": "#/components/responses/NotFound",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "409": {
            "$ref": "#/components/responses/Conflict",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "429": {
            "$ref": "#/components/responses/TooManyRequests",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "500": {
            "$ref": "#/components/responses/InternalServerError",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          }
        },
        "parameters": [
          {
            "$ref": "#/components/parameters/RequestId"
          },
          {
            "$ref": "#/components/parameters/Traceparent"
          },
          {
            "$ref": "#/components/parameters/Tracestate"
          },
          {
            "$ref": "#/components/parameters/AcceptLanguage"
          }
        ],
        "x-codeSamples": [
          {
            "lang": "cURL",
            "label": "cURL",
            "source": "curl -X POST \"https://api.kangopenbanking.com/v1/compliance/screen\" \\\n  -H \"Authorization: Bearer $KOB_ACCESS_TOKEN\" \\\n  -H \"Content-Type: application/json\" \\\n  -d '{}'"
          },
          {
            "lang": "JavaScript",
            "label": "Node.js",
            "source": "import { KangOpenBanking } from \"@kangopenbanking/sdk\";\n\nconst kob = new KangOpenBanking({ apiKey: process.env.KOB_API_KEY });\nconst res = await kob.request(\"POST\", \"/v1/compliance/screen\", { /* payload */ });\nconsole.log(res);"
          },
          {
            "lang": "Python",
            "label": "Python",
            "source": "from kangopenbanking import KangOpenBanking\n\nkob = KangOpenBanking(api_key=os.environ[\"KOB_API_KEY\"])\nres = kob.request(\"POST\", \"/v1/compliance/screen\", json={})\nprint(res)"
          },
          {
            "lang": "PHP",
            "label": "PHP",
            "source": "<?php\n$kob = new KangOpenBanking\\KangOpenBanking(getenv('KOB_API_KEY'));\n$res = $kob->request('POST', '/v1/compliance/screen', []);\nprint_r($res);"
          }
        ]
      }
    },
    "/v1/compliance/sar": {
      "post": {
        "tags": [
          "KYC & Compliance"
        ],
        "summary": "File SAR",
        "description": "File a Suspicious Activity Report.",
        "operationId": "sarFile",
        "security": [
          {
            "bearerAuth": []
          }
        ],
        "parameters": [
          {
            "name": "Idempotency-Key",
            "in": "header",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid"
            },
            "description": "Required on all POST/PUT endpoints. Unique key for idempotent request processing (UUID v4 recommended). Keys expire after 24 hours."
          },
          {
            "$ref": "#/components/parameters/RequestId"
          },
          {
            "$ref": "#/components/parameters/Traceparent"
          },
          {
            "$ref": "#/components/parameters/Tracestate"
          },
          {
            "$ref": "#/components/parameters/AcceptLanguage"
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "required": [
                  "subject_user_id",
                  "activity_type",
                  "description"
                ],
                "properties": {
                  "subject_user_id": {
                    "type": "string",
                    "format": "uuid"
                  },
                  "activity_type": {
                    "type": "string"
                  },
                  "description": {
                    "type": "string"
                  },
                  "amount": {
                    "type": "string",
                    "pattern": "^[0-9]{1,15}$",
                    "description": "Represented as a string integer in the currency's minor unit (XAF has no subunits). Must be consistent with the currency field."
                  },
                  "currency": {
                    "type": "string",
                    "enum": [
                      "XAF",
                      "XOF",
                      "USD",
                      "EUR",
                      "GBP",
                      "CNY",
                      "NGN",
                      "GHS",
                      "KES",
                      "ZAR"
                    ],
                    "default": "XAF",
                    "description": "ISO 4217 currency code. Default is XAF (Central African CFA Franc)."
                  }
                }
              }
            }
          }
        },
        "responses": {
          "201": {
            "description": "SAR filed",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "id": {
                      "type": "string",
                      "format": "uuid"
                    },
                    "status": {
                      "type": "string",
                      "example": "filed"
                    },
                    "reference": {
                      "type": "string"
                    },
                    "created_at": {
                      "type": "string",
                      "format": "date-time"
                    }
                  }
                },
                "example": {
                  "id": "00000000-0000-4000-8000-000000000000",
                  "status": "filed",
                  "reference": "string",
                  "created_at": "2026-01-01T00:00:00Z"
                }
              }
            },
            "headers": {
              "x-fapi-interaction-id": {
                "$ref": "#/components/headers/XFapiInteractionIdResponse"
              },
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/XRateLimitLimit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/XRateLimitRemaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/XRateLimitReset"
              },
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              },
              "traceparent": {
                "$ref": "#/components/headers/Traceparent"
              },
              "Content-Language": {
                "$ref": "#/components/headers/Content-Language"
              }
            }
          },
          "400": {
            "description": "Bad request",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              },
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                },
                "examples": {
                  "error": {
                    "$ref": "#/components/examples/ErrorBadRequest"
                  }
                }
              }
            },
            "headers": {
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/XRateLimitLimit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/XRateLimitRemaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/XRateLimitReset"
              },
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "403": {
            "$ref": "#/components/responses/Forbidden",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "404": {
            "$ref": "#/components/responses/NotFound",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "409": {
            "$ref": "#/components/responses/Conflict",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "429": {
            "$ref": "#/components/responses/TooManyRequests",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "500": {
            "$ref": "#/components/responses/InternalServerError",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          }
        },
        "x-codeSamples": [
          {
            "lang": "cURL",
            "label": "cURL",
            "source": "curl -X POST \"https://api.kangopenbanking.com/v1/compliance/sar\" \\\n  -H \"Authorization: Bearer $KOB_ACCESS_TOKEN\" \\\n  -H \"Content-Type: application/json\" \\\n  -d '{}'"
          },
          {
            "lang": "JavaScript",
            "label": "Node.js",
            "source": "import { KangOpenBanking } from \"@kangopenbanking/sdk\";\n\nconst kob = new KangOpenBanking({ apiKey: process.env.KOB_API_KEY });\nconst res = await kob.request(\"POST\", \"/v1/compliance/sar\", { /* payload */ });\nconsole.log(res);"
          },
          {
            "lang": "Python",
            "label": "Python",
            "source": "from kangopenbanking import KangOpenBanking\n\nkob = KangOpenBanking(api_key=os.environ[\"KOB_API_KEY\"])\nres = kob.request(\"POST\", \"/v1/compliance/sar\", json={})\nprint(res)"
          },
          {
            "lang": "PHP",
            "label": "PHP",
            "source": "<?php\n$kob = new KangOpenBanking\\KangOpenBanking(getenv('KOB_API_KEY'));\n$res = $kob->request('POST', '/v1/compliance/sar', []);\nprint_r($res);"
          }
        ]
      },
      "get": {
        "tags": [
          "KYC & Compliance"
        ],
        "summary": "List SARs",
        "operationId": "sarList",
        "security": [
          {
            "bearerAuth": []
          }
        ],
        "parameters": [
          {
            "name": "status",
            "in": "query",
            "schema": {
              "type": "string",
              "enum": [
                "draft",
                "filed",
                "under_review",
                "escalated",
                "submitted",
                "closed"
              ]
            }
          },
          {
            "name": "limit",
            "in": "query",
            "schema": {
              "type": "integer",
              "default": 25,
              "maximum": 100
            },
            "description": "Items per page"
          },
          {
            "name": "offset",
            "in": "query",
            "schema": {
              "type": "integer",
              "default": 0
            },
            "description": "Items to skip"
          },
          {
            "name": "sort_by",
            "in": "query",
            "schema": {
              "type": "string",
              "default": "created_at"
            },
            "description": "Sort field"
          },
          {
            "name": "sort_order",
            "in": "query",
            "schema": {
              "type": "string",
              "enum": [
                "asc",
                "desc"
              ],
              "default": "desc"
            },
            "description": "Sort direction"
          },
          {
            "$ref": "#/components/parameters/StartingAfter"
          },
          {
            "$ref": "#/components/parameters/EndingBefore"
          },
          {
            "$ref": "#/components/parameters/RequestId"
          },
          {
            "$ref": "#/components/parameters/Traceparent"
          },
          {
            "$ref": "#/components/parameters/Tracestate"
          },
          {
            "$ref": "#/components/parameters/AcceptLanguage"
          }
        ],
        "responses": {
          "200": {
            "description": "SAR list",
            "content": {
              "application/json": {
                "schema": {
                  "allOf": [
                    {
                      "$ref": "#/components/schemas/PaginatedResponse"
                    },
                    {
                      "type": "object",
                      "properties": {
                        "data": {
                          "type": "array",
                          "items": {}
                        }
                      }
                    }
                  ]
                },
                "example": {
                  "data": [
                    {}
                  ],
                  "pagination": {
                    "page": 1,
                    "limit": 20,
                    "total": 150,
                    "has_next": true,
                    "next_cursor": "eyJpZCI6IjEyMyJ9"
                  },
                  "meta": {
                    "request_id": "550e8400-e29b-41d4-a716-446655440000",
                    "timestamp": "2025-03-27T12:00:00Z",
                    "api_version": "4.3.0"
                  }
                }
              }
            },
            "headers": {
              "x-fapi-interaction-id": {
                "$ref": "#/components/headers/XFapiInteractionIdResponse"
              },
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/XRateLimitLimit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/XRateLimitRemaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/XRateLimitReset"
              },
              "Cache-Control": {
                "$ref": "#/components/headers/CacheControl"
              },
              "ETag": {
                "$ref": "#/components/headers/ETag"
              },
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              },
              "traceparent": {
                "$ref": "#/components/headers/Traceparent"
              },
              "Content-Language": {
                "$ref": "#/components/headers/Content-Language"
              }
            }
          },
          "400": {
            "description": "Bad request",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              },
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                },
                "examples": {
                  "error": {
                    "$ref": "#/components/examples/ErrorBadRequest"
                  }
                }
              }
            },
            "headers": {
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/XRateLimitLimit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/XRateLimitRemaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/XRateLimitReset"
              },
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "403": {
            "$ref": "#/components/responses/Forbidden",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "404": {
            "$ref": "#/components/responses/NotFound",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "409": {
            "$ref": "#/components/responses/Conflict",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "429": {
            "$ref": "#/components/responses/TooManyRequests",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "500": {
            "$ref": "#/components/responses/InternalServerError",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          }
        },
        "x-codeSamples": [
          {
            "lang": "cURL",
            "label": "cURL",
            "source": "curl -X GET \"https://api.kangopenbanking.com/v1/compliance/sar\" \\\n  -H \"Authorization: Bearer $KOB_ACCESS_TOKEN\" \\\n  -H \"Content-Type: application/json\""
          },
          {
            "lang": "JavaScript",
            "label": "Node.js",
            "source": "import { KangOpenBanking } from \"@kangopenbanking/sdk\";\n\nconst kob = new KangOpenBanking({ apiKey: process.env.KOB_API_KEY });\nconst res = await kob.request(\"GET\", \"/v1/compliance/sar\");\nconsole.log(res);"
          },
          {
            "lang": "Python",
            "label": "Python",
            "source": "from kangopenbanking import KangOpenBanking\n\nkob = KangOpenBanking(api_key=os.environ[\"KOB_API_KEY\"])\nres = kob.request(\"GET\", \"/v1/compliance/sar\")\nprint(res)"
          },
          {
            "lang": "PHP",
            "label": "PHP",
            "source": "<?php\n$kob = new KangOpenBanking\\KangOpenBanking(getenv('KOB_API_KEY'));\n$res = $kob->request('GET', '/v1/compliance/sar');\nprint_r($res);"
          }
        ]
      }
    },
    "/v1/compliance/sar/{sarId}/review": {
      "post": {
        "tags": [
          "KYC & Compliance"
        ],
        "summary": "Review SAR",
        "operationId": "sarReview",
        "security": [
          {
            "bearerAuth": []
          }
        ],
        "parameters": [
          {
            "name": "sarId",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "$ref": "#/components/parameters/RequestId"
          },
          {
            "$ref": "#/components/parameters/Traceparent"
          },
          {
            "$ref": "#/components/parameters/Tracestate"
          },
          {
            "$ref": "#/components/parameters/AcceptLanguage"
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "required": [
                  "action"
                ],
                "properties": {
                  "action": {
                    "type": "string",
                    "enum": [
                      "approve",
                      "escalate",
                      "close",
                      "request_info"
                    ]
                  },
                  "notes": {
                    "type": "string"
                  }
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "SAR reviewed",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "success": {
                      "type": "boolean",
                      "example": true
                    },
                    "message": {
                      "type": "string"
                    }
                  }
                },
                "example": {
                  "success": true,
                  "message": "string"
                }
              }
            },
            "headers": {
              "x-fapi-interaction-id": {
                "$ref": "#/components/headers/XFapiInteractionIdResponse"
              },
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/XRateLimitLimit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/XRateLimitRemaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/XRateLimitReset"
              },
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              },
              "traceparent": {
                "$ref": "#/components/headers/Traceparent"
              },
              "Content-Language": {
                "$ref": "#/components/headers/Content-Language"
              }
            }
          },
          "400": {
            "description": "Bad request",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              },
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                },
                "examples": {
                  "error": {
                    "$ref": "#/components/examples/ErrorBadRequest"
                  }
                }
              }
            },
            "headers": {
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/XRateLimitLimit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/XRateLimitRemaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/XRateLimitReset"
              },
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "403": {
            "$ref": "#/components/responses/Forbidden",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "404": {
            "$ref": "#/components/responses/NotFound",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "409": {
            "$ref": "#/components/responses/Conflict",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "429": {
            "$ref": "#/components/responses/TooManyRequests",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "500": {
            "$ref": "#/components/responses/InternalServerError",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          }
        },
        "x-codeSamples": [
          {
            "lang": "cURL",
            "label": "cURL",
            "source": "curl -X POST \"https://api.kangopenbanking.com/v1/compliance/sar/{sarId}/review\" \\\n  -H \"Authorization: Bearer $KOB_ACCESS_TOKEN\" \\\n  -H \"Content-Type: application/json\" \\\n  -d '{}'"
          },
          {
            "lang": "JavaScript",
            "label": "Node.js",
            "source": "import { KangOpenBanking } from \"@kangopenbanking/sdk\";\n\nconst kob = new KangOpenBanking({ apiKey: process.env.KOB_API_KEY });\nconst res = await kob.request(\"POST\", \"/v1/compliance/sar/{sarId}/review\", { /* payload */ });\nconsole.log(res);"
          },
          {
            "lang": "Python",
            "label": "Python",
            "source": "from kangopenbanking import KangOpenBanking\n\nkob = KangOpenBanking(api_key=os.environ[\"KOB_API_KEY\"])\nres = kob.request(\"POST\", \"/v1/compliance/sar/{sarId}/review\", json={})\nprint(res)"
          },
          {
            "lang": "PHP",
            "label": "PHP",
            "source": "<?php\n$kob = new KangOpenBanking\\KangOpenBanking(getenv('KOB_API_KEY'));\n$res = $kob->request('POST', '/v1/compliance/sar/{sarId}/review', []);\nprint_r($res);"
          }
        ]
      }
    },
    "/v1/compliance/sar/{sarId}/submit": {
      "post": {
        "tags": [
          "KYC & Compliance"
        ],
        "summary": "Submit SAR to regulator",
        "operationId": "sarSubmit",
        "security": [
          {
            "bearerAuth": []
          }
        ],
        "parameters": [
          {
            "name": "sarId",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "Idempotency-Key",
            "in": "header",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid"
            },
            "description": "Required on all POST/PUT endpoints. Unique key for idempotent request processing (UUID v4 recommended). Keys expire after 24 hours."
          },
          {
            "$ref": "#/components/parameters/RequestId"
          },
          {
            "$ref": "#/components/parameters/Traceparent"
          },
          {
            "$ref": "#/components/parameters/Tracestate"
          },
          {
            "$ref": "#/components/parameters/AcceptLanguage"
          }
        ],
        "responses": {
          "200": {
            "description": "SAR submitted",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "success": {
                      "type": "boolean",
                      "example": true
                    },
                    "message": {
                      "type": "string"
                    }
                  }
                },
                "example": {
                  "success": true,
                  "message": "string"
                }
              }
            },
            "headers": {
              "x-fapi-interaction-id": {
                "$ref": "#/components/headers/XFapiInteractionIdResponse"
              },
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/XRateLimitLimit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/XRateLimitRemaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/XRateLimitReset"
              },
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              },
              "traceparent": {
                "$ref": "#/components/headers/Traceparent"
              },
              "Content-Language": {
                "$ref": "#/components/headers/Content-Language"
              }
            }
          },
          "400": {
            "description": "Bad request",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              },
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                },
                "examples": {
                  "error": {
                    "$ref": "#/components/examples/ErrorBadRequest"
                  }
                }
              }
            },
            "headers": {
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/XRateLimitLimit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/XRateLimitRemaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/XRateLimitReset"
              },
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "403": {
            "$ref": "#/components/responses/Forbidden",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "404": {
            "$ref": "#/components/responses/NotFound",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "409": {
            "$ref": "#/components/responses/Conflict",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "429": {
            "$ref": "#/components/responses/TooManyRequests",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "500": {
            "$ref": "#/components/responses/InternalServerError",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          }
        },
        "x-codeSamples": [
          {
            "lang": "cURL",
            "label": "cURL",
            "source": "curl -X POST \"https://api.kangopenbanking.com/v1/compliance/sar/{sarId}/submit\" \\\n  -H \"Authorization: Bearer $KOB_ACCESS_TOKEN\" \\\n  -H \"Content-Type: application/json\""
          },
          {
            "lang": "JavaScript",
            "label": "Node.js",
            "source": "import { KangOpenBanking } from \"@kangopenbanking/sdk\";\n\nconst kob = new KangOpenBanking({ apiKey: process.env.KOB_API_KEY });\nconst res = await kob.request(\"POST\", \"/v1/compliance/sar/{sarId}/submit\");\nconsole.log(res);"
          },
          {
            "lang": "Python",
            "label": "Python",
            "source": "from kangopenbanking import KangOpenBanking\n\nkob = KangOpenBanking(api_key=os.environ[\"KOB_API_KEY\"])\nres = kob.request(\"POST\", \"/v1/compliance/sar/{sarId}/submit\")\nprint(res)"
          },
          {
            "lang": "PHP",
            "label": "PHP",
            "source": "<?php\n$kob = new KangOpenBanking\\KangOpenBanking(getenv('KOB_API_KEY'));\n$res = $kob->request('POST', '/v1/compliance/sar/{sarId}/submit');\nprint_r($res);"
          }
        ]
      }
    },
    "/v1/safeguarding/reconcile": {
      "post": {
        "tags": [
          "KYC & Compliance"
        ],
        "summary": "Run safeguarding reconciliation",
        "description": "Reconcile total e-money liabilities against actual wallet and escrow balances.",
        "operationId": "safeguardingReconcile",
        "security": [
          {
            "bearerAuth": []
          }
        ],
        "responses": {
          "200": {
            "description": "Reconciliation result with discrepancy details",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "total_liabilities": {
                      "type": "number"
                    },
                    "total_assets": {
                      "type": "number"
                    },
                    "discrepancy": {
                      "type": "number"
                    },
                    "status": {
                      "type": "string"
                    }
                  }
                },
                "example": {
                  "total_liabilities": 0,
                  "total_assets": 0,
                  "discrepancy": 0,
                  "status": "string"
                }
              }
            },
            "headers": {
              "x-fapi-interaction-id": {
                "$ref": "#/components/headers/XFapiInteractionIdResponse"
              },
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/XRateLimitLimit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/XRateLimitRemaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/XRateLimitReset"
              },
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              },
              "traceparent": {
                "$ref": "#/components/headers/Traceparent"
              },
              "Content-Language": {
                "$ref": "#/components/headers/Content-Language"
              }
            }
          },
          "400": {
            "description": "Bad request",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              },
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                },
                "examples": {
                  "error": {
                    "$ref": "#/components/examples/ErrorBadRequest"
                  }
                }
              }
            },
            "headers": {
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/XRateLimitLimit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/XRateLimitRemaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/XRateLimitReset"
              },
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "403": {
            "$ref": "#/components/responses/Forbidden",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "404": {
            "$ref": "#/components/responses/NotFound",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "409": {
            "$ref": "#/components/responses/Conflict",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "429": {
            "$ref": "#/components/responses/TooManyRequests",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "500": {
            "$ref": "#/components/responses/InternalServerError",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          }
        },
        "parameters": [
          {
            "$ref": "#/components/parameters/RequestId"
          },
          {
            "$ref": "#/components/parameters/Traceparent"
          },
          {
            "$ref": "#/components/parameters/Tracestate"
          },
          {
            "$ref": "#/components/parameters/AcceptLanguage"
          }
        ],
        "x-codeSamples": [
          {
            "lang": "cURL",
            "label": "cURL",
            "source": "curl -X POST \"https://api.kangopenbanking.com/v1/safeguarding/reconcile\" \\\n  -H \"Authorization: Bearer $KOB_ACCESS_TOKEN\" \\\n  -H \"Content-Type: application/json\""
          },
          {
            "lang": "JavaScript",
            "label": "Node.js",
            "source": "import { KangOpenBanking } from \"@kangopenbanking/sdk\";\n\nconst kob = new KangOpenBanking({ apiKey: process.env.KOB_API_KEY });\nconst res = await kob.request(\"POST\", \"/v1/safeguarding/reconcile\");\nconsole.log(res);"
          },
          {
            "lang": "Python",
            "label": "Python",
            "source": "from kangopenbanking import KangOpenBanking\n\nkob = KangOpenBanking(api_key=os.environ[\"KOB_API_KEY\"])\nres = kob.request(\"POST\", \"/v1/safeguarding/reconcile\")\nprint(res)"
          },
          {
            "lang": "PHP",
            "label": "PHP",
            "source": "<?php\n$kob = new KangOpenBanking\\KangOpenBanking(getenv('KOB_API_KEY'));\n$res = $kob->request('POST', '/v1/safeguarding/reconcile');\nprint_r($res);"
          }
        ]
      }
    },
    "/v1/safeguarding/snapshots": {
      "get": {
        "tags": [
          "KYC & Compliance"
        ],
        "summary": "List safeguarding snapshots",
        "operationId": "safeguardingSnapshots",
        "security": [
          {
            "bearerAuth": []
          }
        ],
        "parameters": [
          {
            "name": "from",
            "in": "query",
            "schema": {
              "type": "string",
              "format": "date"
            }
          },
          {
            "name": "to",
            "in": "query",
            "schema": {
              "type": "string",
              "format": "date"
            }
          },
          {
            "name": "limit",
            "in": "query",
            "schema": {
              "type": "integer",
              "default": 25,
              "maximum": 100
            },
            "description": "Items per page"
          },
          {
            "name": "offset",
            "in": "query",
            "schema": {
              "type": "integer",
              "default": 0
            },
            "description": "Items to skip"
          },
          {
            "name": "sort_by",
            "in": "query",
            "schema": {
              "type": "string",
              "default": "created_at"
            },
            "description": "Sort field"
          },
          {
            "name": "sort_order",
            "in": "query",
            "schema": {
              "type": "string",
              "enum": [
                "asc",
                "desc"
              ],
              "default": "desc"
            },
            "description": "Sort direction"
          },
          {
            "$ref": "#/components/parameters/StartingAfter"
          },
          {
            "$ref": "#/components/parameters/EndingBefore"
          },
          {
            "$ref": "#/components/parameters/RequestId"
          },
          {
            "$ref": "#/components/parameters/Traceparent"
          },
          {
            "$ref": "#/components/parameters/Tracestate"
          },
          {
            "$ref": "#/components/parameters/AcceptLanguage"
          }
        ],
        "responses": {
          "200": {
            "description": "Daily safeguarding snapshots",
            "content": {
              "application/json": {
                "schema": {
                  "allOf": [
                    {
                      "$ref": "#/components/schemas/PaginatedResponse"
                    },
                    {
                      "type": "object",
                      "properties": {
                        "data": {
                          "type": "array",
                          "items": {}
                        }
                      }
                    }
                  ]
                },
                "example": {
                  "data": [
                    {}
                  ],
                  "pagination": {
                    "page": 1,
                    "limit": 20,
                    "total": 150,
                    "has_next": true,
                    "next_cursor": "eyJpZCI6IjEyMyJ9"
                  },
                  "meta": {
                    "request_id": "550e8400-e29b-41d4-a716-446655440000",
                    "timestamp": "2025-03-27T12:00:00Z",
                    "api_version": "4.3.0"
                  }
                }
              }
            },
            "headers": {
              "x-fapi-interaction-id": {
                "$ref": "#/components/headers/XFapiInteractionIdResponse"
              },
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/XRateLimitLimit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/XRateLimitRemaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/XRateLimitReset"
              },
              "Cache-Control": {
                "$ref": "#/components/headers/CacheControl"
              },
              "ETag": {
                "$ref": "#/components/headers/ETag"
              },
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              },
              "traceparent": {
                "$ref": "#/components/headers/Traceparent"
              },
              "Content-Language": {
                "$ref": "#/components/headers/Content-Language"
              }
            }
          },
          "400": {
            "description": "Bad request",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              },
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                },
                "examples": {
                  "error": {
                    "$ref": "#/components/examples/ErrorBadRequest"
                  }
                }
              }
            },
            "headers": {
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/XRateLimitLimit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/XRateLimitRemaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/XRateLimitReset"
              },
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "403": {
            "$ref": "#/components/responses/Forbidden",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "404": {
            "$ref": "#/components/responses/NotFound",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "409": {
            "$ref": "#/components/responses/Conflict",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "429": {
            "$ref": "#/components/responses/TooManyRequests",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "500": {
            "$ref": "#/components/responses/InternalServerError",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          }
        },
        "x-codeSamples": [
          {
            "lang": "cURL",
            "label": "cURL",
            "source": "curl -X GET \"https://api.kangopenbanking.com/v1/safeguarding/snapshots\" \\\n  -H \"Authorization: Bearer $KOB_ACCESS_TOKEN\" \\\n  -H \"Content-Type: application/json\""
          },
          {
            "lang": "JavaScript",
            "label": "Node.js",
            "source": "import { KangOpenBanking } from \"@kangopenbanking/sdk\";\n\nconst kob = new KangOpenBanking({ apiKey: process.env.KOB_API_KEY });\nconst res = await kob.request(\"GET\", \"/v1/safeguarding/snapshots\");\nconsole.log(res);"
          },
          {
            "lang": "Python",
            "label": "Python",
            "source": "from kangopenbanking import KangOpenBanking\n\nkob = KangOpenBanking(api_key=os.environ[\"KOB_API_KEY\"])\nres = kob.request(\"GET\", \"/v1/safeguarding/snapshots\")\nprint(res)"
          },
          {
            "lang": "PHP",
            "label": "PHP",
            "source": "<?php\n$kob = new KangOpenBanking\\KangOpenBanking(getenv('KOB_API_KEY'));\n$res = $kob->request('GET', '/v1/safeguarding/snapshots');\nprint_r($res);"
          }
        ]
      }
    },
    "/v1/payouts/instant": {
      "post": {
        "tags": [
          "Payment Gateway"
        ],
        "summary": "Instant payout",
        "description": "Route payout through fastest available rail (MoMo instant, bank express, Visa Direct).",
        "operationId": "payoutInstant",
        "security": [
          {
            "bearerAuth": []
          }
        ],
        "parameters": [
          {
            "name": "Idempotency-Key",
            "in": "header",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid"
            },
            "description": "Required on all POST/PUT endpoints. Unique key for idempotent request processing (UUID v4 recommended). Keys expire after 24 hours."
          },
          {
            "$ref": "#/components/parameters/RequestId"
          },
          {
            "$ref": "#/components/parameters/Traceparent"
          },
          {
            "$ref": "#/components/parameters/Tracestate"
          },
          {
            "$ref": "#/components/parameters/AcceptLanguage"
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "required": [
                  "merchant_id",
                  "amount",
                  "currency",
                  "channel"
                ],
                "properties": {
                  "merchant_id": {
                    "type": "string",
                    "format": "uuid"
                  },
                  "amount": {
                    "type": "string",
                    "pattern": "^[0-9]{1,15}$",
                    "description": "Represented as a string integer in the currency's minor unit (XAF has no subunits). Must be consistent with the currency field."
                  },
                  "currency": {
                    "type": "string",
                    "enum": [
                      "XAF",
                      "XOF",
                      "USD",
                      "EUR",
                      "GBP",
                      "CNY",
                      "NGN",
                      "GHS",
                      "KES",
                      "ZAR"
                    ],
                    "default": "XAF",
                    "description": "ISO 4217 currency code. Default is XAF (Central African CFA Franc)."
                  },
                  "channel": {
                    "type": "string",
                    "enum": [
                      "momo_instant",
                      "bank_express",
                      "visa_direct"
                    ]
                  },
                  "beneficiary_phone": {
                    "type": "string"
                  },
                  "beneficiary_account": {
                    "type": "string"
                  },
                  "beneficiary_name": {
                    "type": "string"
                  }
                }
              }
            }
          }
        },
        "responses": {
          "201": {
            "description": "Instant payout initiated",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/GatewayPayout"
                },
                "example": {
                  "id": "00000000-0000-4000-8000-000000000000",
                  "merchant_id": "00000000-0000-4000-8000-000000000000",
                  "amount": "10000",
                  "currency": "XAF",
                  "channel": "mobile_money",
                  "status": "pending",
                  "beneficiary_name": "string",
                  "beneficiary_phone": "string",
                  "tx_ref": "string",
                  "created_at": "2026-01-01T00:00:00Z"
                }
              }
            },
            "headers": {
              "x-fapi-interaction-id": {
                "$ref": "#/components/headers/XFapiInteractionIdResponse"
              },
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/XRateLimitLimit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/XRateLimitRemaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/XRateLimitReset"
              },
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              },
              "X-Idempotent-Replay": {
                "$ref": "#/components/headers/X-Idempotent-Replay"
              },
              "X-Idempotency-Status": {
                "$ref": "#/components/headers/X-Idempotency-Status"
              },
              "traceparent": {
                "$ref": "#/components/headers/Traceparent"
              },
              "Content-Language": {
                "$ref": "#/components/headers/Content-Language"
              }
            }
          },
          "400": {
            "description": "Bad request",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              },
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                },
                "examples": {
                  "error": {
                    "$ref": "#/components/examples/ErrorBadRequest"
                  }
                }
              }
            },
            "headers": {
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/XRateLimitLimit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/XRateLimitRemaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/XRateLimitReset"
              },
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "403": {
            "$ref": "#/components/responses/Forbidden",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "404": {
            "$ref": "#/components/responses/NotFound",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "409": {
            "$ref": "#/components/responses/Conflict",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "429": {
            "$ref": "#/components/responses/TooManyRequests",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "500": {
            "$ref": "#/components/responses/InternalServerError",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          }
        },
        "x-codeSamples": [
          {
            "lang": "cURL",
            "label": "cURL",
            "source": "curl -X POST \"https://api.kangopenbanking.com/v1/payouts/instant\" \\\n  -H \"Authorization: Bearer $KOB_ACCESS_TOKEN\" \\\n  -H \"Content-Type: application/json\" \\\n  -d '{}'"
          },
          {
            "lang": "JavaScript",
            "label": "Node.js",
            "source": "import { KangOpenBanking } from \"@kangopenbanking/sdk\";\n\nconst kob = new KangOpenBanking({ apiKey: process.env.KOB_API_KEY });\nconst res = await kob.request(\"POST\", \"/v1/payouts/instant\", { /* payload */ });\nconsole.log(res);"
          },
          {
            "lang": "Python",
            "label": "Python",
            "source": "from kangopenbanking import KangOpenBanking\n\nkob = KangOpenBanking(api_key=os.environ[\"KOB_API_KEY\"])\nres = kob.request(\"POST\", \"/v1/payouts/instant\", json={})\nprint(res)"
          },
          {
            "lang": "PHP",
            "label": "PHP",
            "source": "<?php\n$kob = new KangOpenBanking\\KangOpenBanking(getenv('KOB_API_KEY'));\n$res = $kob->request('POST', '/v1/payouts/instant', []);\nprint_r($res);"
          }
        ]
      }
    },
    "/v1/payouts/push-to-card": {
      "post": {
        "tags": [
          "Payment Gateway"
        ],
        "summary": "Push-to-card payout",
        "description": "Visa Direct card push disbursement.",
        "operationId": "payoutPushToCard",
        "security": [
          {
            "bearerAuth": []
          }
        ],
        "parameters": [
          {
            "name": "Idempotency-Key",
            "in": "header",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid"
            },
            "description": "Required on all POST/PUT endpoints. Unique key for idempotent request processing (UUID v4 recommended). Keys expire after 24 hours."
          },
          {
            "$ref": "#/components/parameters/RequestId"
          },
          {
            "$ref": "#/components/parameters/Traceparent"
          },
          {
            "$ref": "#/components/parameters/Tracestate"
          },
          {
            "$ref": "#/components/parameters/AcceptLanguage"
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "required": [
                  "merchant_id",
                  "amount",
                  "currency",
                  "card_number"
                ],
                "properties": {
                  "merchant_id": {
                    "type": "string",
                    "format": "uuid"
                  },
                  "amount": {
                    "type": "string",
                    "pattern": "^[0-9]{1,15}$",
                    "description": "Represented as a string integer in the currency's minor unit (XAF has no subunits). Must be consistent with the currency field."
                  },
                  "currency": {
                    "type": "string",
                    "enum": [
                      "XAF",
                      "XOF",
                      "USD",
                      "EUR",
                      "GBP",
                      "CNY",
                      "NGN",
                      "GHS",
                      "KES",
                      "ZAR"
                    ],
                    "default": "XAF",
                    "description": "ISO 4217 currency code. Default is XAF (Central African CFA Franc)."
                  },
                  "card_number": {
                    "type": "string"
                  },
                  "card_holder_name": {
                    "type": "string"
                  }
                }
              }
            }
          }
        },
        "responses": {
          "201": {
            "description": "Push-to-card initiated",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/GatewayPayout"
                },
                "example": {
                  "id": "00000000-0000-4000-8000-000000000000",
                  "merchant_id": "00000000-0000-4000-8000-000000000000",
                  "amount": "10000",
                  "currency": "XAF",
                  "channel": "mobile_money",
                  "status": "pending",
                  "beneficiary_name": "string",
                  "beneficiary_phone": "string",
                  "tx_ref": "string",
                  "created_at": "2026-01-01T00:00:00Z"
                }
              }
            },
            "headers": {
              "x-fapi-interaction-id": {
                "$ref": "#/components/headers/XFapiInteractionIdResponse"
              },
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/XRateLimitLimit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/XRateLimitRemaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/XRateLimitReset"
              },
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              },
              "X-Idempotent-Replay": {
                "$ref": "#/components/headers/X-Idempotent-Replay"
              },
              "X-Idempotency-Status": {
                "$ref": "#/components/headers/X-Idempotency-Status"
              },
              "traceparent": {
                "$ref": "#/components/headers/Traceparent"
              },
              "Content-Language": {
                "$ref": "#/components/headers/Content-Language"
              }
            }
          },
          "400": {
            "description": "Bad request",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              },
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                },
                "examples": {
                  "error": {
                    "$ref": "#/components/examples/ErrorBadRequest"
                  }
                }
              }
            },
            "headers": {
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/XRateLimitLimit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/XRateLimitRemaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/XRateLimitReset"
              },
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "403": {
            "$ref": "#/components/responses/Forbidden",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "404": {
            "$ref": "#/components/responses/NotFound",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "409": {
            "$ref": "#/components/responses/Conflict",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "429": {
            "$ref": "#/components/responses/TooManyRequests",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "500": {
            "$ref": "#/components/responses/InternalServerError",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          }
        },
        "x-pci-scope": "cardholder_data",
        "x-pci-note": "Accepts a full PAN on the wire to fund a push-to-card payout. The PAN is forwarded to Kora and never persisted in KOB's datastore. Step-up MFA, idempotency, and per-principal rate limits apply.",
        "x-codeSamples": [
          {
            "lang": "cURL",
            "label": "cURL",
            "source": "curl -X POST \"https://api.kangopenbanking.com/v1/payouts/push-to-card\" \\\n  -H \"Authorization: Bearer $KOB_ACCESS_TOKEN\" \\\n  -H \"Content-Type: application/json\" \\\n  -d '{}'"
          },
          {
            "lang": "JavaScript",
            "label": "Node.js",
            "source": "import { KangOpenBanking } from \"@kangopenbanking/sdk\";\n\nconst kob = new KangOpenBanking({ apiKey: process.env.KOB_API_KEY });\nconst res = await kob.request(\"POST\", \"/v1/payouts/push-to-card\", { /* payload */ });\nconsole.log(res);"
          },
          {
            "lang": "Python",
            "label": "Python",
            "source": "from kangopenbanking import KangOpenBanking\n\nkob = KangOpenBanking(api_key=os.environ[\"KOB_API_KEY\"])\nres = kob.request(\"POST\", \"/v1/payouts/push-to-card\", json={})\nprint(res)"
          },
          {
            "lang": "PHP",
            "label": "PHP",
            "source": "<?php\n$kob = new KangOpenBanking\\KangOpenBanking(getenv('KOB_API_KEY'));\n$res = $kob->request('POST', '/v1/payouts/push-to-card', []);\nprint_r($res);"
          }
        ]
      }
    },
    "/v1/payouts/rails": {
      "get": {
        "tags": [
          "Payment Gateway"
        ],
        "summary": "List available payout rails",
        "description": "Returns available rails by country and currency with estimated delivery times.",
        "operationId": "payoutRails",
        "security": [
          {
            "bearerAuth": []
          }
        ],
        "parameters": [
          {
            "name": "country",
            "in": "query",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "currency",
            "in": "query",
            "schema": {
              "type": "string"
            }
          },
          {
            "$ref": "#/components/parameters/RequestId"
          },
          {
            "$ref": "#/components/parameters/Traceparent"
          },
          {
            "$ref": "#/components/parameters/Tracestate"
          },
          {
            "$ref": "#/components/parameters/AcceptLanguage"
          }
        ],
        "responses": {
          "200": {
            "description": "Available payout rails with speeds and fees",
            "content": {
              "application/json": {
                "schema": {
                  "allOf": [
                    {
                      "$ref": "#/components/schemas/PaginatedResponse"
                    },
                    {
                      "type": "object",
                      "properties": {
                        "data": {
                          "type": "array",
                          "items": {}
                        }
                      }
                    }
                  ]
                },
                "example": {
                  "data": [
                    {}
                  ],
                  "pagination": {
                    "page": 1,
                    "limit": 20,
                    "total": 150,
                    "has_next": true,
                    "next_cursor": "eyJpZCI6IjEyMyJ9"
                  },
                  "meta": {
                    "request_id": "550e8400-e29b-41d4-a716-446655440000",
                    "timestamp": "2025-03-27T12:00:00Z",
                    "api_version": "4.3.0"
                  }
                }
              }
            },
            "headers": {
              "x-fapi-interaction-id": {
                "$ref": "#/components/headers/XFapiInteractionIdResponse"
              },
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/XRateLimitLimit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/XRateLimitRemaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/XRateLimitReset"
              },
              "Cache-Control": {
                "$ref": "#/components/headers/CacheControl"
              },
              "ETag": {
                "$ref": "#/components/headers/ETag"
              },
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              },
              "traceparent": {
                "$ref": "#/components/headers/Traceparent"
              },
              "Content-Language": {
                "$ref": "#/components/headers/Content-Language"
              }
            }
          },
          "400": {
            "description": "Bad request",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              },
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                },
                "examples": {
                  "error": {
                    "$ref": "#/components/examples/ErrorBadRequest"
                  }
                }
              }
            },
            "headers": {
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/XRateLimitLimit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/XRateLimitRemaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/XRateLimitReset"
              },
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "403": {
            "$ref": "#/components/responses/Forbidden",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "404": {
            "$ref": "#/components/responses/NotFound",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "409": {
            "$ref": "#/components/responses/Conflict",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "429": {
            "$ref": "#/components/responses/TooManyRequests",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "500": {
            "$ref": "#/components/responses/InternalServerError",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          }
        },
        "x-codeSamples": [
          {
            "lang": "cURL",
            "label": "cURL",
            "source": "curl -X GET \"https://api.kangopenbanking.com/v1/payouts/rails\" \\\n  -H \"Authorization: Bearer $KOB_ACCESS_TOKEN\" \\\n  -H \"Content-Type: application/json\""
          },
          {
            "lang": "JavaScript",
            "label": "Node.js",
            "source": "import { KangOpenBanking } from \"@kangopenbanking/sdk\";\n\nconst kob = new KangOpenBanking({ apiKey: process.env.KOB_API_KEY });\nconst res = await kob.request(\"GET\", \"/v1/payouts/rails\");\nconsole.log(res);"
          },
          {
            "lang": "Python",
            "label": "Python",
            "source": "from kangopenbanking import KangOpenBanking\n\nkob = KangOpenBanking(api_key=os.environ[\"KOB_API_KEY\"])\nres = kob.request(\"GET\", \"/v1/payouts/rails\")\nprint(res)"
          },
          {
            "lang": "PHP",
            "label": "PHP",
            "source": "<?php\n$kob = new KangOpenBanking\\KangOpenBanking(getenv('KOB_API_KEY'));\n$res = $kob->request('GET', '/v1/payouts/rails');\nprint_r($res);"
          }
        ]
      }
    },
    "/v1/payouts/{payoutId}/cancel": {
      "post": {
        "tags": [
          "Payment Gateway"
        ],
        "summary": "Cancel pending payout",
        "operationId": "payoutCancel",
        "security": [
          {
            "bearerAuth": []
          }
        ],
        "parameters": [
          {
            "name": "payoutId",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "$ref": "#/components/parameters/IdempotencyKey"
          },
          {
            "$ref": "#/components/parameters/RequestId"
          },
          {
            "$ref": "#/components/parameters/Traceparent"
          },
          {
            "$ref": "#/components/parameters/Tracestate"
          },
          {
            "$ref": "#/components/parameters/AcceptLanguage"
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "reason": {
                    "type": "string"
                  }
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Payout cancelled and funds returned to wallet",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "success": {
                      "type": "boolean",
                      "example": true
                    },
                    "message": {
                      "type": "string"
                    }
                  }
                },
                "example": {
                  "success": true,
                  "message": "string"
                }
              }
            },
            "headers": {
              "x-fapi-interaction-id": {
                "$ref": "#/components/headers/XFapiInteractionIdResponse"
              },
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/XRateLimitLimit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/XRateLimitRemaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/XRateLimitReset"
              },
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              },
              "X-Idempotent-Replay": {
                "$ref": "#/components/headers/X-Idempotent-Replay"
              },
              "X-Idempotency-Status": {
                "$ref": "#/components/headers/X-Idempotency-Status"
              },
              "traceparent": {
                "$ref": "#/components/headers/Traceparent"
              },
              "Content-Language": {
                "$ref": "#/components/headers/Content-Language"
              }
            }
          },
          "400": {
            "description": "Bad request",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              },
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                },
                "examples": {
                  "error": {
                    "$ref": "#/components/examples/ErrorBadRequest"
                  }
                }
              }
            },
            "headers": {
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/XRateLimitLimit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/XRateLimitRemaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/XRateLimitReset"
              },
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "403": {
            "$ref": "#/components/responses/Forbidden",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "404": {
            "$ref": "#/components/responses/NotFound",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "409": {
            "$ref": "#/components/responses/Conflict",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "429": {
            "$ref": "#/components/responses/TooManyRequests",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "500": {
            "$ref": "#/components/responses/InternalServerError",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          }
        },
        "x-codeSamples": [
          {
            "lang": "cURL",
            "label": "cURL",
            "source": "curl -X POST \"https://api.kangopenbanking.com/v1/payouts/{payoutId}/cancel\" \\\n  -H \"Authorization: Bearer $KOB_ACCESS_TOKEN\" \\\n  -H \"Content-Type: application/json\" \\\n  -d '{}'"
          },
          {
            "lang": "JavaScript",
            "label": "Node.js",
            "source": "import { KangOpenBanking } from \"@kangopenbanking/sdk\";\n\nconst kob = new KangOpenBanking({ apiKey: process.env.KOB_API_KEY });\nconst res = await kob.request(\"POST\", \"/v1/payouts/{payoutId}/cancel\", { /* payload */ });\nconsole.log(res);"
          },
          {
            "lang": "Python",
            "label": "Python",
            "source": "from kangopenbanking import KangOpenBanking\n\nkob = KangOpenBanking(api_key=os.environ[\"KOB_API_KEY\"])\nres = kob.request(\"POST\", \"/v1/payouts/{payoutId}/cancel\", json={})\nprint(res)"
          },
          {
            "lang": "PHP",
            "label": "PHP",
            "source": "<?php\n$kob = new KangOpenBanking\\KangOpenBanking(getenv('KOB_API_KEY'));\n$res = $kob->request('POST', '/v1/payouts/{payoutId}/cancel', []);\nprint_r($res);"
          }
        ]
      }
    },
    "/v1/treasury/float": {
      "get": {
        "tags": [
          "Payment Gateway"
        ],
        "summary": "Get treasury float balance",
        "description": "Current float balances across all provider accounts.",
        "operationId": "treasuryFloat",
        "security": [
          {
            "bearerAuth": []
          }
        ],
        "responses": {
          "200": {
            "description": "Float balances by provider and currency",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "balances": {
                      "type": "array",
                      "items": {
                        "type": "object",
                        "properties": {
                          "provider": {
                            "type": "string"
                          },
                          "currency": {
                            "type": "string",
                            "enum": [
                              "XAF",
                              "XOF",
                              "USD",
                              "EUR",
                              "GBP",
                              "CNY",
                              "NGN",
                              "GHS",
                              "KES",
                              "ZAR"
                            ],
                            "default": "XAF",
                            "description": "ISO 4217 currency code. Default is XAF (Central African CFA Franc)."
                          },
                          "balance": {
                            "type": "string",
                            "pattern": "^[0-9]{1,15}$",
                            "description": "Represented as a string integer in the currency's minor unit (XAF has no subunits). Must be consistent with the currency field."
                          }
                        }
                      }
                    }
                  }
                },
                "example": {
                  "balances": [
                    {
                      "provider": "string",
                      "currency": "XAF",
                      "balance": "1000"
                    }
                  ]
                }
              }
            },
            "headers": {
              "x-fapi-interaction-id": {
                "$ref": "#/components/headers/XFapiInteractionIdResponse"
              },
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/XRateLimitLimit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/XRateLimitRemaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/XRateLimitReset"
              },
              "Cache-Control": {
                "$ref": "#/components/headers/CacheControl"
              },
              "ETag": {
                "$ref": "#/components/headers/ETag"
              },
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              },
              "traceparent": {
                "$ref": "#/components/headers/Traceparent"
              },
              "Content-Language": {
                "$ref": "#/components/headers/Content-Language"
              }
            }
          },
          "400": {
            "description": "Bad request",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              },
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                },
                "examples": {
                  "error": {
                    "$ref": "#/components/examples/ErrorBadRequest"
                  }
                }
              }
            },
            "headers": {
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/XRateLimitLimit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/XRateLimitRemaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/XRateLimitReset"
              },
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "403": {
            "$ref": "#/components/responses/Forbidden",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "404": {
            "$ref": "#/components/responses/NotFound",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "409": {
            "$ref": "#/components/responses/Conflict",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "429": {
            "$ref": "#/components/responses/TooManyRequests",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "500": {
            "$ref": "#/components/responses/InternalServerError",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          }
        },
        "parameters": [
          {
            "$ref": "#/components/parameters/RequestId"
          },
          {
            "$ref": "#/components/parameters/Traceparent"
          },
          {
            "$ref": "#/components/parameters/Tracestate"
          },
          {
            "$ref": "#/components/parameters/AcceptLanguage"
          }
        ],
        "x-codeSamples": [
          {
            "lang": "cURL",
            "label": "cURL",
            "source": "curl -X GET \"https://api.kangopenbanking.com/v1/treasury/float\" \\\n  -H \"Authorization: Bearer $KOB_ACCESS_TOKEN\" \\\n  -H \"Content-Type: application/json\""
          },
          {
            "lang": "JavaScript",
            "label": "Node.js",
            "source": "import { KangOpenBanking } from \"@kangopenbanking/sdk\";\n\nconst kob = new KangOpenBanking({ apiKey: process.env.KOB_API_KEY });\nconst res = await kob.request(\"GET\", \"/v1/treasury/float\");\nconsole.log(res);"
          },
          {
            "lang": "Python",
            "label": "Python",
            "source": "from kangopenbanking import KangOpenBanking\n\nkob = KangOpenBanking(api_key=os.environ[\"KOB_API_KEY\"])\nres = kob.request(\"GET\", \"/v1/treasury/float\")\nprint(res)"
          },
          {
            "lang": "PHP",
            "label": "PHP",
            "source": "<?php\n$kob = new KangOpenBanking\\KangOpenBanking(getenv('KOB_API_KEY'));\n$res = $kob->request('GET', '/v1/treasury/float');\nprint_r($res);"
          }
        ]
      }
    },
    "/v1/treasury/replenish": {
      "post": {
        "tags": [
          "Payment Gateway"
        ],
        "summary": "Replenish treasury float",
        "operationId": "treasuryReplenish",
        "security": [
          {
            "bearerAuth": []
          }
        ],
        "parameters": [
          {
            "name": "Idempotency-Key",
            "in": "header",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid"
            },
            "description": "Required on all POST/PUT endpoints. Unique key for idempotent request processing (UUID v4 recommended). Keys expire after 24 hours."
          },
          {
            "$ref": "#/components/parameters/RequestId"
          },
          {
            "$ref": "#/components/parameters/Traceparent"
          },
          {
            "$ref": "#/components/parameters/Tracestate"
          },
          {
            "$ref": "#/components/parameters/AcceptLanguage"
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "required": [
                  "provider",
                  "amount",
                  "currency"
                ],
                "properties": {
                  "provider": {
                    "type": "string"
                  },
                  "amount": {
                    "type": "string",
                    "pattern": "^[0-9]{1,15}$",
                    "description": "Represented as a string integer in the currency's minor unit (XAF has no subunits). Must be consistent with the currency field."
                  },
                  "currency": {
                    "type": "string",
                    "enum": [
                      "XAF",
                      "XOF",
                      "USD",
                      "EUR",
                      "GBP",
                      "CNY",
                      "NGN",
                      "GHS",
                      "KES",
                      "ZAR"
                    ],
                    "default": "XAF",
                    "description": "ISO 4217 currency code. Default is XAF (Central African CFA Franc)."
                  }
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Replenishment initiated",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "success": {
                      "type": "boolean",
                      "example": true
                    },
                    "message": {
                      "type": "string"
                    }
                  }
                },
                "example": {
                  "success": true,
                  "message": "string"
                }
              }
            },
            "headers": {
              "x-fapi-interaction-id": {
                "$ref": "#/components/headers/XFapiInteractionIdResponse"
              },
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/XRateLimitLimit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/XRateLimitRemaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/XRateLimitReset"
              },
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              },
              "X-Idempotent-Replay": {
                "$ref": "#/components/headers/X-Idempotent-Replay"
              },
              "X-Idempotency-Status": {
                "$ref": "#/components/headers/X-Idempotency-Status"
              },
              "traceparent": {
                "$ref": "#/components/headers/Traceparent"
              },
              "Content-Language": {
                "$ref": "#/components/headers/Content-Language"
              }
            }
          },
          "400": {
            "description": "Bad request",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              },
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                },
                "examples": {
                  "error": {
                    "$ref": "#/components/examples/ErrorBadRequest"
                  }
                }
              }
            },
            "headers": {
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/XRateLimitLimit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/XRateLimitRemaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/XRateLimitReset"
              },
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "403": {
            "$ref": "#/components/responses/Forbidden",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "404": {
            "$ref": "#/components/responses/NotFound",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "409": {
            "$ref": "#/components/responses/Conflict",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "429": {
            "$ref": "#/components/responses/TooManyRequests",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "500": {
            "$ref": "#/components/responses/InternalServerError",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          }
        },
        "x-codeSamples": [
          {
            "lang": "cURL",
            "label": "cURL",
            "source": "curl -X POST \"https://api.kangopenbanking.com/v1/treasury/replenish\" \\\n  -H \"Authorization: Bearer $KOB_ACCESS_TOKEN\" \\\n  -H \"Content-Type: application/json\" \\\n  -d '{}'"
          },
          {
            "lang": "JavaScript",
            "label": "Node.js",
            "source": "import { KangOpenBanking } from \"@kangopenbanking/sdk\";\n\nconst kob = new KangOpenBanking({ apiKey: process.env.KOB_API_KEY });\nconst res = await kob.request(\"POST\", \"/v1/treasury/replenish\", { /* payload */ });\nconsole.log(res);"
          },
          {
            "lang": "Python",
            "label": "Python",
            "source": "from kangopenbanking import KangOpenBanking\n\nkob = KangOpenBanking(api_key=os.environ[\"KOB_API_KEY\"])\nres = kob.request(\"POST\", \"/v1/treasury/replenish\", json={})\nprint(res)"
          },
          {
            "lang": "PHP",
            "label": "PHP",
            "source": "<?php\n$kob = new KangOpenBanking\\KangOpenBanking(getenv('KOB_API_KEY'));\n$res = $kob->request('POST', '/v1/treasury/replenish', []);\nprint_r($res);"
          }
        ]
      }
    },
    "/v1/sla/metrics": {
      "get": {
        "tags": [
          "Monitoring"
        ],
        "summary": "SLA metrics",
        "description": "Uptime percentages, latency percentiles (p50/p95/p99), and error rates.",
        "operationId": "slaMetrics",
        "security": [
          {
            "bearerAuth": []
          }
        ],
        "parameters": [
          {
            "name": "from",
            "in": "query",
            "schema": {
              "type": "string",
              "format": "date"
            }
          },
          {
            "name": "to",
            "in": "query",
            "schema": {
              "type": "string",
              "format": "date"
            }
          },
          {
            "$ref": "#/components/parameters/RequestId"
          },
          {
            "$ref": "#/components/parameters/Traceparent"
          },
          {
            "$ref": "#/components/parameters/Tracestate"
          },
          {
            "$ref": "#/components/parameters/AcceptLanguage"
          }
        ],
        "responses": {
          "200": {
            "description": "SLA metric data",
            "content": {
              "application/json": {
                "schema": {
                  "allOf": [
                    {
                      "$ref": "#/components/schemas/PaginatedResponse"
                    },
                    {
                      "type": "object",
                      "properties": {
                        "data": {
                          "type": "array",
                          "items": {}
                        }
                      }
                    }
                  ]
                },
                "example": {
                  "data": [
                    {}
                  ],
                  "pagination": {
                    "page": 1,
                    "limit": 20,
                    "total": 150,
                    "has_next": true,
                    "next_cursor": "eyJpZCI6IjEyMyJ9"
                  },
                  "meta": {
                    "request_id": "550e8400-e29b-41d4-a716-446655440000",
                    "timestamp": "2025-03-27T12:00:00Z",
                    "api_version": "4.3.0"
                  }
                }
              }
            },
            "headers": {
              "x-fapi-interaction-id": {
                "$ref": "#/components/headers/XFapiInteractionIdResponse"
              },
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/XRateLimitLimit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/XRateLimitRemaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/XRateLimitReset"
              },
              "Cache-Control": {
                "$ref": "#/components/headers/CacheControl"
              },
              "ETag": {
                "$ref": "#/components/headers/ETag"
              },
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              },
              "traceparent": {
                "$ref": "#/components/headers/Traceparent"
              },
              "Content-Language": {
                "$ref": "#/components/headers/Content-Language"
              }
            }
          },
          "400": {
            "description": "Bad request",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              },
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                },
                "examples": {
                  "error": {
                    "$ref": "#/components/examples/ErrorBadRequest"
                  }
                }
              }
            },
            "headers": {
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/XRateLimitLimit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/XRateLimitRemaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/XRateLimitReset"
              },
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "403": {
            "$ref": "#/components/responses/Forbidden",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "404": {
            "$ref": "#/components/responses/NotFound",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "409": {
            "$ref": "#/components/responses/Conflict",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "429": {
            "$ref": "#/components/responses/TooManyRequests",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "500": {
            "$ref": "#/components/responses/InternalServerError",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          }
        },
        "x-codeSamples": [
          {
            "lang": "cURL",
            "label": "cURL",
            "source": "curl -X GET \"https://api.kangopenbanking.com/v1/sla/metrics\" \\\n  -H \"Authorization: Bearer $KOB_ACCESS_TOKEN\" \\\n  -H \"Content-Type: application/json\""
          },
          {
            "lang": "JavaScript",
            "label": "Node.js",
            "source": "import { KangOpenBanking } from \"@kangopenbanking/sdk\";\n\nconst kob = new KangOpenBanking({ apiKey: process.env.KOB_API_KEY });\nconst res = await kob.request(\"GET\", \"/v1/sla/metrics\");\nconsole.log(res);"
          },
          {
            "lang": "Python",
            "label": "Python",
            "source": "from kangopenbanking import KangOpenBanking\n\nkob = KangOpenBanking(api_key=os.environ[\"KOB_API_KEY\"])\nres = kob.request(\"GET\", \"/v1/sla/metrics\")\nprint(res)"
          },
          {
            "lang": "PHP",
            "label": "PHP",
            "source": "<?php\n$kob = new KangOpenBanking\\KangOpenBanking(getenv('KOB_API_KEY'));\n$res = $kob->request('GET', '/v1/sla/metrics');\nprint_r($res);"
          }
        ]
      },
      "post": {
        "tags": [
          "Monitoring"
        ],
        "summary": "Record SLA metric",
        "operationId": "slaMetricRecord",
        "security": [
          {
            "bearerAuth": []
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "required": [
                  "service_name"
                ],
                "properties": {
                  "service_name": {
                    "type": "string"
                  },
                  "uptime_pct": {
                    "type": "number"
                  },
                  "p50_ms": {
                    "type": "number"
                  },
                  "p95_ms": {
                    "type": "number"
                  },
                  "p99_ms": {
                    "type": "number"
                  },
                  "error_rate": {
                    "type": "number"
                  }
                }
              }
            }
          }
        },
        "responses": {
          "201": {
            "description": "Metric recorded",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "success": {
                      "type": "boolean",
                      "example": true
                    },
                    "message": {
                      "type": "string"
                    }
                  }
                },
                "example": {
                  "success": true,
                  "message": "string"
                }
              }
            },
            "headers": {
              "x-fapi-interaction-id": {
                "$ref": "#/components/headers/XFapiInteractionIdResponse"
              },
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/XRateLimitLimit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/XRateLimitRemaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/XRateLimitReset"
              },
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              },
              "traceparent": {
                "$ref": "#/components/headers/Traceparent"
              },
              "Content-Language": {
                "$ref": "#/components/headers/Content-Language"
              }
            }
          },
          "400": {
            "description": "Bad request",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              },
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                },
                "examples": {
                  "error": {
                    "$ref": "#/components/examples/ErrorBadRequest"
                  }
                }
              }
            },
            "headers": {
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/XRateLimitLimit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/XRateLimitRemaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/XRateLimitReset"
              },
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "403": {
            "$ref": "#/components/responses/Forbidden",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "404": {
            "$ref": "#/components/responses/NotFound",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "409": {
            "$ref": "#/components/responses/Conflict",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "429": {
            "$ref": "#/components/responses/TooManyRequests",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "500": {
            "$ref": "#/components/responses/InternalServerError",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          }
        },
        "parameters": [
          {
            "$ref": "#/components/parameters/RequestId"
          },
          {
            "$ref": "#/components/parameters/Traceparent"
          },
          {
            "$ref": "#/components/parameters/Tracestate"
          },
          {
            "$ref": "#/components/parameters/AcceptLanguage"
          }
        ],
        "x-codeSamples": [
          {
            "lang": "cURL",
            "label": "cURL",
            "source": "curl -X POST \"https://api.kangopenbanking.com/v1/sla/metrics\" \\\n  -H \"Authorization: Bearer $KOB_ACCESS_TOKEN\" \\\n  -H \"Content-Type: application/json\" \\\n  -d '{}'"
          },
          {
            "lang": "JavaScript",
            "label": "Node.js",
            "source": "import { KangOpenBanking } from \"@kangopenbanking/sdk\";\n\nconst kob = new KangOpenBanking({ apiKey: process.env.KOB_API_KEY });\nconst res = await kob.request(\"POST\", \"/v1/sla/metrics\", { /* payload */ });\nconsole.log(res);"
          },
          {
            "lang": "Python",
            "label": "Python",
            "source": "from kangopenbanking import KangOpenBanking\n\nkob = KangOpenBanking(api_key=os.environ[\"KOB_API_KEY\"])\nres = kob.request(\"POST\", \"/v1/sla/metrics\", json={})\nprint(res)"
          },
          {
            "lang": "PHP",
            "label": "PHP",
            "source": "<?php\n$kob = new KangOpenBanking\\KangOpenBanking(getenv('KOB_API_KEY'));\n$res = $kob->request('POST', '/v1/sla/metrics', []);\nprint_r($res);"
          }
        ]
      }
    },
    "/v1/sla/incidents": {
      "get": {
        "tags": [
          "Monitoring"
        ],
        "summary": "List incidents",
        "operationId": "slaIncidentList",
        "security": [
          {
            "bearerAuth": []
          }
        ],
        "parameters": [
          {
            "name": "status",
            "in": "query",
            "schema": {
              "type": "string",
              "enum": [
                "open",
                "investigating",
                "resolved"
              ]
            }
          },
          {
            "name": "limit",
            "in": "query",
            "schema": {
              "type": "integer",
              "default": 25,
              "maximum": 100
            },
            "description": "Items per page"
          },
          {
            "name": "offset",
            "in": "query",
            "schema": {
              "type": "integer",
              "default": 0
            },
            "description": "Items to skip"
          },
          {
            "name": "sort_by",
            "in": "query",
            "schema": {
              "type": "string",
              "default": "created_at"
            },
            "description": "Sort field"
          },
          {
            "name": "sort_order",
            "in": "query",
            "schema": {
              "type": "string",
              "enum": [
                "asc",
                "desc"
              ],
              "default": "desc"
            },
            "description": "Sort direction"
          },
          {
            "$ref": "#/components/parameters/StartingAfter"
          },
          {
            "$ref": "#/components/parameters/EndingBefore"
          },
          {
            "$ref": "#/components/parameters/RequestId"
          },
          {
            "$ref": "#/components/parameters/Traceparent"
          },
          {
            "$ref": "#/components/parameters/Tracestate"
          },
          {
            "$ref": "#/components/parameters/AcceptLanguage"
          }
        ],
        "responses": {
          "200": {
            "description": "Incident list",
            "content": {
              "application/json": {
                "schema": {
                  "allOf": [
                    {
                      "$ref": "#/components/schemas/PaginatedResponse"
                    },
                    {
                      "type": "object",
                      "properties": {
                        "data": {
                          "type": "array",
                          "items": {}
                        }
                      }
                    }
                  ]
                },
                "example": {
                  "data": [
                    {}
                  ],
                  "pagination": {
                    "page": 1,
                    "limit": 20,
                    "total": 150,
                    "has_next": true,
                    "next_cursor": "eyJpZCI6IjEyMyJ9"
                  },
                  "meta": {
                    "request_id": "550e8400-e29b-41d4-a716-446655440000",
                    "timestamp": "2025-03-27T12:00:00Z",
                    "api_version": "4.3.0"
                  }
                }
              }
            },
            "headers": {
              "x-fapi-interaction-id": {
                "$ref": "#/components/headers/XFapiInteractionIdResponse"
              },
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/XRateLimitLimit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/XRateLimitRemaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/XRateLimitReset"
              },
              "Cache-Control": {
                "$ref": "#/components/headers/CacheControl"
              },
              "ETag": {
                "$ref": "#/components/headers/ETag"
              },
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              },
              "traceparent": {
                "$ref": "#/components/headers/Traceparent"
              },
              "Content-Language": {
                "$ref": "#/components/headers/Content-Language"
              }
            }
          },
          "400": {
            "description": "Bad request",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              },
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                },
                "examples": {
                  "error": {
                    "$ref": "#/components/examples/ErrorBadRequest"
                  }
                }
              }
            },
            "headers": {
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/XRateLimitLimit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/XRateLimitRemaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/XRateLimitReset"
              },
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "403": {
            "$ref": "#/components/responses/Forbidden",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "404": {
            "$ref": "#/components/responses/NotFound",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "409": {
            "$ref": "#/components/responses/Conflict",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "429": {
            "$ref": "#/components/responses/TooManyRequests",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "500": {
            "$ref": "#/components/responses/InternalServerError",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          }
        },
        "x-codeSamples": [
          {
            "lang": "cURL",
            "label": "cURL",
            "source": "curl -X GET \"https://api.kangopenbanking.com/v1/sla/incidents\" \\\n  -H \"Authorization: Bearer $KOB_ACCESS_TOKEN\" \\\n  -H \"Content-Type: application/json\""
          },
          {
            "lang": "JavaScript",
            "label": "Node.js",
            "source": "import { KangOpenBanking } from \"@kangopenbanking/sdk\";\n\nconst kob = new KangOpenBanking({ apiKey: process.env.KOB_API_KEY });\nconst res = await kob.request(\"GET\", \"/v1/sla/incidents\");\nconsole.log(res);"
          },
          {
            "lang": "Python",
            "label": "Python",
            "source": "from kangopenbanking import KangOpenBanking\n\nkob = KangOpenBanking(api_key=os.environ[\"KOB_API_KEY\"])\nres = kob.request(\"GET\", \"/v1/sla/incidents\")\nprint(res)"
          },
          {
            "lang": "PHP",
            "label": "PHP",
            "source": "<?php\n$kob = new KangOpenBanking\\KangOpenBanking(getenv('KOB_API_KEY'));\n$res = $kob->request('GET', '/v1/sla/incidents');\nprint_r($res);"
          }
        ]
      },
      "post": {
        "tags": [
          "Monitoring"
        ],
        "summary": "Create incident",
        "operationId": "slaIncidentCreate",
        "security": [
          {
            "bearerAuth": []
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "required": [
                  "title",
                  "severity"
                ],
                "properties": {
                  "title": {
                    "type": "string"
                  },
                  "description": {
                    "type": "string"
                  },
                  "severity": {
                    "type": "string",
                    "enum": [
                      "low",
                      "medium",
                      "high",
                      "critical"
                    ]
                  },
                  "affected_services": {
                    "type": "array",
                    "items": {
                      "type": "string"
                    }
                  }
                }
              }
            }
          }
        },
        "responses": {
          "201": {
            "description": "Incident created",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "id": {
                      "type": "string"
                    },
                    "title": {
                      "type": "string"
                    },
                    "severity": {
                      "type": "string"
                    },
                    "status": {
                      "type": "string"
                    }
                  }
                },
                "example": {
                  "id": "string",
                  "title": "string",
                  "severity": "string",
                  "status": "string"
                }
              }
            },
            "headers": {
              "x-fapi-interaction-id": {
                "$ref": "#/components/headers/XFapiInteractionIdResponse"
              },
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/XRateLimitLimit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/XRateLimitRemaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/XRateLimitReset"
              },
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              },
              "traceparent": {
                "$ref": "#/components/headers/Traceparent"
              },
              "Content-Language": {
                "$ref": "#/components/headers/Content-Language"
              }
            }
          },
          "400": {
            "description": "Bad request",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              },
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                },
                "examples": {
                  "error": {
                    "$ref": "#/components/examples/ErrorBadRequest"
                  }
                }
              }
            },
            "headers": {
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/XRateLimitLimit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/XRateLimitRemaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/XRateLimitReset"
              },
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "403": {
            "$ref": "#/components/responses/Forbidden",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "404": {
            "$ref": "#/components/responses/NotFound",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "409": {
            "$ref": "#/components/responses/Conflict",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "429": {
            "$ref": "#/components/responses/TooManyRequests",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "500": {
            "$ref": "#/components/responses/InternalServerError",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          }
        },
        "parameters": [
          {
            "$ref": "#/components/parameters/RequestId"
          },
          {
            "$ref": "#/components/parameters/Traceparent"
          },
          {
            "$ref": "#/components/parameters/Tracestate"
          },
          {
            "$ref": "#/components/parameters/AcceptLanguage"
          }
        ],
        "x-codeSamples": [
          {
            "lang": "cURL",
            "label": "cURL",
            "source": "curl -X POST \"https://api.kangopenbanking.com/v1/sla/incidents\" \\\n  -H \"Authorization: Bearer $KOB_ACCESS_TOKEN\" \\\n  -H \"Content-Type: application/json\" \\\n  -d '{}'"
          },
          {
            "lang": "JavaScript",
            "label": "Node.js",
            "source": "import { KangOpenBanking } from \"@kangopenbanking/sdk\";\n\nconst kob = new KangOpenBanking({ apiKey: process.env.KOB_API_KEY });\nconst res = await kob.request(\"POST\", \"/v1/sla/incidents\", { /* payload */ });\nconsole.log(res);"
          },
          {
            "lang": "Python",
            "label": "Python",
            "source": "from kangopenbanking import KangOpenBanking\n\nkob = KangOpenBanking(api_key=os.environ[\"KOB_API_KEY\"])\nres = kob.request(\"POST\", \"/v1/sla/incidents\", json={})\nprint(res)"
          },
          {
            "lang": "PHP",
            "label": "PHP",
            "source": "<?php\n$kob = new KangOpenBanking\\KangOpenBanking(getenv('KOB_API_KEY'));\n$res = $kob->request('POST', '/v1/sla/incidents', []);\nprint_r($res);"
          }
        ]
      }
    },
    "/v1/sla/incidents/{incidentId}": {
      "patch": {
        "tags": [
          "Monitoring"
        ],
        "summary": "Update incident",
        "operationId": "slaIncidentUpdate",
        "security": [
          {
            "bearerAuth": []
          }
        ],
        "parameters": [
          {
            "name": "incidentId",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "$ref": "#/components/parameters/IdempotencyKey"
          },
          {
            "$ref": "#/components/parameters/RequestId"
          },
          {
            "$ref": "#/components/parameters/Traceparent"
          },
          {
            "$ref": "#/components/parameters/Tracestate"
          },
          {
            "$ref": "#/components/parameters/AcceptLanguage"
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "status": {
                    "type": "string",
                    "enum": [
                      "investigating",
                      "resolved"
                    ]
                  },
                  "resolution_notes": {
                    "type": "string"
                  }
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Incident updated",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "success": {
                      "type": "boolean",
                      "example": true
                    },
                    "message": {
                      "type": "string"
                    }
                  }
                },
                "example": {
                  "success": true,
                  "message": "string"
                }
              }
            },
            "headers": {
              "x-fapi-interaction-id": {
                "$ref": "#/components/headers/XFapiInteractionIdResponse"
              },
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/XRateLimitLimit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/XRateLimitRemaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/XRateLimitReset"
              },
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              },
              "traceparent": {
                "$ref": "#/components/headers/Traceparent"
              },
              "Content-Language": {
                "$ref": "#/components/headers/Content-Language"
              }
            }
          },
          "400": {
            "description": "Bad request",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              },
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                },
                "examples": {
                  "error": {
                    "$ref": "#/components/examples/ErrorBadRequest"
                  }
                }
              }
            },
            "headers": {
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/XRateLimitLimit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/XRateLimitRemaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/XRateLimitReset"
              },
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "403": {
            "$ref": "#/components/responses/Forbidden",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "404": {
            "$ref": "#/components/responses/NotFound",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "409": {
            "$ref": "#/components/responses/Conflict",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "429": {
            "$ref": "#/components/responses/TooManyRequests",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "500": {
            "$ref": "#/components/responses/InternalServerError",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          }
        },
        "x-codeSamples": [
          {
            "lang": "cURL",
            "label": "cURL",
            "source": "curl -X PATCH \"https://api.kangopenbanking.com/v1/sla/incidents/{incidentId}\" \\\n  -H \"Authorization: Bearer $KOB_ACCESS_TOKEN\" \\\n  -H \"Content-Type: application/json\" \\\n  -d '{}'"
          },
          {
            "lang": "JavaScript",
            "label": "Node.js",
            "source": "import { KangOpenBanking } from \"@kangopenbanking/sdk\";\n\nconst kob = new KangOpenBanking({ apiKey: process.env.KOB_API_KEY });\nconst res = await kob.request(\"PATCH\", \"/v1/sla/incidents/{incidentId}\", { /* payload */ });\nconsole.log(res);"
          },
          {
            "lang": "Python",
            "label": "Python",
            "source": "from kangopenbanking import KangOpenBanking\n\nkob = KangOpenBanking(api_key=os.environ[\"KOB_API_KEY\"])\nres = kob.request(\"PATCH\", \"/v1/sla/incidents/{incidentId}\", json={})\nprint(res)"
          },
          {
            "lang": "PHP",
            "label": "PHP",
            "source": "<?php\n$kob = new KangOpenBanking\\KangOpenBanking(getenv('KOB_API_KEY'));\n$res = $kob->request('PATCH', '/v1/sla/incidents/{incidentId}', []);\nprint_r($res);"
          }
        ]
      }
    },
    "/v1/webhooks/v2/endpoints": {
      "post": {
        "tags": [
          "Webhooks"
        ],
        "summary": "Register webhook endpoint (v2)",
        "description": "Register a new webhook endpoint with event filtering and unique signing secret. All delivered webhook payloads follow the WebhookEventPayload schema (see components/schemas/WebhookEventPayload). The data field contains the event-specific resource object referenced in the event type mapping.",
        "operationId": "webhookV2Create",
        "security": [
          {
            "bearerAuth": []
          }
        ],
        "parameters": [
          {
            "name": "Idempotency-Key",
            "in": "header",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid"
            },
            "description": "Required on all POST/PUT endpoints. Unique key for idempotent request processing (UUID v4 recommended). Keys expire after 24 hours."
          },
          {
            "$ref": "#/components/parameters/RequestId"
          },
          {
            "$ref": "#/components/parameters/Traceparent"
          },
          {
            "$ref": "#/components/parameters/Tracestate"
          },
          {
            "$ref": "#/components/parameters/AcceptLanguage"
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "required": [
                  "merchant_id",
                  "url",
                  "events"
                ],
                "properties": {
                  "merchant_id": {
                    "type": "string",
                    "format": "uuid"
                  },
                  "url": {
                    "type": "string",
                    "format": "uri"
                  },
                  "events": {
                    "type": "array",
                    "items": {
                      "type": "string",
                      "enum": [
                        "wildcard.*",
                        "charge.created",
                        "charge.captured",
                        "charge.voided",
                        "charge.failed",
                        "charge.cancelled",
                        "refund.created",
                        "refund.processed",
                        "refund.failed",
                        "payout.created",
                        "payout.processing",
                        "payout.completed",
                        "payout.failed",
                        "payment.initiated",
                        "payment.authorised",
                        "payment.submitted",
                        "payment.completed",
                        "payment.rejected",
                        "payment.cancelled",
                        "dispute.created",
                        "dispute.evidence_required",
                        "dispute.resolved",
                        "settlement.created",
                        "settlement.processed",
                        "consent.authorised",
                        "consent.revoked",
                        "consent.expired",
                        "loan.applied",
                        "loan.approved",
                        "loan.disbursed",
                        "loan.repaid",
                        "loan.defaulted",
                        "kyc.submitted",
                        "kyc.approved",
                        "kyc.rejected",
                        "mobile_money.charge_initiated",
                        "mobile_money.charge_completed",
                        "mobile_money.charge_failed",
                        "escrow.funded",
                        "escrow.released",
                        "escrow.refunded",
                        "virtual_account.credited",
                        "interbank.payment_submitted",
                        "interbank.payment_completed",
                        "interbank.payment_returned",
                        "pay_by_bank.intent_authorised",
                        "pay_by_bank.intent_rejected",
                        "pay_by_bank.payment_completed",
                        "subscription.created",
                        "subscription.renewed",
                        "subscription.cancelled",
                        "subscription.payment_failed"
                      ]
                    },
                    "description": "List of event types to subscribe to. Use 'wildcard.*' to subscribe to all events.",
                    "minItems": 1,
                    "example": [
                      "charge.created",
                      "charge.captured",
                      "refund.created"
                    ]
                  },
                  "description": {
                    "type": "string"
                  }
                }
              }
            }
          }
        },
        "responses": {
          "201": {
            "description": "Endpoint created with signing secret (shown once)",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "id": {
                      "type": "string"
                    },
                    "url": {
                      "type": "string"
                    },
                    "secret": {
                      "type": "string",
                      "description": "whsec_... — shown only on creation"
                    },
                    "events": {
                      "type": "array",
                      "items": {
                        "type": "string"
                      }
                    }
                  }
                },
                "example": {
                  "id": "string",
                  "url": "string",
                  "secret": "string",
                  "events": [
                    "string"
                  ]
                }
              }
            },
            "headers": {
              "x-fapi-interaction-id": {
                "$ref": "#/components/headers/XFapiInteractionIdResponse"
              },
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/XRateLimitLimit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/XRateLimitRemaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/XRateLimitReset"
              },
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              },
              "traceparent": {
                "$ref": "#/components/headers/Traceparent"
              },
              "Content-Language": {
                "$ref": "#/components/headers/Content-Language"
              }
            }
          },
          "400": {
            "description": "Bad request",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              },
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                },
                "examples": {
                  "error": {
                    "$ref": "#/components/examples/ErrorBadRequest"
                  }
                }
              }
            },
            "headers": {
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/XRateLimitLimit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/XRateLimitRemaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/XRateLimitReset"
              },
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "403": {
            "$ref": "#/components/responses/Forbidden",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "404": {
            "$ref": "#/components/responses/NotFound",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "409": {
            "$ref": "#/components/responses/Conflict",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "429": {
            "$ref": "#/components/responses/TooManyRequests",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "500": {
            "$ref": "#/components/responses/InternalServerError",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          }
        },
        "x-codeSamples": [
          {
            "lang": "cURL",
            "label": "cURL",
            "source": "curl -X POST \"https://api.kangopenbanking.com/v1/webhooks/v2/endpoints\" \\\n  -H \"Authorization: Bearer $KOB_ACCESS_TOKEN\" \\\n  -H \"Content-Type: application/json\" \\\n  -d '{}'"
          },
          {
            "lang": "JavaScript",
            "label": "Node.js",
            "source": "import { KangOpenBanking } from \"@kangopenbanking/sdk\";\n\nconst kob = new KangOpenBanking({ apiKey: process.env.KOB_API_KEY });\nconst res = await kob.request(\"POST\", \"/v1/webhooks/v2/endpoints\", { /* payload */ });\nconsole.log(res);"
          },
          {
            "lang": "Python",
            "label": "Python",
            "source": "from kangopenbanking import KangOpenBanking\n\nkob = KangOpenBanking(api_key=os.environ[\"KOB_API_KEY\"])\nres = kob.request(\"POST\", \"/v1/webhooks/v2/endpoints\", json={})\nprint(res)"
          },
          {
            "lang": "PHP",
            "label": "PHP",
            "source": "<?php\n$kob = new KangOpenBanking\\KangOpenBanking(getenv('KOB_API_KEY'));\n$res = $kob->request('POST', '/v1/webhooks/v2/endpoints', []);\nprint_r($res);"
          }
        ]
      },
      "get": {
        "tags": [
          "Webhooks"
        ],
        "summary": "List webhook endpoints (v2)",
        "operationId": "webhookV2List",
        "security": [
          {
            "bearerAuth": []
          }
        ],
        "parameters": [
          {
            "name": "merchant_id",
            "in": "query",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "$ref": "#/components/parameters/RequestId"
          },
          {
            "$ref": "#/components/parameters/Traceparent"
          },
          {
            "$ref": "#/components/parameters/Tracestate"
          },
          {
            "$ref": "#/components/parameters/AcceptLanguage"
          }
        ],
        "responses": {
          "200": {
            "description": "Webhook endpoints",
            "content": {
              "application/json": {
                "schema": {
                  "allOf": [
                    {
                      "$ref": "#/components/schemas/PaginatedResponse"
                    },
                    {
                      "type": "object",
                      "properties": {
                        "data": {
                          "type": "array",
                          "items": {}
                        }
                      }
                    }
                  ]
                },
                "example": {
                  "data": [
                    {}
                  ],
                  "pagination": {
                    "page": 1,
                    "limit": 20,
                    "total": 150,
                    "has_next": true,
                    "next_cursor": "eyJpZCI6IjEyMyJ9"
                  },
                  "meta": {
                    "request_id": "550e8400-e29b-41d4-a716-446655440000",
                    "timestamp": "2025-03-27T12:00:00Z",
                    "api_version": "4.3.0"
                  }
                }
              }
            },
            "headers": {
              "x-fapi-interaction-id": {
                "$ref": "#/components/headers/XFapiInteractionIdResponse"
              },
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/XRateLimitLimit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/XRateLimitRemaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/XRateLimitReset"
              },
              "Cache-Control": {
                "$ref": "#/components/headers/CacheControl"
              },
              "ETag": {
                "$ref": "#/components/headers/ETag"
              },
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              },
              "traceparent": {
                "$ref": "#/components/headers/Traceparent"
              },
              "Content-Language": {
                "$ref": "#/components/headers/Content-Language"
              }
            }
          },
          "400": {
            "description": "Bad request",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              },
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                },
                "examples": {
                  "error": {
                    "$ref": "#/components/examples/ErrorBadRequest"
                  }
                }
              }
            },
            "headers": {
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/XRateLimitLimit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/XRateLimitRemaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/XRateLimitReset"
              },
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "403": {
            "$ref": "#/components/responses/Forbidden",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "404": {
            "$ref": "#/components/responses/NotFound",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "409": {
            "$ref": "#/components/responses/Conflict",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "429": {
            "$ref": "#/components/responses/TooManyRequests",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "500": {
            "$ref": "#/components/responses/InternalServerError",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          }
        },
        "x-codeSamples": [
          {
            "lang": "cURL",
            "label": "cURL",
            "source": "curl -X GET \"https://api.kangopenbanking.com/v1/webhooks/v2/endpoints\" \\\n  -H \"Authorization: Bearer $KOB_ACCESS_TOKEN\" \\\n  -H \"Content-Type: application/json\""
          },
          {
            "lang": "JavaScript",
            "label": "Node.js",
            "source": "import { KangOpenBanking } from \"@kangopenbanking/sdk\";\n\nconst kob = new KangOpenBanking({ apiKey: process.env.KOB_API_KEY });\nconst res = await kob.request(\"GET\", \"/v1/webhooks/v2/endpoints\");\nconsole.log(res);"
          },
          {
            "lang": "Python",
            "label": "Python",
            "source": "from kangopenbanking import KangOpenBanking\n\nkob = KangOpenBanking(api_key=os.environ[\"KOB_API_KEY\"])\nres = kob.request(\"GET\", \"/v1/webhooks/v2/endpoints\")\nprint(res)"
          },
          {
            "lang": "PHP",
            "label": "PHP",
            "source": "<?php\n$kob = new KangOpenBanking\\KangOpenBanking(getenv('KOB_API_KEY'));\n$res = $kob->request('GET', '/v1/webhooks/v2/endpoints');\nprint_r($res);"
          }
        ]
      }
    },
    "/v1/webhooks/v2/endpoints/{endpointId}": {
      "patch": {
        "tags": [
          "Webhooks"
        ],
        "summary": "Update webhook endpoint",
        "operationId": "webhookV2Update",
        "security": [
          {
            "bearerAuth": []
          }
        ],
        "parameters": [
          {
            "name": "endpointId",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "$ref": "#/components/parameters/IdempotencyKey"
          },
          {
            "$ref": "#/components/parameters/RequestId"
          },
          {
            "$ref": "#/components/parameters/Traceparent"
          },
          {
            "$ref": "#/components/parameters/Tracestate"
          },
          {
            "$ref": "#/components/parameters/AcceptLanguage"
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "url": {
                    "type": "string"
                  },
                  "events": {
                    "type": "array",
                    "items": {
                      "type": "string"
                    }
                  },
                  "is_active": {
                    "type": "boolean"
                  }
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Endpoint updated",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "success": {
                      "type": "boolean",
                      "example": true
                    },
                    "message": {
                      "type": "string"
                    }
                  }
                },
                "example": {
                  "success": true,
                  "message": "string"
                }
              }
            },
            "headers": {
              "x-fapi-interaction-id": {
                "$ref": "#/components/headers/XFapiInteractionIdResponse"
              },
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/XRateLimitLimit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/XRateLimitRemaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/XRateLimitReset"
              },
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              },
              "traceparent": {
                "$ref": "#/components/headers/Traceparent"
              },
              "Content-Language": {
                "$ref": "#/components/headers/Content-Language"
              }
            }
          },
          "400": {
            "description": "Bad request",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              },
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                },
                "examples": {
                  "error": {
                    "$ref": "#/components/examples/ErrorBadRequest"
                  }
                }
              }
            },
            "headers": {
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/XRateLimitLimit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/XRateLimitRemaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/XRateLimitReset"
              },
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "403": {
            "$ref": "#/components/responses/Forbidden",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "404": {
            "$ref": "#/components/responses/NotFound",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "409": {
            "$ref": "#/components/responses/Conflict",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "429": {
            "$ref": "#/components/responses/TooManyRequests",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "500": {
            "$ref": "#/components/responses/InternalServerError",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          }
        },
        "x-codeSamples": [
          {
            "lang": "cURL",
            "label": "cURL",
            "source": "curl -X PATCH \"https://api.kangopenbanking.com/v1/webhooks/v2/endpoints/{endpointId}\" \\\n  -H \"Authorization: Bearer $KOB_ACCESS_TOKEN\" \\\n  -H \"Content-Type: application/json\" \\\n  -d '{}'"
          },
          {
            "lang": "JavaScript",
            "label": "Node.js",
            "source": "import { KangOpenBanking } from \"@kangopenbanking/sdk\";\n\nconst kob = new KangOpenBanking({ apiKey: process.env.KOB_API_KEY });\nconst res = await kob.request(\"PATCH\", \"/v1/webhooks/v2/endpoints/{endpointId}\", { /* payload */ });\nconsole.log(res);"
          },
          {
            "lang": "Python",
            "label": "Python",
            "source": "from kangopenbanking import KangOpenBanking\n\nkob = KangOpenBanking(api_key=os.environ[\"KOB_API_KEY\"])\nres = kob.request(\"PATCH\", \"/v1/webhooks/v2/endpoints/{endpointId}\", json={})\nprint(res)"
          },
          {
            "lang": "PHP",
            "label": "PHP",
            "source": "<?php\n$kob = new KangOpenBanking\\KangOpenBanking(getenv('KOB_API_KEY'));\n$res = $kob->request('PATCH', '/v1/webhooks/v2/endpoints/{endpointId}', []);\nprint_r($res);"
          }
        ]
      },
      "delete": {
        "tags": [
          "Webhooks"
        ],
        "summary": "Delete webhook endpoint",
        "operationId": "webhookV2Delete",
        "security": [
          {
            "bearerAuth": []
          }
        ],
        "parameters": [
          {
            "name": "endpointId",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "$ref": "#/components/parameters/RequestId"
          },
          {
            "$ref": "#/components/parameters/Traceparent"
          },
          {
            "$ref": "#/components/parameters/Tracestate"
          },
          {
            "$ref": "#/components/parameters/AcceptLanguage"
          }
        ],
        "responses": {
          "204": {
            "description": "Endpoint deleted",
            "headers": {
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/XRateLimitLimit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/XRateLimitRemaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/XRateLimitReset"
              },
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              },
              "traceparent": {
                "$ref": "#/components/headers/Traceparent"
              },
              "Content-Language": {
                "$ref": "#/components/headers/Content-Language"
              }
            }
          },
          "400": {
            "description": "Bad request",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              },
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                },
                "examples": {
                  "error": {
                    "$ref": "#/components/examples/ErrorBadRequest"
                  }
                }
              }
            },
            "headers": {
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/XRateLimitLimit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/XRateLimitRemaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/XRateLimitReset"
              },
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "403": {
            "$ref": "#/components/responses/Forbidden",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "404": {
            "$ref": "#/components/responses/NotFound",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "409": {
            "$ref": "#/components/responses/Conflict",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "429": {
            "$ref": "#/components/responses/TooManyRequests",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "500": {
            "$ref": "#/components/responses/InternalServerError",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          }
        },
        "x-codeSamples": [
          {
            "lang": "cURL",
            "label": "cURL",
            "source": "curl -X DELETE \"https://api.kangopenbanking.com/v1/webhooks/v2/endpoints/{endpointId}\" \\\n  -H \"Authorization: Bearer $KOB_ACCESS_TOKEN\" \\\n  -H \"Content-Type: application/json\""
          },
          {
            "lang": "JavaScript",
            "label": "Node.js",
            "source": "import { KangOpenBanking } from \"@kangopenbanking/sdk\";\n\nconst kob = new KangOpenBanking({ apiKey: process.env.KOB_API_KEY });\nconst res = await kob.request(\"DELETE\", \"/v1/webhooks/v2/endpoints/{endpointId}\");\nconsole.log(res);"
          },
          {
            "lang": "Python",
            "label": "Python",
            "source": "from kangopenbanking import KangOpenBanking\n\nkob = KangOpenBanking(api_key=os.environ[\"KOB_API_KEY\"])\nres = kob.request(\"DELETE\", \"/v1/webhooks/v2/endpoints/{endpointId}\")\nprint(res)"
          },
          {
            "lang": "PHP",
            "label": "PHP",
            "source": "<?php\n$kob = new KangOpenBanking\\KangOpenBanking(getenv('KOB_API_KEY'));\n$res = $kob->request('DELETE', '/v1/webhooks/v2/endpoints/{endpointId}');\nprint_r($res);"
          }
        ]
      }
    },
    "/v1/webhooks/v2/deliveries": {
      "get": {
        "tags": [
          "Webhooks"
        ],
        "summary": "List webhook deliveries",
        "description": "View delivery attempts and retry history.",
        "operationId": "webhookV2Deliveries",
        "security": [
          {
            "bearerAuth": []
          }
        ],
        "parameters": [
          {
            "name": "endpoint_id",
            "in": "query",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "status",
            "in": "query",
            "schema": {
              "type": "string",
              "enum": [
                "pending",
                "delivered",
                "failed"
              ]
            }
          },
          {
            "name": "limit",
            "in": "query",
            "schema": {
              "type": "integer",
              "default": 25,
              "maximum": 100
            },
            "description": "Items per page"
          },
          {
            "name": "offset",
            "in": "query",
            "schema": {
              "type": "integer",
              "default": 0
            },
            "description": "Items to skip"
          },
          {
            "name": "sort_by",
            "in": "query",
            "schema": {
              "type": "string",
              "default": "created_at"
            },
            "description": "Sort field"
          },
          {
            "name": "sort_order",
            "in": "query",
            "schema": {
              "type": "string",
              "enum": [
                "asc",
                "desc"
              ],
              "default": "desc"
            },
            "description": "Sort direction"
          },
          {
            "$ref": "#/components/parameters/StartingAfter"
          },
          {
            "$ref": "#/components/parameters/EndingBefore"
          },
          {
            "$ref": "#/components/parameters/RequestId"
          },
          {
            "$ref": "#/components/parameters/Traceparent"
          },
          {
            "$ref": "#/components/parameters/Tracestate"
          },
          {
            "$ref": "#/components/parameters/AcceptLanguage"
          }
        ],
        "responses": {
          "200": {
            "description": "Delivery logs",
            "content": {
              "application/json": {
                "schema": {
                  "allOf": [
                    {
                      "$ref": "#/components/schemas/PaginatedResponse"
                    },
                    {
                      "type": "object",
                      "properties": {
                        "data": {
                          "type": "array",
                          "items": {}
                        }
                      }
                    }
                  ]
                },
                "example": {
                  "data": [
                    {}
                  ],
                  "pagination": {
                    "page": 1,
                    "limit": 20,
                    "total": 150,
                    "has_next": true,
                    "next_cursor": "eyJpZCI6IjEyMyJ9"
                  },
                  "meta": {
                    "request_id": "550e8400-e29b-41d4-a716-446655440000",
                    "timestamp": "2025-03-27T12:00:00Z",
                    "api_version": "4.3.0"
                  }
                }
              }
            },
            "headers": {
              "x-fapi-interaction-id": {
                "$ref": "#/components/headers/XFapiInteractionIdResponse"
              },
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/XRateLimitLimit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/XRateLimitRemaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/XRateLimitReset"
              },
              "Cache-Control": {
                "$ref": "#/components/headers/CacheControl"
              },
              "ETag": {
                "$ref": "#/components/headers/ETag"
              },
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              },
              "traceparent": {
                "$ref": "#/components/headers/Traceparent"
              },
              "Content-Language": {
                "$ref": "#/components/headers/Content-Language"
              }
            }
          },
          "400": {
            "description": "Bad request",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              },
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                },
                "examples": {
                  "error": {
                    "$ref": "#/components/examples/ErrorBadRequest"
                  }
                }
              }
            },
            "headers": {
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/XRateLimitLimit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/XRateLimitRemaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/XRateLimitReset"
              },
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "403": {
            "$ref": "#/components/responses/Forbidden",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "404": {
            "$ref": "#/components/responses/NotFound",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "409": {
            "$ref": "#/components/responses/Conflict",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "429": {
            "$ref": "#/components/responses/TooManyRequests",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "500": {
            "$ref": "#/components/responses/InternalServerError",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          }
        },
        "x-codeSamples": [
          {
            "lang": "cURL",
            "label": "cURL",
            "source": "curl -X GET \"https://api.kangopenbanking.com/v1/webhooks/v2/deliveries\" \\\n  -H \"Authorization: Bearer $KOB_ACCESS_TOKEN\" \\\n  -H \"Content-Type: application/json\""
          },
          {
            "lang": "JavaScript",
            "label": "Node.js",
            "source": "import { KangOpenBanking } from \"@kangopenbanking/sdk\";\n\nconst kob = new KangOpenBanking({ apiKey: process.env.KOB_API_KEY });\nconst res = await kob.request(\"GET\", \"/v1/webhooks/v2/deliveries\");\nconsole.log(res);"
          },
          {
            "lang": "Python",
            "label": "Python",
            "source": "from kangopenbanking import KangOpenBanking\n\nkob = KangOpenBanking(api_key=os.environ[\"KOB_API_KEY\"])\nres = kob.request(\"GET\", \"/v1/webhooks/v2/deliveries\")\nprint(res)"
          },
          {
            "lang": "PHP",
            "label": "PHP",
            "source": "<?php\n$kob = new KangOpenBanking\\KangOpenBanking(getenv('KOB_API_KEY'));\n$res = $kob->request('GET', '/v1/webhooks/v2/deliveries');\nprint_r($res);"
          }
        ]
      }
    },
    "/v1/sandbox/payout-sim": {
      "post": {
        "tags": [
          "Sandbox"
        ],
        "summary": "Simulate payout scenario",
        "description": "Run a payout through a pre-seeded sandbox scenario (e.g. insufficient_funds, network_timeout, reversed_after_success).",
        "operationId": "sandboxPayoutSim",
        "security": [
          {
            "bearerAuth": []
          }
        ],
        "parameters": [
          {
            "name": "Idempotency-Key",
            "in": "header",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid"
            },
            "description": "Required on all POST/PUT endpoints. Unique key for idempotent request processing (UUID v4 recommended). Keys expire after 24 hours."
          },
          {
            "$ref": "#/components/parameters/RequestId"
          },
          {
            "$ref": "#/components/parameters/Traceparent"
          },
          {
            "$ref": "#/components/parameters/Tracestate"
          },
          {
            "$ref": "#/components/parameters/AcceptLanguage"
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "required": [
                  "scenario",
                  "amount",
                  "currency"
                ],
                "properties": {
                  "scenario": {
                    "type": "string",
                    "enum": [
                      "instant_success",
                      "delayed_success",
                      "insufficient_funds",
                      "network_timeout",
                      "compliance_hold",
                      "reversed_after_success",
                      "partial_failure"
                    ]
                  },
                  "amount": {
                    "type": "string",
                    "pattern": "^[0-9]{1,15}$",
                    "description": "Represented as a string integer in the currency's minor unit (XAF has no subunits). Must be consistent with the currency field."
                  },
                  "currency": {
                    "type": "string",
                    "enum": [
                      "XAF",
                      "XOF",
                      "USD",
                      "EUR",
                      "GBP",
                      "CNY",
                      "NGN",
                      "GHS",
                      "KES",
                      "ZAR"
                    ],
                    "default": "XAF",
                    "description": "ISO 4217 currency code. Default is XAF (Central African CFA Franc)."
                  },
                  "merchant_id": {
                    "type": "string",
                    "format": "uuid"
                  },
                  "webhook_url": {
                    "type": "string",
                    "format": "uri"
                  }
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Simulation result with timeline and webhook callbacks",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "scenario": {
                      "type": "string"
                    },
                    "payout": {
                      "$ref": "#/components/schemas/GatewayPayout"
                    },
                    "timeline": {
                      "type": "array",
                      "items": {
                        "type": "object",
                        "properties": {
                          "event": {
                            "type": "string"
                          },
                          "timestamp": {
                            "type": "string"
                          },
                          "status": {
                            "type": "string"
                          }
                        }
                      }
                    }
                  }
                },
                "example": {
                  "scenario": "string",
                  "payout": {
                    "id": "00000000-0000-4000-8000-000000000000",
                    "merchant_id": "00000000-0000-4000-8000-000000000000",
                    "amount": "10000",
                    "currency": "XAF",
                    "channel": "mobile_money",
                    "status": "pending",
                    "beneficiary_name": "string",
                    "beneficiary_phone": "string",
                    "tx_ref": "string",
                    "created_at": "2026-01-01T00:00:00Z"
                  },
                  "timeline": [
                    {
                      "event": "string",
                      "timestamp": "string",
                      "status": "string"
                    }
                  ]
                }
              }
            },
            "headers": {
              "x-fapi-interaction-id": {
                "$ref": "#/components/headers/XFapiInteractionIdResponse"
              },
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/XRateLimitLimit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/XRateLimitRemaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/XRateLimitReset"
              },
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              },
              "traceparent": {
                "$ref": "#/components/headers/Traceparent"
              },
              "Content-Language": {
                "$ref": "#/components/headers/Content-Language"
              }
            }
          },
          "400": {
            "description": "Bad request",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              },
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                },
                "examples": {
                  "error": {
                    "$ref": "#/components/examples/ErrorBadRequest"
                  }
                }
              }
            },
            "headers": {
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/XRateLimitLimit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/XRateLimitRemaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/XRateLimitReset"
              },
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "403": {
            "$ref": "#/components/responses/Forbidden",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "404": {
            "$ref": "#/components/responses/NotFound",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "409": {
            "$ref": "#/components/responses/Conflict",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "429": {
            "$ref": "#/components/responses/TooManyRequests",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "500": {
            "$ref": "#/components/responses/InternalServerError",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          }
        },
        "x-codeSamples": [
          {
            "lang": "cURL",
            "label": "cURL",
            "source": "curl -X POST \"https://api.kangopenbanking.com/v1/sandbox/payout-sim\" \\\n  -H \"Authorization: Bearer $KOB_ACCESS_TOKEN\" \\\n  -H \"Content-Type: application/json\" \\\n  -d '{}'"
          },
          {
            "lang": "JavaScript",
            "label": "Node.js",
            "source": "import { KangOpenBanking } from \"@kangopenbanking/sdk\";\n\nconst kob = new KangOpenBanking({ apiKey: process.env.KOB_API_KEY });\nconst res = await kob.request(\"POST\", \"/v1/sandbox/payout-sim\", { /* payload */ });\nconsole.log(res);"
          },
          {
            "lang": "Python",
            "label": "Python",
            "source": "from kangopenbanking import KangOpenBanking\n\nkob = KangOpenBanking(api_key=os.environ[\"KOB_API_KEY\"])\nres = kob.request(\"POST\", \"/v1/sandbox/payout-sim\", json={})\nprint(res)"
          },
          {
            "lang": "PHP",
            "label": "PHP",
            "source": "<?php\n$kob = new KangOpenBanking\\KangOpenBanking(getenv('KOB_API_KEY'));\n$res = $kob->request('POST', '/v1/sandbox/payout-sim', []);\nprint_r($res);"
          }
        ]
      },
      "get": {
        "tags": [
          "Sandbox"
        ],
        "summary": "List sandbox scenarios",
        "operationId": "sandboxScenarioList",
        "security": [
          {
            "bearerAuth": []
          }
        ],
        "responses": {
          "200": {
            "description": "Available sandbox payout scenarios",
            "content": {
              "application/json": {
                "schema": {
                  "allOf": [
                    {
                      "$ref": "#/components/schemas/PaginatedResponse"
                    },
                    {
                      "type": "object",
                      "properties": {
                        "data": {
                          "type": "array",
                          "items": {}
                        }
                      }
                    }
                  ]
                },
                "example": {
                  "data": [
                    {}
                  ],
                  "pagination": {
                    "page": 1,
                    "limit": 20,
                    "total": 150,
                    "has_next": true,
                    "next_cursor": "eyJpZCI6IjEyMyJ9"
                  },
                  "meta": {
                    "request_id": "550e8400-e29b-41d4-a716-446655440000",
                    "timestamp": "2025-03-27T12:00:00Z",
                    "api_version": "4.3.0"
                  }
                }
              }
            },
            "headers": {
              "x-fapi-interaction-id": {
                "$ref": "#/components/headers/XFapiInteractionIdResponse"
              },
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/XRateLimitLimit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/XRateLimitRemaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/XRateLimitReset"
              },
              "Cache-Control": {
                "$ref": "#/components/headers/CacheControl"
              },
              "ETag": {
                "$ref": "#/components/headers/ETag"
              },
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              },
              "traceparent": {
                "$ref": "#/components/headers/Traceparent"
              },
              "Content-Language": {
                "$ref": "#/components/headers/Content-Language"
              }
            }
          },
          "400": {
            "description": "Bad request",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              },
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                },
                "examples": {
                  "error": {
                    "$ref": "#/components/examples/ErrorBadRequest"
                  }
                }
              }
            },
            "headers": {
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/XRateLimitLimit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/XRateLimitRemaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/XRateLimitReset"
              },
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "403": {
            "$ref": "#/components/responses/Forbidden",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "404": {
            "$ref": "#/components/responses/NotFound",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "409": {
            "$ref": "#/components/responses/Conflict",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "429": {
            "$ref": "#/components/responses/TooManyRequests",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "500": {
            "$ref": "#/components/responses/InternalServerError",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          }
        },
        "parameters": [
          {
            "$ref": "#/components/parameters/RequestId"
          },
          {
            "$ref": "#/components/parameters/Traceparent"
          },
          {
            "$ref": "#/components/parameters/Tracestate"
          },
          {
            "$ref": "#/components/parameters/AcceptLanguage"
          }
        ],
        "x-codeSamples": [
          {
            "lang": "cURL",
            "label": "cURL",
            "source": "curl -X GET \"https://api.kangopenbanking.com/v1/sandbox/payout-sim\" \\\n  -H \"Authorization: Bearer $KOB_ACCESS_TOKEN\" \\\n  -H \"Content-Type: application/json\""
          },
          {
            "lang": "JavaScript",
            "label": "Node.js",
            "source": "import { KangOpenBanking } from \"@kangopenbanking/sdk\";\n\nconst kob = new KangOpenBanking({ apiKey: process.env.KOB_API_KEY });\nconst res = await kob.request(\"GET\", \"/v1/sandbox/payout-sim\");\nconsole.log(res);"
          },
          {
            "lang": "Python",
            "label": "Python",
            "source": "from kangopenbanking import KangOpenBanking\n\nkob = KangOpenBanking(api_key=os.environ[\"KOB_API_KEY\"])\nres = kob.request(\"GET\", \"/v1/sandbox/payout-sim\")\nprint(res)"
          },
          {
            "lang": "PHP",
            "label": "PHP",
            "source": "<?php\n$kob = new KangOpenBanking\\KangOpenBanking(getenv('KOB_API_KEY'));\n$res = $kob->request('GET', '/v1/sandbox/payout-sim');\nprint_r($res);"
          }
        ]
      }
    },
    "/v1/reconciliation/mismatches": {
      "get": {
        "tags": [
          "Payment Gateway"
        ],
        "summary": "List reconciliation mismatches",
        "operationId": "reconciliationMismatches",
        "security": [
          {
            "bearerAuth": []
          }
        ],
        "parameters": [
          {
            "name": "merchant_id",
            "in": "query",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "status",
            "in": "query",
            "schema": {
              "type": "string",
              "enum": [
                "open",
                "resolved",
                "ignored"
              ]
            }
          },
          {
            "name": "limit",
            "in": "query",
            "schema": {
              "type": "integer",
              "default": 25,
              "maximum": 100
            },
            "description": "Items per page"
          },
          {
            "name": "offset",
            "in": "query",
            "schema": {
              "type": "integer",
              "default": 0
            },
            "description": "Items to skip"
          },
          {
            "name": "sort_by",
            "in": "query",
            "schema": {
              "type": "string",
              "default": "created_at"
            },
            "description": "Sort field"
          },
          {
            "name": "sort_order",
            "in": "query",
            "schema": {
              "type": "string",
              "enum": [
                "asc",
                "desc"
              ],
              "default": "desc"
            },
            "description": "Sort direction"
          },
          {
            "$ref": "#/components/parameters/StartingAfter"
          },
          {
            "$ref": "#/components/parameters/EndingBefore"
          },
          {
            "$ref": "#/components/parameters/RequestId"
          },
          {
            "$ref": "#/components/parameters/Traceparent"
          },
          {
            "$ref": "#/components/parameters/Tracestate"
          },
          {
            "$ref": "#/components/parameters/AcceptLanguage"
          }
        ],
        "responses": {
          "200": {
            "description": "Mismatch list",
            "content": {
              "application/json": {
                "schema": {
                  "allOf": [
                    {
                      "$ref": "#/components/schemas/PaginatedResponse"
                    },
                    {
                      "type": "object",
                      "properties": {
                        "data": {
                          "type": "array",
                          "items": {}
                        }
                      }
                    }
                  ]
                },
                "example": {
                  "data": [
                    {}
                  ],
                  "pagination": {
                    "page": 1,
                    "limit": 20,
                    "total": 150,
                    "has_next": true,
                    "next_cursor": "eyJpZCI6IjEyMyJ9"
                  },
                  "meta": {
                    "request_id": "550e8400-e29b-41d4-a716-446655440000",
                    "timestamp": "2025-03-27T12:00:00Z",
                    "api_version": "4.3.0"
                  }
                }
              }
            },
            "headers": {
              "x-fapi-interaction-id": {
                "$ref": "#/components/headers/XFapiInteractionIdResponse"
              },
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/XRateLimitLimit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/XRateLimitRemaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/XRateLimitReset"
              },
              "Cache-Control": {
                "$ref": "#/components/headers/CacheControl"
              },
              "ETag": {
                "$ref": "#/components/headers/ETag"
              },
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              },
              "traceparent": {
                "$ref": "#/components/headers/Traceparent"
              },
              "Content-Language": {
                "$ref": "#/components/headers/Content-Language"
              }
            }
          },
          "400": {
            "description": "Bad request",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              },
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                },
                "examples": {
                  "error": {
                    "$ref": "#/components/examples/ErrorBadRequest"
                  }
                }
              }
            },
            "headers": {
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/XRateLimitLimit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/XRateLimitRemaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/XRateLimitReset"
              },
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "403": {
            "$ref": "#/components/responses/Forbidden",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "404": {
            "$ref": "#/components/responses/NotFound",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "409": {
            "$ref": "#/components/responses/Conflict",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "429": {
            "$ref": "#/components/responses/TooManyRequests",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "500": {
            "$ref": "#/components/responses/InternalServerError",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          }
        },
        "x-codeSamples": [
          {
            "lang": "cURL",
            "label": "cURL",
            "source": "curl -X GET \"https://api.kangopenbanking.com/v1/reconciliation/mismatches\" \\\n  -H \"Authorization: Bearer $KOB_ACCESS_TOKEN\" \\\n  -H \"Content-Type: application/json\""
          },
          {
            "lang": "JavaScript",
            "label": "Node.js",
            "source": "import { KangOpenBanking } from \"@kangopenbanking/sdk\";\n\nconst kob = new KangOpenBanking({ apiKey: process.env.KOB_API_KEY });\nconst res = await kob.request(\"GET\", \"/v1/reconciliation/mismatches\");\nconsole.log(res);"
          },
          {
            "lang": "Python",
            "label": "Python",
            "source": "from kangopenbanking import KangOpenBanking\n\nkob = KangOpenBanking(api_key=os.environ[\"KOB_API_KEY\"])\nres = kob.request(\"GET\", \"/v1/reconciliation/mismatches\")\nprint(res)"
          },
          {
            "lang": "PHP",
            "label": "PHP",
            "source": "<?php\n$kob = new KangOpenBanking\\KangOpenBanking(getenv('KOB_API_KEY'));\n$res = $kob->request('GET', '/v1/reconciliation/mismatches');\nprint_r($res);"
          }
        ]
      }
    },
    "/v1/reconciliation/mismatches/{mismatchId}/resolve": {
      "post": {
        "tags": [
          "Payment Gateway"
        ],
        "summary": "Resolve mismatch",
        "operationId": "reconciliationResolve",
        "security": [
          {
            "bearerAuth": []
          }
        ],
        "parameters": [
          {
            "name": "mismatchId",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "$ref": "#/components/parameters/RequestId"
          },
          {
            "$ref": "#/components/parameters/Traceparent"
          },
          {
            "$ref": "#/components/parameters/Tracestate"
          },
          {
            "$ref": "#/components/parameters/AcceptLanguage"
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "required": [
                  "resolution"
                ],
                "properties": {
                  "resolution": {
                    "type": "string",
                    "enum": [
                      "adjust_ledger",
                      "adjust_provider",
                      "ignore"
                    ]
                  },
                  "notes": {
                    "type": "string"
                  }
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Mismatch resolved",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "success": {
                      "type": "boolean",
                      "example": true
                    },
                    "message": {
                      "type": "string"
                    }
                  }
                },
                "example": {
                  "success": true,
                  "message": "string"
                }
              }
            },
            "headers": {
              "x-fapi-interaction-id": {
                "$ref": "#/components/headers/XFapiInteractionIdResponse"
              },
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/XRateLimitLimit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/XRateLimitRemaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/XRateLimitReset"
              },
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              },
              "traceparent": {
                "$ref": "#/components/headers/Traceparent"
              },
              "Content-Language": {
                "$ref": "#/components/headers/Content-Language"
              }
            }
          },
          "400": {
            "description": "Bad request",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              },
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                },
                "examples": {
                  "error": {
                    "$ref": "#/components/examples/ErrorBadRequest"
                  }
                }
              }
            },
            "headers": {
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/XRateLimitLimit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/XRateLimitRemaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/XRateLimitReset"
              },
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "403": {
            "$ref": "#/components/responses/Forbidden",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "404": {
            "$ref": "#/components/responses/NotFound",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "409": {
            "$ref": "#/components/responses/Conflict",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "429": {
            "$ref": "#/components/responses/TooManyRequests",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "500": {
            "$ref": "#/components/responses/InternalServerError",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          }
        },
        "x-codeSamples": [
          {
            "lang": "cURL",
            "label": "cURL",
            "source": "curl -X POST \"https://api.kangopenbanking.com/v1/reconciliation/mismatches/{mismatchId}/resolve\" \\\n  -H \"Authorization: Bearer $KOB_ACCESS_TOKEN\" \\\n  -H \"Content-Type: application/json\" \\\n  -d '{}'"
          },
          {
            "lang": "JavaScript",
            "label": "Node.js",
            "source": "import { KangOpenBanking } from \"@kangopenbanking/sdk\";\n\nconst kob = new KangOpenBanking({ apiKey: process.env.KOB_API_KEY });\nconst res = await kob.request(\"POST\", \"/v1/reconciliation/mismatches/{mismatchId}/resolve\", { /* payload */ });\nconsole.log(res);"
          },
          {
            "lang": "Python",
            "label": "Python",
            "source": "from kangopenbanking import KangOpenBanking\n\nkob = KangOpenBanking(api_key=os.environ[\"KOB_API_KEY\"])\nres = kob.request(\"POST\", \"/v1/reconciliation/mismatches/{mismatchId}/resolve\", json={})\nprint(res)"
          },
          {
            "lang": "PHP",
            "label": "PHP",
            "source": "<?php\n$kob = new KangOpenBanking\\KangOpenBanking(getenv('KOB_API_KEY'));\n$res = $kob->request('POST', '/v1/reconciliation/mismatches/{mismatchId}/resolve', []);\nprint_r($res);"
          }
        ]
      }
    },
    "/v1/directory/banks": {
      "get": {
        "tags": [
          "Bank Directory"
        ],
        "summary": "List active banks",
        "description": "Public directory of active banks integrated with KOB.",
        "operationId": "directoryBanksList",
        "responses": {
          "200": {
            "description": "List of active banks",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "banks": {
                      "type": "array",
                      "items": {
                        "$ref": "#/components/schemas/Bank"
                      }
                    }
                  }
                },
                "example": {
                  "banks": [
                    {
                      "id": "00000000-0000-4000-8000-000000000000",
                      "legal_name": "Afriland First Bank",
                      "display_name": "string",
                      "short_code": "AFB",
                      "country": "CM",
                      "swift_bic": "AFRIACMCXXX",
                      "bank_code": "string",
                      "status": "draft",
                      "integration_mode": "connector_push",
                      "contact_email": "string",
                      "support_phone": "string"
                    }
                  ]
                }
              }
            },
            "headers": {
              "x-fapi-interaction-id": {
                "$ref": "#/components/headers/XFapiInteractionIdResponse"
              },
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/XRateLimitLimit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/XRateLimitRemaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/XRateLimitReset"
              },
              "Cache-Control": {
                "$ref": "#/components/headers/CacheControl"
              },
              "ETag": {
                "$ref": "#/components/headers/ETag"
              },
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              },
              "traceparent": {
                "$ref": "#/components/headers/Traceparent"
              },
              "Content-Language": {
                "$ref": "#/components/headers/Content-Language"
              }
            }
          },
          "400": {
            "description": "Bad request",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              },
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                },
                "examples": {
                  "error": {
                    "$ref": "#/components/examples/ErrorBadRequest"
                  }
                }
              }
            },
            "headers": {
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/XRateLimitLimit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/XRateLimitRemaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/XRateLimitReset"
              },
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "403": {
            "$ref": "#/components/responses/Forbidden",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "404": {
            "$ref": "#/components/responses/NotFound",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "409": {
            "$ref": "#/components/responses/Conflict",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "429": {
            "$ref": "#/components/responses/TooManyRequests",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "500": {
            "$ref": "#/components/responses/InternalServerError",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          }
        },
        "parameters": [
          {
            "$ref": "#/components/parameters/RequestId"
          },
          {
            "$ref": "#/components/parameters/Traceparent"
          },
          {
            "$ref": "#/components/parameters/Tracestate"
          },
          {
            "$ref": "#/components/parameters/AcceptLanguage"
          }
        ],
        "x-codeSamples": [
          {
            "lang": "cURL",
            "label": "cURL",
            "source": "curl -X GET \"https://api.kangopenbanking.com/v1/directory/banks\" \\\n  -H \"Authorization: Bearer $KOB_ACCESS_TOKEN\" \\\n  -H \"Content-Type: application/json\""
          },
          {
            "lang": "JavaScript",
            "label": "Node.js",
            "source": "import { KangOpenBanking } from \"@kangopenbanking/sdk\";\n\nconst kob = new KangOpenBanking({ apiKey: process.env.KOB_API_KEY });\nconst res = await kob.request(\"GET\", \"/v1/directory/banks\");\nconsole.log(res);"
          },
          {
            "lang": "Python",
            "label": "Python",
            "source": "from kangopenbanking import KangOpenBanking\n\nkob = KangOpenBanking(api_key=os.environ[\"KOB_API_KEY\"])\nres = kob.request(\"GET\", \"/v1/directory/banks\")\nprint(res)"
          },
          {
            "lang": "PHP",
            "label": "PHP",
            "source": "<?php\n$kob = new KangOpenBanking\\KangOpenBanking(getenv('KOB_API_KEY'));\n$res = $kob->request('GET', '/v1/directory/banks');\nprint_r($res);"
          }
        ]
      }
    },
    "/v1/banks/register": {
      "post": {
        "tags": [
          "Bank Directory"
        ],
        "summary": "Register a bank",
        "description": "Register a new bank/ASPSP in the directory.",
        "operationId": "bankRegister",
        "security": [
          {
            "bearerAuth": []
          }
        ],
        "parameters": [
          {
            "name": "Idempotency-Key",
            "in": "header",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid"
            },
            "description": "Required on all POST/PUT endpoints. Unique key for idempotent request processing (UUID v4 recommended). Keys expire after 24 hours."
          },
          {
            "$ref": "#/components/parameters/RequestId"
          },
          {
            "$ref": "#/components/parameters/Traceparent"
          },
          {
            "$ref": "#/components/parameters/Tracestate"
          },
          {
            "$ref": "#/components/parameters/AcceptLanguage"
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "required": [
                  "legal_name",
                  "short_code"
                ],
                "properties": {
                  "legal_name": {
                    "type": "string",
                    "example": "Afriland First Bank"
                  },
                  "display_name": {
                    "type": "string"
                  },
                  "short_code": {
                    "type": "string",
                    "example": "AFB"
                  },
                  "swift_bic": {
                    "type": "string"
                  },
                  "bank_code": {
                    "type": "string"
                  },
                  "contact_email": {
                    "type": "string"
                  },
                  "support_phone": {
                    "type": "string"
                  },
                  "integration_mode": {
                    "type": "string",
                    "enum": [
                      "connector_push",
                      "connector_pull",
                      "file_feed",
                      "hybrid"
                    ]
                  }
                }
              }
            }
          }
        },
        "responses": {
          "201": {
            "description": "Bank registered",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Bank"
                },
                "example": {
                  "id": "00000000-0000-4000-8000-000000000000",
                  "legal_name": "Afriland First Bank",
                  "display_name": "string",
                  "short_code": "AFB",
                  "country": "CM",
                  "swift_bic": "AFRIACMCXXX",
                  "bank_code": "string",
                  "status": "draft",
                  "integration_mode": "connector_push",
                  "contact_email": "string",
                  "support_phone": "string"
                }
              }
            },
            "headers": {
              "x-fapi-interaction-id": {
                "$ref": "#/components/headers/XFapiInteractionIdResponse"
              },
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/XRateLimitLimit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/XRateLimitRemaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/XRateLimitReset"
              },
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              },
              "traceparent": {
                "$ref": "#/components/headers/Traceparent"
              },
              "Content-Language": {
                "$ref": "#/components/headers/Content-Language"
              }
            }
          },
          "400": {
            "description": "Bad request",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              },
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                },
                "examples": {
                  "error": {
                    "$ref": "#/components/examples/ErrorBadRequest"
                  }
                }
              }
            },
            "headers": {
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/XRateLimitLimit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/XRateLimitRemaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/XRateLimitReset"
              },
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "403": {
            "$ref": "#/components/responses/Forbidden",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "404": {
            "$ref": "#/components/responses/NotFound",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "409": {
            "$ref": "#/components/responses/Conflict",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "429": {
            "$ref": "#/components/responses/TooManyRequests",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "500": {
            "$ref": "#/components/responses/InternalServerError",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          }
        },
        "x-codeSamples": [
          {
            "lang": "cURL",
            "label": "cURL",
            "source": "curl -X POST \"https://api.kangopenbanking.com/v1/banks/register\" \\\n  -H \"Authorization: Bearer $KOB_ACCESS_TOKEN\" \\\n  -H \"Content-Type: application/json\" \\\n  -d '{}'"
          },
          {
            "lang": "JavaScript",
            "label": "Node.js",
            "source": "import { KangOpenBanking } from \"@kangopenbanking/sdk\";\n\nconst kob = new KangOpenBanking({ apiKey: process.env.KOB_API_KEY });\nconst res = await kob.request(\"POST\", \"/v1/banks/register\", { /* payload */ });\nconsole.log(res);"
          },
          {
            "lang": "Python",
            "label": "Python",
            "source": "from kangopenbanking import KangOpenBanking\n\nkob = KangOpenBanking(api_key=os.environ[\"KOB_API_KEY\"])\nres = kob.request(\"POST\", \"/v1/banks/register\", json={})\nprint(res)"
          },
          {
            "lang": "PHP",
            "label": "PHP",
            "source": "<?php\n$kob = new KangOpenBanking\\KangOpenBanking(getenv('KOB_API_KEY'));\n$res = $kob->request('POST', '/v1/banks/register', []);\nprint_r($res);"
          }
        ]
      }
    },
    "/v1/banks": {
      "get": {
        "tags": [
          "Bank Directory"
        ],
        "summary": "List all banks (admin)",
        "description": "Admin-only list of all banks including draft/suspended.",
        "operationId": "banksList",
        "security": [
          {
            "bearerAuth": []
          }
        ],
        "parameters": [
          {
            "name": "limit",
            "in": "query",
            "schema": {
              "type": "integer",
              "default": 25,
              "maximum": 100
            },
            "description": "Items per page"
          },
          {
            "name": "offset",
            "in": "query",
            "schema": {
              "type": "integer",
              "default": 0
            },
            "description": "Items to skip"
          },
          {
            "name": "sort_by",
            "in": "query",
            "schema": {
              "type": "string",
              "default": "created_at"
            },
            "description": "Sort field"
          },
          {
            "name": "sort_order",
            "in": "query",
            "schema": {
              "type": "string",
              "enum": [
                "asc",
                "desc"
              ],
              "default": "desc"
            },
            "description": "Sort direction"
          },
          {
            "$ref": "#/components/parameters/StartingAfter"
          },
          {
            "$ref": "#/components/parameters/EndingBefore"
          },
          {
            "$ref": "#/components/parameters/RequestId"
          },
          {
            "$ref": "#/components/parameters/Traceparent"
          },
          {
            "$ref": "#/components/parameters/Tracestate"
          },
          {
            "$ref": "#/components/parameters/AcceptLanguage"
          }
        ],
        "responses": {
          "200": {
            "description": "Banks list",
            "content": {
              "application/json": {
                "schema": {
                  "allOf": [
                    {
                      "$ref": "#/components/schemas/PaginatedResponse"
                    },
                    {
                      "type": "object",
                      "properties": {
                        "data": {
                          "type": "array",
                          "items": {
                            "$ref": "#/components/schemas/Bank"
                          }
                        }
                      }
                    }
                  ]
                },
                "example": {
                  "data": [
                    {
                      "id": "f1d6f4a0-1d4e-4a3a-9e0a-1a2b3c4d5e6f",
                      "legal_name": "Afriland First Bank",
                      "display_name": "XAF",
                      "short_code": "AFB",
                      "country": "CM",
                      "swift_bic": "AFRIACMCXXX",
                      "bank_code": "XAF",
                      "status": "draft",
                      "integration_mode": "connector_push",
                      "contact_email": "XAF",
                      "support_phone": "XAF"
                    }
                  ],
                  "pagination": {
                    "page": 1,
                    "limit": 20,
                    "total": 150,
                    "has_next": true,
                    "next_cursor": "eyJpZCI6IjEyMyJ9"
                  },
                  "meta": {
                    "request_id": "550e8400-e29b-41d4-a716-446655440000",
                    "timestamp": "2025-03-27T12:00:00Z",
                    "api_version": "4.3.0"
                  }
                }
              }
            },
            "headers": {
              "x-fapi-interaction-id": {
                "$ref": "#/components/headers/XFapiInteractionIdResponse"
              },
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/XRateLimitLimit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/XRateLimitRemaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/XRateLimitReset"
              },
              "Cache-Control": {
                "$ref": "#/components/headers/CacheControl"
              },
              "ETag": {
                "$ref": "#/components/headers/ETag"
              },
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              },
              "traceparent": {
                "$ref": "#/components/headers/Traceparent"
              },
              "Content-Language": {
                "$ref": "#/components/headers/Content-Language"
              }
            }
          },
          "400": {
            "description": "Bad request",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              },
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                },
                "examples": {
                  "error": {
                    "$ref": "#/components/examples/ErrorBadRequest"
                  }
                }
              }
            },
            "headers": {
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/XRateLimitLimit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/XRateLimitRemaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/XRateLimitReset"
              },
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "403": {
            "$ref": "#/components/responses/Forbidden",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "404": {
            "$ref": "#/components/responses/NotFound",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "409": {
            "$ref": "#/components/responses/Conflict",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "429": {
            "$ref": "#/components/responses/TooManyRequests",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "500": {
            "$ref": "#/components/responses/InternalServerError",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          }
        },
        "x-codeSamples": [
          {
            "lang": "cURL",
            "label": "cURL",
            "source": "curl -X GET \"https://api.kangopenbanking.com/v1/banks\" \\\n  -H \"Authorization: Bearer $KOB_ACCESS_TOKEN\" \\\n  -H \"Content-Type: application/json\""
          },
          {
            "lang": "JavaScript",
            "label": "Node.js",
            "source": "import { KangOpenBanking } from \"@kangopenbanking/sdk\";\n\nconst kob = new KangOpenBanking({ apiKey: process.env.KOB_API_KEY });\nconst res = await kob.request(\"GET\", \"/v1/banks\");\nconsole.log(res);"
          },
          {
            "lang": "Python",
            "label": "Python",
            "source": "from kangopenbanking import KangOpenBanking\n\nkob = KangOpenBanking(api_key=os.environ[\"KOB_API_KEY\"])\nres = kob.request(\"GET\", \"/v1/banks\")\nprint(res)"
          },
          {
            "lang": "PHP",
            "label": "PHP",
            "source": "<?php\n$kob = new KangOpenBanking\\KangOpenBanking(getenv('KOB_API_KEY'));\n$res = $kob->request('GET', '/v1/banks');\nprint_r($res);"
          }
        ]
      }
    },
    "/v1/banks/{bankId}": {
      "get": {
        "tags": [
          "Bank Directory"
        ],
        "summary": "Get bank details",
        "operationId": "banksGet",
        "security": [
          {
            "bearerAuth": []
          }
        ],
        "parameters": [
          {
            "name": "bankId",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          },
          {
            "$ref": "#/components/parameters/RequestId"
          },
          {
            "$ref": "#/components/parameters/Traceparent"
          },
          {
            "$ref": "#/components/parameters/Tracestate"
          },
          {
            "$ref": "#/components/parameters/AcceptLanguage"
          }
        ],
        "responses": {
          "200": {
            "description": "Bank details",
            "content": {
              "application/json": {
                "schema": {
                  "allOf": [
                    {
                      "$ref": "#/components/schemas/StandardResponse"
                    },
                    {
                      "type": "object",
                      "properties": {
                        "data": {
                          "$ref": "#/components/schemas/Bank"
                        }
                      }
                    }
                  ]
                },
                "example": {
                  "data": {
                    "id": "00000000-0000-4000-8000-000000000000",
                    "legal_name": "Afriland First Bank",
                    "display_name": "string",
                    "short_code": "AFB",
                    "country": "CM",
                    "swift_bic": "AFRIACMCXXX",
                    "bank_code": "string",
                    "status": "draft",
                    "integration_mode": "connector_push",
                    "contact_email": "string",
                    "support_phone": "string"
                  },
                  "meta": {
                    "request_id": "550e8400-e29b-41d4-a716-446655440000",
                    "timestamp": "2025-03-27T12:00:00Z",
                    "api_version": "4.3.0"
                  }
                }
              }
            },
            "headers": {
              "x-fapi-interaction-id": {
                "$ref": "#/components/headers/XFapiInteractionIdResponse"
              },
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/XRateLimitLimit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/XRateLimitRemaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/XRateLimitReset"
              },
              "Cache-Control": {
                "$ref": "#/components/headers/CacheControl"
              },
              "ETag": {
                "$ref": "#/components/headers/ETag"
              },
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              },
              "traceparent": {
                "$ref": "#/components/headers/Traceparent"
              },
              "Content-Language": {
                "$ref": "#/components/headers/Content-Language"
              }
            }
          },
          "400": {
            "description": "Bad request",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              },
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                },
                "examples": {
                  "error": {
                    "$ref": "#/components/examples/ErrorBadRequest"
                  }
                }
              }
            },
            "headers": {
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/XRateLimitLimit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/XRateLimitRemaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/XRateLimitReset"
              },
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "403": {
            "$ref": "#/components/responses/Forbidden",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "404": {
            "$ref": "#/components/responses/NotFound",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "409": {
            "$ref": "#/components/responses/Conflict",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "429": {
            "$ref": "#/components/responses/TooManyRequests",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "500": {
            "$ref": "#/components/responses/InternalServerError",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          }
        },
        "x-codeSamples": [
          {
            "lang": "cURL",
            "label": "cURL",
            "source": "curl -X GET \"https://api.kangopenbanking.com/v1/banks/{bankId}\" \\\n  -H \"Authorization: Bearer $KOB_ACCESS_TOKEN\" \\\n  -H \"Content-Type: application/json\""
          },
          {
            "lang": "JavaScript",
            "label": "Node.js",
            "source": "import { KangOpenBanking } from \"@kangopenbanking/sdk\";\n\nconst kob = new KangOpenBanking({ apiKey: process.env.KOB_API_KEY });\nconst res = await kob.request(\"GET\", \"/v1/banks/{bankId}\");\nconsole.log(res);"
          },
          {
            "lang": "Python",
            "label": "Python",
            "source": "from kangopenbanking import KangOpenBanking\n\nkob = KangOpenBanking(api_key=os.environ[\"KOB_API_KEY\"])\nres = kob.request(\"GET\", \"/v1/banks/{bankId}\")\nprint(res)"
          },
          {
            "lang": "PHP",
            "label": "PHP",
            "source": "<?php\n$kob = new KangOpenBanking\\KangOpenBanking(getenv('KOB_API_KEY'));\n$res = $kob->request('GET', '/v1/banks/{bankId}');\nprint_r($res);"
          }
        ]
      },
      "put": {
        "tags": [
          "Bank Directory"
        ],
        "summary": "Update bank",
        "operationId": "banksUpdate",
        "security": [
          {
            "bearerAuth": []
          }
        ],
        "parameters": [
          {
            "name": "bankId",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          },
          {
            "$ref": "#/components/parameters/RequestId"
          },
          {
            "$ref": "#/components/parameters/Traceparent"
          },
          {
            "$ref": "#/components/parameters/Tracestate"
          },
          {
            "$ref": "#/components/parameters/AcceptLanguage"
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "display_name": {
                    "type": "string"
                  },
                  "contact_email": {
                    "type": "string"
                  },
                  "support_phone": {
                    "type": "string"
                  },
                  "integration_mode": {
                    "type": "string"
                  }
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Bank updated",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Bank"
                },
                "example": {
                  "id": "00000000-0000-4000-8000-000000000000",
                  "legal_name": "Afriland First Bank",
                  "display_name": "string",
                  "short_code": "AFB",
                  "country": "CM",
                  "swift_bic": "AFRIACMCXXX",
                  "bank_code": "string",
                  "status": "draft",
                  "integration_mode": "connector_push",
                  "contact_email": "string",
                  "support_phone": "string"
                }
              }
            },
            "headers": {
              "x-fapi-interaction-id": {
                "$ref": "#/components/headers/XFapiInteractionIdResponse"
              },
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/XRateLimitLimit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/XRateLimitRemaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/XRateLimitReset"
              },
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              },
              "traceparent": {
                "$ref": "#/components/headers/Traceparent"
              },
              "Content-Language": {
                "$ref": "#/components/headers/Content-Language"
              }
            }
          },
          "400": {
            "description": "Bad request",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              },
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                },
                "examples": {
                  "error": {
                    "$ref": "#/components/examples/ErrorBadRequest"
                  }
                }
              }
            },
            "headers": {
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/XRateLimitLimit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/XRateLimitRemaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/XRateLimitReset"
              },
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "403": {
            "$ref": "#/components/responses/Forbidden",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "404": {
            "$ref": "#/components/responses/NotFound",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "409": {
            "$ref": "#/components/responses/Conflict",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "429": {
            "$ref": "#/components/responses/TooManyRequests",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "500": {
            "$ref": "#/components/responses/InternalServerError",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          }
        },
        "x-codeSamples": [
          {
            "lang": "cURL",
            "label": "cURL",
            "source": "curl -X PUT \"https://api.kangopenbanking.com/v1/banks/{bankId}\" \\\n  -H \"Authorization: Bearer $KOB_ACCESS_TOKEN\" \\\n  -H \"Content-Type: application/json\" \\\n  -d '{}'"
          },
          {
            "lang": "JavaScript",
            "label": "Node.js",
            "source": "import { KangOpenBanking } from \"@kangopenbanking/sdk\";\n\nconst kob = new KangOpenBanking({ apiKey: process.env.KOB_API_KEY });\nconst res = await kob.request(\"PUT\", \"/v1/banks/{bankId}\", { /* payload */ });\nconsole.log(res);"
          },
          {
            "lang": "Python",
            "label": "Python",
            "source": "from kangopenbanking import KangOpenBanking\n\nkob = KangOpenBanking(api_key=os.environ[\"KOB_API_KEY\"])\nres = kob.request(\"PUT\", \"/v1/banks/{bankId}\", json={})\nprint(res)"
          },
          {
            "lang": "PHP",
            "label": "PHP",
            "source": "<?php\n$kob = new KangOpenBanking\\KangOpenBanking(getenv('KOB_API_KEY'));\n$res = $kob->request('PUT', '/v1/banks/{bankId}', []);\nprint_r($res);"
          }
        ]
      }
    },
    "/v1/banks/{bankId}/approve": {
      "post": {
        "tags": [
          "Bank Directory"
        ],
        "summary": "Approve bank (admin)",
        "operationId": "bankApprove",
        "security": [
          {
            "bearerAuth": []
          }
        ],
        "parameters": [
          {
            "name": "bankId",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          },
          {
            "$ref": "#/components/parameters/RequestId"
          },
          {
            "$ref": "#/components/parameters/Traceparent"
          },
          {
            "$ref": "#/components/parameters/Tracestate"
          },
          {
            "$ref": "#/components/parameters/AcceptLanguage"
          }
        ],
        "responses": {
          "200": {
            "description": "Bank approved and set to active",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "success": {
                      "type": "boolean",
                      "example": true
                    },
                    "message": {
                      "type": "string"
                    }
                  }
                },
                "example": {
                  "success": true,
                  "message": "string"
                }
              }
            },
            "headers": {
              "x-fapi-interaction-id": {
                "$ref": "#/components/headers/XFapiInteractionIdResponse"
              },
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/XRateLimitLimit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/XRateLimitRemaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/XRateLimitReset"
              },
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              },
              "traceparent": {
                "$ref": "#/components/headers/Traceparent"
              },
              "Content-Language": {
                "$ref": "#/components/headers/Content-Language"
              }
            }
          },
          "400": {
            "description": "Bad request",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              },
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                },
                "examples": {
                  "error": {
                    "$ref": "#/components/examples/ErrorBadRequest"
                  }
                }
              }
            },
            "headers": {
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/XRateLimitLimit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/XRateLimitRemaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/XRateLimitReset"
              },
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "403": {
            "$ref": "#/components/responses/Forbidden",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "404": {
            "$ref": "#/components/responses/NotFound",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "409": {
            "$ref": "#/components/responses/Conflict",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "429": {
            "$ref": "#/components/responses/TooManyRequests",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "500": {
            "$ref": "#/components/responses/InternalServerError",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          }
        },
        "x-codeSamples": [
          {
            "lang": "cURL",
            "label": "cURL",
            "source": "curl -X POST \"https://api.kangopenbanking.com/v1/banks/{bankId}/approve\" \\\n  -H \"Authorization: Bearer $KOB_ACCESS_TOKEN\" \\\n  -H \"Content-Type: application/json\""
          },
          {
            "lang": "JavaScript",
            "label": "Node.js",
            "source": "import { KangOpenBanking } from \"@kangopenbanking/sdk\";\n\nconst kob = new KangOpenBanking({ apiKey: process.env.KOB_API_KEY });\nconst res = await kob.request(\"POST\", \"/v1/banks/{bankId}/approve\");\nconsole.log(res);"
          },
          {
            "lang": "Python",
            "label": "Python",
            "source": "from kangopenbanking import KangOpenBanking\n\nkob = KangOpenBanking(api_key=os.environ[\"KOB_API_KEY\"])\nres = kob.request(\"POST\", \"/v1/banks/{bankId}/approve\")\nprint(res)"
          },
          {
            "lang": "PHP",
            "label": "PHP",
            "source": "<?php\n$kob = new KangOpenBanking\\KangOpenBanking(getenv('KOB_API_KEY'));\n$res = $kob->request('POST', '/v1/banks/{bankId}/approve');\nprint_r($res);"
          }
        ]
      }
    },
    "/v1/banks/{bankId}/suspend": {
      "post": {
        "tags": [
          "Bank Directory"
        ],
        "summary": "Suspend bank (admin)",
        "operationId": "bankSuspend",
        "security": [
          {
            "bearerAuth": []
          }
        ],
        "parameters": [
          {
            "name": "bankId",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          },
          {
            "$ref": "#/components/parameters/RequestId"
          },
          {
            "$ref": "#/components/parameters/Traceparent"
          },
          {
            "$ref": "#/components/parameters/Tracestate"
          },
          {
            "$ref": "#/components/parameters/AcceptLanguage"
          }
        ],
        "responses": {
          "200": {
            "description": "Bank suspended",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "success": {
                      "type": "boolean",
                      "example": true
                    },
                    "message": {
                      "type": "string"
                    }
                  }
                },
                "example": {
                  "success": true,
                  "message": "string"
                }
              }
            },
            "headers": {
              "x-fapi-interaction-id": {
                "$ref": "#/components/headers/XFapiInteractionIdResponse"
              },
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/XRateLimitLimit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/XRateLimitRemaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/XRateLimitReset"
              },
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              },
              "traceparent": {
                "$ref": "#/components/headers/Traceparent"
              },
              "Content-Language": {
                "$ref": "#/components/headers/Content-Language"
              }
            }
          },
          "400": {
            "description": "Bad request",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              },
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                },
                "examples": {
                  "error": {
                    "$ref": "#/components/examples/ErrorBadRequest"
                  }
                }
              }
            },
            "headers": {
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/XRateLimitLimit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/XRateLimitRemaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/XRateLimitReset"
              },
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "403": {
            "$ref": "#/components/responses/Forbidden",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "404": {
            "$ref": "#/components/responses/NotFound",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "409": {
            "$ref": "#/components/responses/Conflict",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "429": {
            "$ref": "#/components/responses/TooManyRequests",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "500": {
            "$ref": "#/components/responses/InternalServerError",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          }
        },
        "x-codeSamples": [
          {
            "lang": "cURL",
            "label": "cURL",
            "source": "curl -X POST \"https://api.kangopenbanking.com/v1/banks/{bankId}/suspend\" \\\n  -H \"Authorization: Bearer $KOB_ACCESS_TOKEN\" \\\n  -H \"Content-Type: application/json\""
          },
          {
            "lang": "JavaScript",
            "label": "Node.js",
            "source": "import { KangOpenBanking } from \"@kangopenbanking/sdk\";\n\nconst kob = new KangOpenBanking({ apiKey: process.env.KOB_API_KEY });\nconst res = await kob.request(\"POST\", \"/v1/banks/{bankId}/suspend\");\nconsole.log(res);"
          },
          {
            "lang": "Python",
            "label": "Python",
            "source": "from kangopenbanking import KangOpenBanking\n\nkob = KangOpenBanking(api_key=os.environ[\"KOB_API_KEY\"])\nres = kob.request(\"POST\", \"/v1/banks/{bankId}/suspend\")\nprint(res)"
          },
          {
            "lang": "PHP",
            "label": "PHP",
            "source": "<?php\n$kob = new KangOpenBanking\\KangOpenBanking(getenv('KOB_API_KEY'));\n$res = $kob->request('POST', '/v1/banks/{bankId}/suspend');\nprint_r($res);"
          }
        ]
      }
    },
    "/v1/banks/{bankId}/connectors": {
      "get": {
        "tags": [
          "Bank Connectors"
        ],
        "summary": "List connectors",
        "operationId": "connectorsList",
        "security": [
          {
            "bearerAuth": []
          }
        ],
        "parameters": [
          {
            "name": "bankId",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          },
          {
            "$ref": "#/components/parameters/RequestId"
          },
          {
            "$ref": "#/components/parameters/Traceparent"
          },
          {
            "$ref": "#/components/parameters/Tracestate"
          },
          {
            "$ref": "#/components/parameters/AcceptLanguage"
          }
        ],
        "responses": {
          "200": {
            "description": "Connector instances list",
            "content": {
              "application/json": {
                "schema": {
                  "allOf": [
                    {
                      "$ref": "#/components/schemas/PaginatedResponse"
                    },
                    {
                      "type": "object",
                      "properties": {
                        "data": {
                          "type": "array",
                          "items": {}
                        }
                      }
                    }
                  ]
                },
                "example": {
                  "data": [
                    {}
                  ],
                  "pagination": {
                    "page": 1,
                    "limit": 20,
                    "total": 150,
                    "has_next": true,
                    "next_cursor": "eyJpZCI6IjEyMyJ9"
                  },
                  "meta": {
                    "request_id": "550e8400-e29b-41d4-a716-446655440000",
                    "timestamp": "2025-03-27T12:00:00Z",
                    "api_version": "4.3.0"
                  }
                }
              }
            },
            "headers": {
              "x-fapi-interaction-id": {
                "$ref": "#/components/headers/XFapiInteractionIdResponse"
              },
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/XRateLimitLimit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/XRateLimitRemaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/XRateLimitReset"
              },
              "Cache-Control": {
                "$ref": "#/components/headers/CacheControl"
              },
              "ETag": {
                "$ref": "#/components/headers/ETag"
              },
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              },
              "traceparent": {
                "$ref": "#/components/headers/Traceparent"
              },
              "Content-Language": {
                "$ref": "#/components/headers/Content-Language"
              }
            }
          },
          "400": {
            "description": "Bad request",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              },
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                },
                "examples": {
                  "error": {
                    "$ref": "#/components/examples/ErrorBadRequest"
                  }
                }
              }
            },
            "headers": {
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/XRateLimitLimit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/XRateLimitRemaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/XRateLimitReset"
              },
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "403": {
            "$ref": "#/components/responses/Forbidden",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "404": {
            "$ref": "#/components/responses/NotFound",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "409": {
            "$ref": "#/components/responses/Conflict",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "429": {
            "$ref": "#/components/responses/TooManyRequests",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "500": {
            "$ref": "#/components/responses/InternalServerError",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          }
        },
        "x-codeSamples": [
          {
            "lang": "cURL",
            "label": "cURL",
            "source": "curl -X GET \"https://api.kangopenbanking.com/v1/banks/{bankId}/connectors\" \\\n  -H \"Authorization: Bearer $KOB_ACCESS_TOKEN\" \\\n  -H \"Content-Type: application/json\""
          },
          {
            "lang": "JavaScript",
            "label": "Node.js",
            "source": "import { KangOpenBanking } from \"@kangopenbanking/sdk\";\n\nconst kob = new KangOpenBanking({ apiKey: process.env.KOB_API_KEY });\nconst res = await kob.request(\"GET\", \"/v1/banks/{bankId}/connectors\");\nconsole.log(res);"
          },
          {
            "lang": "Python",
            "label": "Python",
            "source": "from kangopenbanking import KangOpenBanking\n\nkob = KangOpenBanking(api_key=os.environ[\"KOB_API_KEY\"])\nres = kob.request(\"GET\", \"/v1/banks/{bankId}/connectors\")\nprint(res)"
          },
          {
            "lang": "PHP",
            "label": "PHP",
            "source": "<?php\n$kob = new KangOpenBanking\\KangOpenBanking(getenv('KOB_API_KEY'));\n$res = $kob->request('GET', '/v1/banks/{bankId}/connectors');\nprint_r($res);"
          }
        ]
      },
      "post": {
        "tags": [
          "Bank Connectors"
        ],
        "summary": "Register connector",
        "operationId": "connectorRegister",
        "security": [
          {
            "bearerAuth": []
          }
        ],
        "parameters": [
          {
            "name": "bankId",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          },
          {
            "name": "Idempotency-Key",
            "in": "header",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid"
            },
            "description": "Required on all POST/PUT endpoints. Unique key for idempotent request processing (UUID v4 recommended). Keys expire after 24 hours."
          },
          {
            "$ref": "#/components/parameters/RequestId"
          },
          {
            "$ref": "#/components/parameters/Traceparent"
          },
          {
            "$ref": "#/components/parameters/Tracestate"
          },
          {
            "$ref": "#/components/parameters/AcceptLanguage"
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "required": [
                  "name",
                  "environment"
                ],
                "properties": {
                  "name": {
                    "type": "string"
                  },
                  "environment": {
                    "type": "string",
                    "enum": [
                      "sandbox",
                      "prod"
                    ]
                  },
                  "base_url": {
                    "type": "string"
                  },
                  "connector_type": {
                    "type": "string",
                    "enum": [
                      "rest",
                      "iso20022",
                      "file"
                    ]
                  }
                }
              }
            }
          }
        },
        "responses": {
          "201": {
            "description": "Connector registered",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "success": {
                      "type": "boolean",
                      "example": true
                    },
                    "message": {
                      "type": "string"
                    }
                  }
                },
                "example": {
                  "success": true,
                  "message": "string"
                }
              }
            },
            "headers": {
              "x-fapi-interaction-id": {
                "$ref": "#/components/headers/XFapiInteractionIdResponse"
              },
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/XRateLimitLimit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/XRateLimitRemaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/XRateLimitReset"
              },
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              },
              "traceparent": {
                "$ref": "#/components/headers/Traceparent"
              },
              "Content-Language": {
                "$ref": "#/components/headers/Content-Language"
              }
            }
          },
          "400": {
            "description": "Bad request",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              },
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                },
                "examples": {
                  "error": {
                    "$ref": "#/components/examples/ErrorBadRequest"
                  }
                }
              }
            },
            "headers": {
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/XRateLimitLimit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/XRateLimitRemaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/XRateLimitReset"
              },
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "403": {
            "$ref": "#/components/responses/Forbidden",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "404": {
            "$ref": "#/components/responses/NotFound",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "409": {
            "$ref": "#/components/responses/Conflict",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "429": {
            "$ref": "#/components/responses/TooManyRequests",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "500": {
            "$ref": "#/components/responses/InternalServerError",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          }
        },
        "x-codeSamples": [
          {
            "lang": "cURL",
            "label": "cURL",
            "source": "curl -X POST \"https://api.kangopenbanking.com/v1/banks/{bankId}/connectors\" \\\n  -H \"Authorization: Bearer $KOB_ACCESS_TOKEN\" \\\n  -H \"Content-Type: application/json\" \\\n  -d '{}'"
          },
          {
            "lang": "JavaScript",
            "label": "Node.js",
            "source": "import { KangOpenBanking } from \"@kangopenbanking/sdk\";\n\nconst kob = new KangOpenBanking({ apiKey: process.env.KOB_API_KEY });\nconst res = await kob.request(\"POST\", \"/v1/banks/{bankId}/connectors\", { /* payload */ });\nconsole.log(res);"
          },
          {
            "lang": "Python",
            "label": "Python",
            "source": "from kangopenbanking import KangOpenBanking\n\nkob = KangOpenBanking(api_key=os.environ[\"KOB_API_KEY\"])\nres = kob.request(\"POST\", \"/v1/banks/{bankId}/connectors\", json={})\nprint(res)"
          },
          {
            "lang": "PHP",
            "label": "PHP",
            "source": "<?php\n$kob = new KangOpenBanking\\KangOpenBanking(getenv('KOB_API_KEY'));\n$res = $kob->request('POST', '/v1/banks/{bankId}/connectors', []);\nprint_r($res);"
          }
        ]
      }
    },
    "/v1/banks/{bankId}/connectors/{connectorId}/health": {
      "get": {
        "tags": [
          "Bank Connectors"
        ],
        "summary": "Connector health",
        "operationId": "connectorHealth",
        "security": [
          {
            "bearerAuth": []
          }
        ],
        "parameters": [
          {
            "name": "bankId",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          },
          {
            "name": "connectorId",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          },
          {
            "$ref": "#/components/parameters/RequestId"
          },
          {
            "$ref": "#/components/parameters/Traceparent"
          },
          {
            "$ref": "#/components/parameters/Tracestate"
          },
          {
            "$ref": "#/components/parameters/AcceptLanguage"
          }
        ],
        "responses": {
          "200": {
            "description": "Connector health status",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "status": {
                      "type": "string"
                    },
                    "latency_ms": {
                      "type": "number"
                    },
                    "last_check_at": {
                      "type": "string",
                      "format": "date-time"
                    }
                  }
                },
                "example": {
                  "status": "string",
                  "latency_ms": 0,
                  "last_check_at": "2026-01-01T00:00:00Z"
                }
              }
            },
            "headers": {
              "x-fapi-interaction-id": {
                "$ref": "#/components/headers/XFapiInteractionIdResponse"
              },
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/XRateLimitLimit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/XRateLimitRemaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/XRateLimitReset"
              },
              "Cache-Control": {
                "$ref": "#/components/headers/CacheControl"
              },
              "ETag": {
                "$ref": "#/components/headers/ETag"
              },
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              },
              "traceparent": {
                "$ref": "#/components/headers/Traceparent"
              },
              "Content-Language": {
                "$ref": "#/components/headers/Content-Language"
              }
            }
          },
          "400": {
            "description": "Bad request",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              },
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                },
                "examples": {
                  "error": {
                    "$ref": "#/components/examples/ErrorBadRequest"
                  }
                }
              }
            },
            "headers": {
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/XRateLimitLimit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/XRateLimitRemaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/XRateLimitReset"
              },
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "403": {
            "$ref": "#/components/responses/Forbidden",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "404": {
            "$ref": "#/components/responses/NotFound",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "409": {
            "$ref": "#/components/responses/Conflict",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "429": {
            "$ref": "#/components/responses/TooManyRequests",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "500": {
            "$ref": "#/components/responses/InternalServerError",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          }
        },
        "x-codeSamples": [
          {
            "lang": "cURL",
            "label": "cURL",
            "source": "curl -X GET \"https://api.kangopenbanking.com/v1/banks/{bankId}/connectors/{connectorId}/health\" \\\n  -H \"Authorization: Bearer $KOB_ACCESS_TOKEN\" \\\n  -H \"Content-Type: application/json\""
          },
          {
            "lang": "JavaScript",
            "label": "Node.js",
            "source": "import { KangOpenBanking } from \"@kangopenbanking/sdk\";\n\nconst kob = new KangOpenBanking({ apiKey: process.env.KOB_API_KEY });\nconst res = await kob.request(\"GET\", \"/v1/banks/{bankId}/connectors/{connectorId}/health\");\nconsole.log(res);"
          },
          {
            "lang": "Python",
            "label": "Python",
            "source": "from kangopenbanking import KangOpenBanking\n\nkob = KangOpenBanking(api_key=os.environ[\"KOB_API_KEY\"])\nres = kob.request(\"GET\", \"/v1/banks/{bankId}/connectors/{connectorId}/health\")\nprint(res)"
          },
          {
            "lang": "PHP",
            "label": "PHP",
            "source": "<?php\n$kob = new KangOpenBanking\\KangOpenBanking(getenv('KOB_API_KEY'));\n$res = $kob->request('GET', '/v1/banks/{bankId}/connectors/{connectorId}/health');\nprint_r($res);"
          }
        ]
      }
    },
    "/v1/banks/{bankId}/connectors/{connectorId}/certificates": {
      "post": {
        "tags": [
          "Bank Connectors"
        ],
        "summary": "Upload mTLS certificate",
        "operationId": "connectorCertUpload",
        "security": [
          {
            "bearerAuth": []
          }
        ],
        "parameters": [
          {
            "name": "bankId",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          },
          {
            "name": "connectorId",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          },
          {
            "$ref": "#/components/parameters/RequestId"
          },
          {
            "$ref": "#/components/parameters/Traceparent"
          },
          {
            "$ref": "#/components/parameters/Tracestate"
          },
          {
            "$ref": "#/components/parameters/AcceptLanguage"
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "required": [
                  "certificate_pem"
                ],
                "properties": {
                  "certificate_pem": {
                    "type": "string"
                  }
                }
              }
            }
          }
        },
        "responses": {
          "201": {
            "description": "Certificate uploaded",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "success": {
                      "type": "boolean",
                      "example": true
                    },
                    "message": {
                      "type": "string"
                    }
                  }
                },
                "example": {
                  "success": true,
                  "message": "string"
                }
              }
            },
            "headers": {
              "x-fapi-interaction-id": {
                "$ref": "#/components/headers/XFapiInteractionIdResponse"
              },
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/XRateLimitLimit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/XRateLimitRemaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/XRateLimitReset"
              },
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              },
              "traceparent": {
                "$ref": "#/components/headers/Traceparent"
              },
              "Content-Language": {
                "$ref": "#/components/headers/Content-Language"
              }
            }
          },
          "400": {
            "description": "Bad request",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              },
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                },
                "examples": {
                  "error": {
                    "$ref": "#/components/examples/ErrorBadRequest"
                  }
                }
              }
            },
            "headers": {
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/XRateLimitLimit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/XRateLimitRemaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/XRateLimitReset"
              },
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "403": {
            "$ref": "#/components/responses/Forbidden",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "404": {
            "$ref": "#/components/responses/NotFound",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "409": {
            "$ref": "#/components/responses/Conflict",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "429": {
            "$ref": "#/components/responses/TooManyRequests",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "500": {
            "$ref": "#/components/responses/InternalServerError",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          }
        },
        "x-codeSamples": [
          {
            "lang": "cURL",
            "label": "cURL",
            "source": "curl -X POST \"https://api.kangopenbanking.com/v1/banks/{bankId}/connectors/{connectorId}/certificates\" \\\n  -H \"Authorization: Bearer $KOB_ACCESS_TOKEN\" \\\n  -H \"Content-Type: application/json\" \\\n  -d '{}'"
          },
          {
            "lang": "JavaScript",
            "label": "Node.js",
            "source": "import { KangOpenBanking } from \"@kangopenbanking/sdk\";\n\nconst kob = new KangOpenBanking({ apiKey: process.env.KOB_API_KEY });\nconst res = await kob.request(\"POST\", \"/v1/banks/{bankId}/connectors/{connectorId}/certificates\", { /* payload */ });\nconsole.log(res);"
          },
          {
            "lang": "Python",
            "label": "Python",
            "source": "from kangopenbanking import KangOpenBanking\n\nkob = KangOpenBanking(api_key=os.environ[\"KOB_API_KEY\"])\nres = kob.request(\"POST\", \"/v1/banks/{bankId}/connectors/{connectorId}/certificates\", json={})\nprint(res)"
          },
          {
            "lang": "PHP",
            "label": "PHP",
            "source": "<?php\n$kob = new KangOpenBanking\\KangOpenBanking(getenv('KOB_API_KEY'));\n$res = $kob->request('POST', '/v1/banks/{bankId}/connectors/{connectorId}/certificates', []);\nprint_r($res);"
          }
        ]
      }
    },
    "/v1/internal/connectors/{bankId}/accounts": {
      "post": {
        "tags": [
          "Bank Connectors"
        ],
        "summary": "Bulk ingest accounts",
        "description": "Bank connector pushes account data (mTLS required).",
        "operationId": "connectorIngestAccounts",
        "security": [
          {
            "mtls": []
          }
        ],
        "parameters": [
          {
            "name": "bankId",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          },
          {
            "name": "Idempotency-Key",
            "in": "header",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid"
            },
            "description": "Required on all POST/PUT endpoints. Unique key for idempotent request processing (UUID v4 recommended). Keys expire after 24 hours."
          },
          {
            "$ref": "#/components/parameters/RequestId"
          },
          {
            "$ref": "#/components/parameters/Traceparent"
          },
          {
            "$ref": "#/components/parameters/Tracestate"
          },
          {
            "$ref": "#/components/parameters/AcceptLanguage"
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "required": [
                  "accounts"
                ],
                "properties": {
                  "accounts": {
                    "type": "array",
                    "items": {
                      "type": "object",
                      "properties": {
                        "external_account_id": {
                          "type": "string"
                        },
                        "account_type": {
                          "type": "string"
                        },
                        "currency": {
                          "type": "string",
                          "default": "XAF",
                          "enum": [
                            "XAF",
                            "XOF",
                            "USD",
                            "EUR",
                            "GBP",
                            "CNY",
                            "NGN",
                            "GHS",
                            "KES",
                            "ZAR"
                          ],
                          "description": "ISO 4217 currency code. Default is XAF (Central African CFA Franc)."
                        },
                        "nickname": {
                          "type": "string"
                        }
                      }
                    }
                  },
                  "correlation_id": {
                    "type": "string"
                  }
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Ingestion result with counts",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "inserted": {
                      "type": "integer"
                    },
                    "updated": {
                      "type": "integer"
                    },
                    "errors": {
                      "type": "integer"
                    },
                    "correlation_id": {
                      "type": "string"
                    }
                  }
                },
                "example": {
                  "inserted": 0,
                  "updated": 0,
                  "errors": 0,
                  "correlation_id": "string"
                }
              }
            },
            "headers": {
              "x-fapi-interaction-id": {
                "$ref": "#/components/headers/XFapiInteractionIdResponse"
              },
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/XRateLimitLimit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/XRateLimitRemaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/XRateLimitReset"
              },
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              },
              "traceparent": {
                "$ref": "#/components/headers/Traceparent"
              },
              "Content-Language": {
                "$ref": "#/components/headers/Content-Language"
              }
            }
          },
          "400": {
            "description": "Bad request",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              },
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                },
                "examples": {
                  "error": {
                    "$ref": "#/components/examples/ErrorBadRequest"
                  }
                }
              }
            },
            "headers": {
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/XRateLimitLimit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/XRateLimitRemaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/XRateLimitReset"
              },
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "403": {
            "$ref": "#/components/responses/Forbidden",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "404": {
            "$ref": "#/components/responses/NotFound",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "409": {
            "$ref": "#/components/responses/Conflict",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "429": {
            "$ref": "#/components/responses/TooManyRequests",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "500": {
            "$ref": "#/components/responses/InternalServerError",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          }
        },
        "x-codeSamples": [
          {
            "lang": "cURL",
            "label": "cURL",
            "source": "curl -X POST \"https://api.kangopenbanking.com/v1/internal/connectors/{bankId}/accounts\" \\\n  -H \"Authorization: Bearer $KOB_ACCESS_TOKEN\" \\\n  -H \"Content-Type: application/json\" \\\n  -d '{}'"
          },
          {
            "lang": "JavaScript",
            "label": "Node.js",
            "source": "import { KangOpenBanking } from \"@kangopenbanking/sdk\";\n\nconst kob = new KangOpenBanking({ apiKey: process.env.KOB_API_KEY });\nconst res = await kob.request(\"POST\", \"/v1/internal/connectors/{bankId}/accounts\", { /* payload */ });\nconsole.log(res);"
          },
          {
            "lang": "Python",
            "label": "Python",
            "source": "from kangopenbanking import KangOpenBanking\n\nkob = KangOpenBanking(api_key=os.environ[\"KOB_API_KEY\"])\nres = kob.request(\"POST\", \"/v1/internal/connectors/{bankId}/accounts\", json={})\nprint(res)"
          },
          {
            "lang": "PHP",
            "label": "PHP",
            "source": "<?php\n$kob = new KangOpenBanking\\KangOpenBanking(getenv('KOB_API_KEY'));\n$res = $kob->request('POST', '/v1/internal/connectors/{bankId}/accounts', []);\nprint_r($res);"
          }
        ]
      }
    },
    "/v1/internal/connectors/{bankId}/transactions": {
      "post": {
        "tags": [
          "Bank Connectors"
        ],
        "summary": "Bulk ingest transactions",
        "description": "Bank connector pushes transaction data (mTLS required).",
        "operationId": "connectorIngestTransactions",
        "security": [
          {
            "mtls": []
          }
        ],
        "parameters": [
          {
            "name": "bankId",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          },
          {
            "name": "Idempotency-Key",
            "in": "header",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid"
            },
            "description": "Required on all POST/PUT endpoints. Unique key for idempotent request processing (UUID v4 recommended). Keys expire after 24 hours."
          },
          {
            "$ref": "#/components/parameters/RequestId"
          },
          {
            "$ref": "#/components/parameters/Traceparent"
          },
          {
            "$ref": "#/components/parameters/Tracestate"
          },
          {
            "$ref": "#/components/parameters/AcceptLanguage"
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "required": [
                  "transactions"
                ],
                "properties": {
                  "transactions": {
                    "type": "array",
                    "items": {
                      "type": "object",
                      "properties": {
                        "external_tx_id": {
                          "type": "string"
                        },
                        "account_id": {
                          "type": "string"
                        },
                        "amount": {
                          "type": "string",
                          "pattern": "^[0-9]{1,15}$",
                          "description": "Represented as a string integer in the currency's minor unit (XAF has no subunits). Must be consistent with the currency field."
                        },
                        "currency": {
                          "type": "string",
                          "enum": [
                            "XAF",
                            "XOF",
                            "USD",
                            "EUR",
                            "GBP",
                            "CNY",
                            "NGN",
                            "GHS",
                            "KES",
                            "ZAR"
                          ],
                          "default": "XAF",
                          "description": "ISO 4217 currency code. Default is XAF (Central African CFA Franc)."
                        },
                        "credit_debit": {
                          "type": "string",
                          "enum": [
                            "credit",
                            "debit"
                          ]
                        },
                        "booking_date": {
                          "type": "string",
                          "format": "date"
                        },
                        "reference": {
                          "type": "string"
                        }
                      }
                    }
                  },
                  "correlation_id": {
                    "type": "string"
                  }
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Ingestion result",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "inserted": {
                      "type": "integer"
                    },
                    "updated": {
                      "type": "integer"
                    },
                    "errors": {
                      "type": "integer"
                    },
                    "correlation_id": {
                      "type": "string"
                    }
                  }
                },
                "example": {
                  "inserted": 0,
                  "updated": 0,
                  "errors": 0,
                  "correlation_id": "string"
                }
              }
            },
            "headers": {
              "x-fapi-interaction-id": {
                "$ref": "#/components/headers/XFapiInteractionIdResponse"
              },
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/XRateLimitLimit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/XRateLimitRemaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/XRateLimitReset"
              },
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              },
              "traceparent": {
                "$ref": "#/components/headers/Traceparent"
              },
              "Content-Language": {
                "$ref": "#/components/headers/Content-Language"
              }
            }
          },
          "400": {
            "description": "Bad request",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              },
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                },
                "examples": {
                  "error": {
                    "$ref": "#/components/examples/ErrorBadRequest"
                  }
                }
              }
            },
            "headers": {
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/XRateLimitLimit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/XRateLimitRemaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/XRateLimitReset"
              },
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "403": {
            "$ref": "#/components/responses/Forbidden",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "404": {
            "$ref": "#/components/responses/NotFound",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "409": {
            "$ref": "#/components/responses/Conflict",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "429": {
            "$ref": "#/components/responses/TooManyRequests",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "500": {
            "$ref": "#/components/responses/InternalServerError",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          }
        },
        "x-codeSamples": [
          {
            "lang": "cURL",
            "label": "cURL",
            "source": "curl -X POST \"https://api.kangopenbanking.com/v1/internal/connectors/{bankId}/transactions\" \\\n  -H \"Authorization: Bearer $KOB_ACCESS_TOKEN\" \\\n  -H \"Content-Type: application/json\" \\\n  -d '{}'"
          },
          {
            "lang": "JavaScript",
            "label": "Node.js",
            "source": "import { KangOpenBanking } from \"@kangopenbanking/sdk\";\n\nconst kob = new KangOpenBanking({ apiKey: process.env.KOB_API_KEY });\nconst res = await kob.request(\"POST\", \"/v1/internal/connectors/{bankId}/transactions\", { /* payload */ });\nconsole.log(res);"
          },
          {
            "lang": "Python",
            "label": "Python",
            "source": "from kangopenbanking import KangOpenBanking\n\nkob = KangOpenBanking(api_key=os.environ[\"KOB_API_KEY\"])\nres = kob.request(\"POST\", \"/v1/internal/connectors/{bankId}/transactions\", json={})\nprint(res)"
          },
          {
            "lang": "PHP",
            "label": "PHP",
            "source": "<?php\n$kob = new KangOpenBanking\\KangOpenBanking(getenv('KOB_API_KEY'));\n$res = $kob->request('POST', '/v1/internal/connectors/{bankId}/transactions', []);\nprint_r($res);"
          }
        ]
      }
    },
    "/v1/interbank/payments": {
      "get": {
        "tags": [
          "Interbank"
        ],
        "summary": "List interbank payments",
        "operationId": "interbankPaymentsList",
        "security": [
          {
            "bearerAuth": []
          }
        ],
        "parameters": [
          {
            "name": "status",
            "in": "query",
            "schema": {
              "type": "string",
              "enum": [
                "created",
                "validated",
                "submitted",
                "accepted",
                "rejected",
                "in_process",
                "settled",
                "failed",
                "reversed",
                "expired"
              ]
            }
          },
          {
            "name": "limit",
            "in": "query",
            "schema": {
              "type": "integer",
              "default": 25,
              "maximum": 100
            },
            "description": "Items per page"
          },
          {
            "name": "offset",
            "in": "query",
            "schema": {
              "type": "integer",
              "default": 0
            },
            "description": "Items to skip"
          },
          {
            "name": "sort_by",
            "in": "query",
            "schema": {
              "type": "string",
              "default": "created_at"
            },
            "description": "Sort field"
          },
          {
            "name": "sort_order",
            "in": "query",
            "schema": {
              "type": "string",
              "enum": [
                "asc",
                "desc"
              ],
              "default": "desc"
            },
            "description": "Sort direction"
          },
          {
            "$ref": "#/components/parameters/StartingAfter"
          },
          {
            "$ref": "#/components/parameters/EndingBefore"
          },
          {
            "$ref": "#/components/parameters/RequestId"
          },
          {
            "$ref": "#/components/parameters/Traceparent"
          },
          {
            "$ref": "#/components/parameters/Tracestate"
          },
          {
            "$ref": "#/components/parameters/AcceptLanguage"
          }
        ],
        "responses": {
          "200": {
            "description": "Interbank payments list",
            "content": {
              "application/json": {
                "schema": {
                  "allOf": [
                    {
                      "$ref": "#/components/schemas/PaginatedResponse"
                    },
                    {
                      "type": "object",
                      "properties": {
                        "data": {
                          "type": "array",
                          "items": {
                            "$ref": "#/components/schemas/InterbankPayment"
                          }
                        }
                      }
                    }
                  ]
                },
                "example": {
                  "data": [
                    {
                      "id": "f1d6f4a0-1d4e-4a3a-9e0a-1a2b3c4d5e6f",
                      "external_reference": "XAF",
                      "debtor_participant_id": "f1d6f4a0-1d4e-4a3a-9e0a-1a2b3c4d5e6f",
                      "creditor_participant_id": "f1d6f4a0-1d4e-4a3a-9e0a-1a2b3c4d5e6f",
                      "amount": "500000",
                      "currency": "XAF",
                      "status": "created",
                      "correlation_id": "XAF",
                      "requested_at": "2026-01-31T12:00:00Z",
                      "settled_at": "2026-01-31T12:00:00Z"
                    }
                  ],
                  "pagination": {
                    "page": 1,
                    "limit": 20,
                    "total": 150,
                    "has_next": true,
                    "next_cursor": "eyJpZCI6IjEyMyJ9"
                  },
                  "meta": {
                    "request_id": "550e8400-e29b-41d4-a716-446655440000",
                    "timestamp": "2025-03-27T12:00:00Z",
                    "api_version": "4.3.0"
                  }
                }
              }
            },
            "headers": {
              "x-fapi-interaction-id": {
                "$ref": "#/components/headers/XFapiInteractionIdResponse"
              },
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/XRateLimitLimit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/XRateLimitRemaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/XRateLimitReset"
              },
              "Cache-Control": {
                "$ref": "#/components/headers/CacheControl"
              },
              "ETag": {
                "$ref": "#/components/headers/ETag"
              },
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              },
              "traceparent": {
                "$ref": "#/components/headers/Traceparent"
              },
              "Content-Language": {
                "$ref": "#/components/headers/Content-Language"
              }
            }
          },
          "400": {
            "description": "Bad request",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              },
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                },
                "examples": {
                  "error": {
                    "$ref": "#/components/examples/ErrorBadRequest"
                  }
                }
              }
            },
            "headers": {
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/XRateLimitLimit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/XRateLimitRemaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/XRateLimitReset"
              },
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "403": {
            "$ref": "#/components/responses/Forbidden",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "404": {
            "$ref": "#/components/responses/NotFound",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "409": {
            "$ref": "#/components/responses/Conflict",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "429": {
            "$ref": "#/components/responses/TooManyRequests",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "500": {
            "$ref": "#/components/responses/InternalServerError",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          }
        },
        "x-iso20022-message": "pacs.002.001.12",
        "description": " Status responses conform to ISO 20022 pacs.002 (FIToFIPaymentStatusReport).",
        "x-codeSamples": [
          {
            "lang": "cURL",
            "label": "cURL",
            "source": "curl -X GET \"https://api.kangopenbanking.com/v1/interbank/payments\" \\\n  -H \"Authorization: Bearer $KOB_ACCESS_TOKEN\" \\\n  -H \"Content-Type: application/json\""
          },
          {
            "lang": "JavaScript",
            "label": "Node.js",
            "source": "import { KangOpenBanking } from \"@kangopenbanking/sdk\";\n\nconst kob = new KangOpenBanking({ apiKey: process.env.KOB_API_KEY });\nconst res = await kob.request(\"GET\", \"/v1/interbank/payments\");\nconsole.log(res);"
          },
          {
            "lang": "Python",
            "label": "Python",
            "source": "from kangopenbanking import KangOpenBanking\n\nkob = KangOpenBanking(api_key=os.environ[\"KOB_API_KEY\"])\nres = kob.request(\"GET\", \"/v1/interbank/payments\")\nprint(res)"
          },
          {
            "lang": "PHP",
            "label": "PHP",
            "source": "<?php\n$kob = new KangOpenBanking\\KangOpenBanking(getenv('KOB_API_KEY'));\n$res = $kob->request('GET', '/v1/interbank/payments');\nprint_r($res);"
          }
        ]
      },
      "post": {
        "tags": [
          "Interbank"
        ],
        "summary": "Create interbank payment",
        "operationId": "interbankPaymentCreate",
        "security": [
          {
            "bearerAuth": []
          }
        ],
        "parameters": [
          {
            "name": "Idempotency-Key",
            "in": "header",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid"
            },
            "description": "Required on all POST/PUT endpoints. Unique key for idempotent request processing (UUID v4 recommended). Keys expire after 24 hours."
          },
          {
            "$ref": "#/components/parameters/XFapiInteractionId"
          },
          {
            "$ref": "#/components/parameters/XFapiCustomerIpAddress"
          },
          {
            "$ref": "#/components/parameters/XFapiAuthDate"
          },
          {
            "$ref": "#/components/parameters/RequestId"
          },
          {
            "$ref": "#/components/parameters/Traceparent"
          },
          {
            "$ref": "#/components/parameters/Tracestate"
          },
          {
            "$ref": "#/components/parameters/AcceptLanguage"
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "required": [
                  "debtor_participant_id",
                  "creditor_participant_id",
                  "amount",
                  "currency"
                ],
                "properties": {
                  "debtor_participant_id": {
                    "type": "string",
                    "format": "uuid"
                  },
                  "creditor_participant_id": {
                    "type": "string",
                    "format": "uuid"
                  },
                  "debtor_account_ref": {
                    "type": "string"
                  },
                  "creditor_account_ref": {
                    "type": "string"
                  },
                  "amount": {
                    "type": "string",
                    "pattern": "^[0-9]{1,15}$",
                    "description": "Represented as a string integer in the currency's minor unit (XAF has no subunits). Must be consistent with the currency field."
                  },
                  "currency": {
                    "type": "string",
                    "default": "XAF",
                    "enum": [
                      "XAF",
                      "XOF",
                      "USD",
                      "EUR",
                      "GBP",
                      "CNY",
                      "NGN",
                      "GHS",
                      "KES",
                      "ZAR"
                    ],
                    "description": "ISO 4217 currency code. Default is XAF (Central African CFA Franc)."
                  },
                  "external_reference": {
                    "type": "string"
                  }
                }
              }
            }
          }
        },
        "responses": {
          "201": {
            "description": "Payment created",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/InterbankPayment"
                },
                "example": {
                  "id": "00000000-0000-4000-8000-000000000000",
                  "external_reference": "string",
                  "debtor_participant_id": "00000000-0000-4000-8000-000000000000",
                  "creditor_participant_id": "00000000-0000-4000-8000-000000000000",
                  "amount": "500000",
                  "currency": "XAF",
                  "status": "created",
                  "correlation_id": "string",
                  "requested_at": "2026-01-01T00:00:00Z",
                  "settled_at": "2026-01-01T00:00:00Z"
                }
              }
            },
            "headers": {
              "x-fapi-interaction-id": {
                "$ref": "#/components/headers/XFapiInteractionIdResponse"
              },
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/XRateLimitLimit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/XRateLimitRemaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/XRateLimitReset"
              },
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              },
              "X-Idempotent-Replay": {
                "$ref": "#/components/headers/X-Idempotent-Replay"
              },
              "X-Idempotency-Status": {
                "$ref": "#/components/headers/X-Idempotency-Status"
              },
              "traceparent": {
                "$ref": "#/components/headers/Traceparent"
              },
              "Content-Language": {
                "$ref": "#/components/headers/Content-Language"
              }
            }
          },
          "400": {
            "description": "Bad request",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              },
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                },
                "examples": {
                  "error": {
                    "$ref": "#/components/examples/ErrorBadRequest"
                  }
                }
              }
            },
            "headers": {
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/XRateLimitLimit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/XRateLimitRemaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/XRateLimitReset"
              },
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "403": {
            "$ref": "#/components/responses/Forbidden",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "404": {
            "$ref": "#/components/responses/NotFound",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "409": {
            "$ref": "#/components/responses/Conflict",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "429": {
            "$ref": "#/components/responses/TooManyRequests",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "500": {
            "$ref": "#/components/responses/InternalServerError",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          }
        },
        "x-iso20022-message": "pacs.008.001.10",
        "description": " Conforms to ISO 20022 pacs.008.001.10 (FIToFICustomerCreditTransfer). The request body maps to the CdtTrfTxInf block of a pacs.008 message.",
        "x-codeSamples": [
          {
            "lang": "cURL",
            "label": "cURL",
            "source": "curl -X POST \"https://api.kangopenbanking.com/v1/interbank/payments\" \\\n  -H \"Authorization: Bearer $KOB_ACCESS_TOKEN\" \\\n  -H \"Content-Type: application/json\" \\\n  -d '{}'"
          },
          {
            "lang": "JavaScript",
            "label": "Node.js",
            "source": "import { KangOpenBanking } from \"@kangopenbanking/sdk\";\n\nconst kob = new KangOpenBanking({ apiKey: process.env.KOB_API_KEY });\nconst res = await kob.request(\"POST\", \"/v1/interbank/payments\", { /* payload */ });\nconsole.log(res);"
          },
          {
            "lang": "Python",
            "label": "Python",
            "source": "from kangopenbanking import KangOpenBanking\n\nkob = KangOpenBanking(api_key=os.environ[\"KOB_API_KEY\"])\nres = kob.request(\"POST\", \"/v1/interbank/payments\", json={})\nprint(res)"
          },
          {
            "lang": "PHP",
            "label": "PHP",
            "source": "<?php\n$kob = new KangOpenBanking\\KangOpenBanking(getenv('KOB_API_KEY'));\n$res = $kob->request('POST', '/v1/interbank/payments', []);\nprint_r($res);"
          }
        ]
      }
    },
    "/v1/interbank/payments/{paymentId}": {
      "get": {
        "tags": [
          "Interbank"
        ],
        "summary": "Get interbank payment",
        "operationId": "interbankPaymentGet",
        "security": [
          {
            "bearerAuth": []
          }
        ],
        "parameters": [
          {
            "name": "paymentId",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          },
          {
            "$ref": "#/components/parameters/RequestId"
          },
          {
            "$ref": "#/components/parameters/Traceparent"
          },
          {
            "$ref": "#/components/parameters/Tracestate"
          },
          {
            "$ref": "#/components/parameters/AcceptLanguage"
          }
        ],
        "responses": {
          "200": {
            "description": "Payment details with status events",
            "content": {
              "application/json": {
                "schema": {
                  "allOf": [
                    {
                      "$ref": "#/components/schemas/StandardResponse"
                    },
                    {
                      "type": "object",
                      "properties": {
                        "data": {
                          "$ref": "#/components/schemas/InterbankPayment"
                        }
                      }
                    }
                  ]
                },
                "example": {
                  "data": {
                    "id": "00000000-0000-4000-8000-000000000000",
                    "external_reference": "string",
                    "debtor_participant_id": "00000000-0000-4000-8000-000000000000",
                    "creditor_participant_id": "00000000-0000-4000-8000-000000000000",
                    "amount": "500000",
                    "currency": "XAF",
                    "status": "created",
                    "correlation_id": "string",
                    "requested_at": "2026-01-01T00:00:00Z",
                    "settled_at": "2026-01-01T00:00:00Z"
                  },
                  "meta": {
                    "request_id": "550e8400-e29b-41d4-a716-446655440000",
                    "timestamp": "2025-03-27T12:00:00Z",
                    "api_version": "4.3.0"
                  }
                }
              }
            },
            "headers": {
              "x-fapi-interaction-id": {
                "$ref": "#/components/headers/XFapiInteractionIdResponse"
              },
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/XRateLimitLimit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/XRateLimitRemaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/XRateLimitReset"
              },
              "Cache-Control": {
                "$ref": "#/components/headers/CacheControl"
              },
              "ETag": {
                "$ref": "#/components/headers/ETag"
              },
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              },
              "traceparent": {
                "$ref": "#/components/headers/Traceparent"
              },
              "Content-Language": {
                "$ref": "#/components/headers/Content-Language"
              }
            }
          },
          "400": {
            "description": "Bad request",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              },
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                },
                "examples": {
                  "error": {
                    "$ref": "#/components/examples/ErrorBadRequest"
                  }
                }
              }
            },
            "headers": {
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/XRateLimitLimit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/XRateLimitRemaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/XRateLimitReset"
              },
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "403": {
            "$ref": "#/components/responses/Forbidden",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "404": {
            "$ref": "#/components/responses/NotFound",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "409": {
            "$ref": "#/components/responses/Conflict",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "429": {
            "$ref": "#/components/responses/TooManyRequests",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "500": {
            "$ref": "#/components/responses/InternalServerError",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          }
        },
        "x-codeSamples": [
          {
            "lang": "cURL",
            "label": "cURL",
            "source": "curl -X GET \"https://api.kangopenbanking.com/v1/interbank/payments/{paymentId}\" \\\n  -H \"Authorization: Bearer $KOB_ACCESS_TOKEN\" \\\n  -H \"Content-Type: application/json\""
          },
          {
            "lang": "JavaScript",
            "label": "Node.js",
            "source": "import { KangOpenBanking } from \"@kangopenbanking/sdk\";\n\nconst kob = new KangOpenBanking({ apiKey: process.env.KOB_API_KEY });\nconst res = await kob.request(\"GET\", \"/v1/interbank/payments/{paymentId}\");\nconsole.log(res);"
          },
          {
            "lang": "Python",
            "label": "Python",
            "source": "from kangopenbanking import KangOpenBanking\n\nkob = KangOpenBanking(api_key=os.environ[\"KOB_API_KEY\"])\nres = kob.request(\"GET\", \"/v1/interbank/payments/{paymentId}\")\nprint(res)"
          },
          {
            "lang": "PHP",
            "label": "PHP",
            "source": "<?php\n$kob = new KangOpenBanking\\KangOpenBanking(getenv('KOB_API_KEY'));\n$res = $kob->request('GET', '/v1/interbank/payments/{paymentId}');\nprint_r($res);"
          }
        ]
      }
    },
    "/v1/interbank/payments/{paymentId}/submit": {
      "post": {
        "tags": [
          "Interbank"
        ],
        "summary": "Submit interbank payment",
        "description": "Generates pacs.008 and dispatches to creditor bank.",
        "operationId": "interbankPaymentSubmit",
        "security": [
          {
            "bearerAuth": []
          }
        ],
        "parameters": [
          {
            "name": "paymentId",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          },
          {
            "$ref": "#/components/parameters/IdempotencyKey"
          },
          {
            "$ref": "#/components/parameters/RequestId"
          },
          {
            "$ref": "#/components/parameters/Traceparent"
          },
          {
            "$ref": "#/components/parameters/Tracestate"
          },
          {
            "$ref": "#/components/parameters/AcceptLanguage"
          }
        ],
        "responses": {
          "200": {
            "description": "Payment submitted with pacs.008 generated",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "success": {
                      "type": "boolean",
                      "example": true
                    },
                    "message": {
                      "type": "string"
                    }
                  }
                },
                "example": {
                  "success": true,
                  "message": "string"
                }
              }
            },
            "headers": {
              "x-fapi-interaction-id": {
                "$ref": "#/components/headers/XFapiInteractionIdResponse"
              },
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/XRateLimitLimit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/XRateLimitRemaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/XRateLimitReset"
              },
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              },
              "X-Idempotent-Replay": {
                "$ref": "#/components/headers/X-Idempotent-Replay"
              },
              "X-Idempotency-Status": {
                "$ref": "#/components/headers/X-Idempotency-Status"
              },
              "traceparent": {
                "$ref": "#/components/headers/Traceparent"
              },
              "Content-Language": {
                "$ref": "#/components/headers/Content-Language"
              }
            }
          },
          "400": {
            "description": "Bad request",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              },
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                },
                "examples": {
                  "error": {
                    "$ref": "#/components/examples/ErrorBadRequest"
                  }
                }
              }
            },
            "headers": {
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/XRateLimitLimit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/XRateLimitRemaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/XRateLimitReset"
              },
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "403": {
            "$ref": "#/components/responses/Forbidden",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "404": {
            "$ref": "#/components/responses/NotFound",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "409": {
            "$ref": "#/components/responses/Conflict",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "429": {
            "$ref": "#/components/responses/TooManyRequests",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "500": {
            "$ref": "#/components/responses/InternalServerError",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          }
        },
        "x-codeSamples": [
          {
            "lang": "cURL",
            "label": "cURL",
            "source": "curl -X POST \"https://api.kangopenbanking.com/v1/interbank/payments/{paymentId}/submit\" \\\n  -H \"Authorization: Bearer $KOB_ACCESS_TOKEN\" \\\n  -H \"Content-Type: application/json\""
          },
          {
            "lang": "JavaScript",
            "label": "Node.js",
            "source": "import { KangOpenBanking } from \"@kangopenbanking/sdk\";\n\nconst kob = new KangOpenBanking({ apiKey: process.env.KOB_API_KEY });\nconst res = await kob.request(\"POST\", \"/v1/interbank/payments/{paymentId}/submit\");\nconsole.log(res);"
          },
          {
            "lang": "Python",
            "label": "Python",
            "source": "from kangopenbanking import KangOpenBanking\n\nkob = KangOpenBanking(api_key=os.environ[\"KOB_API_KEY\"])\nres = kob.request(\"POST\", \"/v1/interbank/payments/{paymentId}/submit\")\nprint(res)"
          },
          {
            "lang": "PHP",
            "label": "PHP",
            "source": "<?php\n$kob = new KangOpenBanking\\KangOpenBanking(getenv('KOB_API_KEY'));\n$res = $kob->request('POST', '/v1/interbank/payments/{paymentId}/submit');\nprint_r($res);"
          }
        ]
      }
    },
    "/v1/interbank/participants": {
      "get": {
        "tags": [
          "Interbank"
        ],
        "summary": "List participants",
        "operationId": "interbankParticipantsList",
        "security": [
          {
            "bearerAuth": []
          }
        ],
        "responses": {
          "200": {
            "description": "Interbank participants list",
            "content": {
              "application/json": {
                "schema": {
                  "allOf": [
                    {
                      "$ref": "#/components/schemas/PaginatedResponse"
                    },
                    {
                      "type": "object",
                      "properties": {
                        "data": {
                          "type": "array",
                          "items": {}
                        }
                      }
                    }
                  ]
                },
                "example": {
                  "data": [
                    {}
                  ],
                  "pagination": {
                    "page": 1,
                    "limit": 20,
                    "total": 150,
                    "has_next": true,
                    "next_cursor": "eyJpZCI6IjEyMyJ9"
                  },
                  "meta": {
                    "request_id": "550e8400-e29b-41d4-a716-446655440000",
                    "timestamp": "2025-03-27T12:00:00Z",
                    "api_version": "4.3.0"
                  }
                }
              }
            },
            "headers": {
              "x-fapi-interaction-id": {
                "$ref": "#/components/headers/XFapiInteractionIdResponse"
              },
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/XRateLimitLimit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/XRateLimitRemaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/XRateLimitReset"
              },
              "Cache-Control": {
                "$ref": "#/components/headers/CacheControl"
              },
              "ETag": {
                "$ref": "#/components/headers/ETag"
              },
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              },
              "traceparent": {
                "$ref": "#/components/headers/Traceparent"
              },
              "Content-Language": {
                "$ref": "#/components/headers/Content-Language"
              }
            }
          },
          "400": {
            "description": "Bad request",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              },
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                },
                "examples": {
                  "error": {
                    "$ref": "#/components/examples/ErrorBadRequest"
                  }
                }
              }
            },
            "headers": {
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/XRateLimitLimit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/XRateLimitRemaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/XRateLimitReset"
              },
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "403": {
            "$ref": "#/components/responses/Forbidden",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "404": {
            "$ref": "#/components/responses/NotFound",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "409": {
            "$ref": "#/components/responses/Conflict",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "429": {
            "$ref": "#/components/responses/TooManyRequests",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "500": {
            "$ref": "#/components/responses/InternalServerError",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          }
        },
        "parameters": [
          {
            "$ref": "#/components/parameters/RequestId"
          },
          {
            "$ref": "#/components/parameters/Traceparent"
          },
          {
            "$ref": "#/components/parameters/Tracestate"
          },
          {
            "$ref": "#/components/parameters/AcceptLanguage"
          }
        ],
        "x-codeSamples": [
          {
            "lang": "cURL",
            "label": "cURL",
            "source": "curl -X GET \"https://api.kangopenbanking.com/v1/interbank/participants\" \\\n  -H \"Authorization: Bearer $KOB_ACCESS_TOKEN\" \\\n  -H \"Content-Type: application/json\""
          },
          {
            "lang": "JavaScript",
            "label": "Node.js",
            "source": "import { KangOpenBanking } from \"@kangopenbanking/sdk\";\n\nconst kob = new KangOpenBanking({ apiKey: process.env.KOB_API_KEY });\nconst res = await kob.request(\"GET\", \"/v1/interbank/participants\");\nconsole.log(res);"
          },
          {
            "lang": "Python",
            "label": "Python",
            "source": "from kangopenbanking import KangOpenBanking\n\nkob = KangOpenBanking(api_key=os.environ[\"KOB_API_KEY\"])\nres = kob.request(\"GET\", \"/v1/interbank/participants\")\nprint(res)"
          },
          {
            "lang": "PHP",
            "label": "PHP",
            "source": "<?php\n$kob = new KangOpenBanking\\KangOpenBanking(getenv('KOB_API_KEY'));\n$res = $kob->request('GET', '/v1/interbank/participants');\nprint_r($res);"
          }
        ]
      }
    },
    "/v1/interbank/messages": {
      "get": {
        "tags": [
          "Interbank"
        ],
        "summary": "List ISO 20022 messages",
        "operationId": "interbankMessagesList",
        "security": [
          {
            "bearerAuth": []
          }
        ],
        "parameters": [
          {
            "name": "payment_id",
            "in": "query",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "limit",
            "in": "query",
            "schema": {
              "type": "integer",
              "default": 25,
              "maximum": 100
            },
            "description": "Items per page"
          },
          {
            "name": "offset",
            "in": "query",
            "schema": {
              "type": "integer",
              "default": 0
            },
            "description": "Items to skip"
          },
          {
            "name": "sort_by",
            "in": "query",
            "schema": {
              "type": "string",
              "default": "created_at"
            },
            "description": "Sort field"
          },
          {
            "name": "sort_order",
            "in": "query",
            "schema": {
              "type": "string",
              "enum": [
                "asc",
                "desc"
              ],
              "default": "desc"
            },
            "description": "Sort direction"
          },
          {
            "$ref": "#/components/parameters/StartingAfter"
          },
          {
            "$ref": "#/components/parameters/EndingBefore"
          },
          {
            "$ref": "#/components/parameters/RequestId"
          },
          {
            "$ref": "#/components/parameters/Traceparent"
          },
          {
            "$ref": "#/components/parameters/Tracestate"
          },
          {
            "$ref": "#/components/parameters/AcceptLanguage"
          }
        ],
        "responses": {
          "200": {
            "description": "ISO messages list",
            "content": {
              "application/json": {
                "schema": {
                  "allOf": [
                    {
                      "$ref": "#/components/schemas/PaginatedResponse"
                    },
                    {
                      "type": "object",
                      "properties": {
                        "data": {
                          "type": "array",
                          "items": {}
                        }
                      }
                    }
                  ]
                },
                "example": {
                  "data": [
                    {}
                  ],
                  "pagination": {
                    "page": 1,
                    "limit": 20,
                    "total": 150,
                    "has_next": true,
                    "next_cursor": "eyJpZCI6IjEyMyJ9"
                  },
                  "meta": {
                    "request_id": "550e8400-e29b-41d4-a716-446655440000",
                    "timestamp": "2025-03-27T12:00:00Z",
                    "api_version": "4.3.0"
                  }
                }
              }
            },
            "headers": {
              "x-fapi-interaction-id": {
                "$ref": "#/components/headers/XFapiInteractionIdResponse"
              },
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/XRateLimitLimit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/XRateLimitRemaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/XRateLimitReset"
              },
              "Cache-Control": {
                "$ref": "#/components/headers/CacheControl"
              },
              "ETag": {
                "$ref": "#/components/headers/ETag"
              },
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              },
              "traceparent": {
                "$ref": "#/components/headers/Traceparent"
              },
              "Content-Language": {
                "$ref": "#/components/headers/Content-Language"
              }
            }
          },
          "400": {
            "description": "Bad request",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              },
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                },
                "examples": {
                  "error": {
                    "$ref": "#/components/examples/ErrorBadRequest"
                  }
                }
              }
            },
            "headers": {
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/XRateLimitLimit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/XRateLimitRemaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/XRateLimitReset"
              },
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "403": {
            "$ref": "#/components/responses/Forbidden",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "404": {
            "$ref": "#/components/responses/NotFound",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "409": {
            "$ref": "#/components/responses/Conflict",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "429": {
            "$ref": "#/components/responses/TooManyRequests",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "500": {
            "$ref": "#/components/responses/InternalServerError",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          }
        },
        "x-codeSamples": [
          {
            "lang": "cURL",
            "label": "cURL",
            "source": "curl -X GET \"https://api.kangopenbanking.com/v1/interbank/messages\" \\\n  -H \"Authorization: Bearer $KOB_ACCESS_TOKEN\" \\\n  -H \"Content-Type: application/json\""
          },
          {
            "lang": "JavaScript",
            "label": "Node.js",
            "source": "import { KangOpenBanking } from \"@kangopenbanking/sdk\";\n\nconst kob = new KangOpenBanking({ apiKey: process.env.KOB_API_KEY });\nconst res = await kob.request(\"GET\", \"/v1/interbank/messages\");\nconsole.log(res);"
          },
          {
            "lang": "Python",
            "label": "Python",
            "source": "from kangopenbanking import KangOpenBanking\n\nkob = KangOpenBanking(api_key=os.environ[\"KOB_API_KEY\"])\nres = kob.request(\"GET\", \"/v1/interbank/messages\")\nprint(res)"
          },
          {
            "lang": "PHP",
            "label": "PHP",
            "source": "<?php\n$kob = new KangOpenBanking\\KangOpenBanking(getenv('KOB_API_KEY'));\n$res = $kob->request('GET', '/v1/interbank/messages');\nprint_r($res);"
          }
        ]
      }
    },
    "/v1/banks/{bankId}/link": {
      "post": {
        "tags": [
          "Bank Directory"
        ],
        "summary": "Link PSU to bank",
        "description": "Start linking a user to a bank for AISP/PISP access.",
        "operationId": "bankLinkPsu",
        "security": [
          {
            "bearerAuth": []
          }
        ],
        "parameters": [
          {
            "name": "bankId",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          },
          {
            "$ref": "#/components/parameters/RequestId"
          },
          {
            "$ref": "#/components/parameters/Traceparent"
          },
          {
            "$ref": "#/components/parameters/Tracestate"
          },
          {
            "$ref": "#/components/parameters/AcceptLanguage"
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "required": [
                  "external_customer_id"
                ],
                "properties": {
                  "external_customer_id": {
                    "type": "string"
                  }
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Link initiated",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "success": {
                      "type": "boolean",
                      "example": true
                    },
                    "message": {
                      "type": "string"
                    }
                  }
                },
                "example": {
                  "success": true,
                  "message": "string"
                }
              }
            },
            "headers": {
              "x-fapi-interaction-id": {
                "$ref": "#/components/headers/XFapiInteractionIdResponse"
              },
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/XRateLimitLimit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/XRateLimitRemaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/XRateLimitReset"
              },
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              },
              "traceparent": {
                "$ref": "#/components/headers/Traceparent"
              },
              "Content-Language": {
                "$ref": "#/components/headers/Content-Language"
              }
            }
          },
          "400": {
            "description": "Bad request",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              },
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                },
                "examples": {
                  "error": {
                    "$ref": "#/components/examples/ErrorBadRequest"
                  }
                }
              }
            },
            "headers": {
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/XRateLimitLimit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/XRateLimitRemaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/XRateLimitReset"
              },
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "403": {
            "$ref": "#/components/responses/Forbidden",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "404": {
            "$ref": "#/components/responses/NotFound",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "409": {
            "$ref": "#/components/responses/Conflict",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "429": {
            "$ref": "#/components/responses/TooManyRequests",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "500": {
            "$ref": "#/components/responses/InternalServerError",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          }
        },
        "x-codeSamples": [
          {
            "lang": "cURL",
            "label": "cURL",
            "source": "curl -X POST \"https://api.kangopenbanking.com/v1/banks/{bankId}/link\" \\\n  -H \"Authorization: Bearer $KOB_ACCESS_TOKEN\" \\\n  -H \"Content-Type: application/json\" \\\n  -d '{}'"
          },
          {
            "lang": "JavaScript",
            "label": "Node.js",
            "source": "import { KangOpenBanking } from \"@kangopenbanking/sdk\";\n\nconst kob = new KangOpenBanking({ apiKey: process.env.KOB_API_KEY });\nconst res = await kob.request(\"POST\", \"/v1/banks/{bankId}/link\", { /* payload */ });\nconsole.log(res);"
          },
          {
            "lang": "Python",
            "label": "Python",
            "source": "from kangopenbanking import KangOpenBanking\n\nkob = KangOpenBanking(api_key=os.environ[\"KOB_API_KEY\"])\nres = kob.request(\"POST\", \"/v1/banks/{bankId}/link\", json={})\nprint(res)"
          },
          {
            "lang": "PHP",
            "label": "PHP",
            "source": "<?php\n$kob = new KangOpenBanking\\KangOpenBanking(getenv('KOB_API_KEY'));\n$res = $kob->request('POST', '/v1/banks/{bankId}/link', []);\nprint_r($res);"
          }
        ]
      }
    },
    "/v1/banks/{bankId}/payments": {
      "get": {
        "tags": [
          "Bank Connectors"
        ],
        "summary": "List bank payments",
        "operationId": "bankPaymentsList",
        "security": [
          {
            "bearerAuth": []
          }
        ],
        "parameters": [
          {
            "name": "bankId",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          },
          {
            "name": "limit",
            "in": "query",
            "schema": {
              "type": "integer",
              "default": 25,
              "maximum": 100
            },
            "description": "Items per page"
          },
          {
            "name": "offset",
            "in": "query",
            "schema": {
              "type": "integer",
              "default": 0
            },
            "description": "Items to skip"
          },
          {
            "name": "sort_by",
            "in": "query",
            "schema": {
              "type": "string",
              "default": "created_at"
            },
            "description": "Sort field"
          },
          {
            "name": "sort_order",
            "in": "query",
            "schema": {
              "type": "string",
              "enum": [
                "asc",
                "desc"
              ],
              "default": "desc"
            },
            "description": "Sort direction"
          },
          {
            "$ref": "#/components/parameters/StartingAfter"
          },
          {
            "$ref": "#/components/parameters/EndingBefore"
          },
          {
            "$ref": "#/components/parameters/RequestId"
          },
          {
            "$ref": "#/components/parameters/Traceparent"
          },
          {
            "$ref": "#/components/parameters/Tracestate"
          },
          {
            "$ref": "#/components/parameters/AcceptLanguage"
          }
        ],
        "responses": {
          "200": {
            "description": "Bank payments list",
            "content": {
              "application/json": {
                "schema": {
                  "allOf": [
                    {
                      "$ref": "#/components/schemas/PaginatedResponse"
                    },
                    {
                      "type": "object",
                      "properties": {
                        "data": {
                          "type": "array",
                          "items": {
                            "$ref": "#/components/schemas/Payment"
                          }
                        }
                      }
                    }
                  ]
                },
                "example": {
                  "data": [
                    {
                      "payment_id": "f1d6f4a0-1d4e-4a3a-9e0a-1a2b3c4d5e6f",
                      "amount": "50000",
                      "currency": "XAF",
                      "status": "pending",
                      "debtor_account": "CM21 10003 00100 0123456789 023",
                      "creditor_account": "CM21 10003 00200 9876543210 045",
                      "reference": "Invoice-2026-001",
                      "created_at": "2026-01-31T12:00:00Z"
                    }
                  ],
                  "pagination": {
                    "page": 1,
                    "limit": 20,
                    "total": 150,
                    "has_next": true,
                    "next_cursor": "eyJpZCI6IjEyMyJ9"
                  },
                  "meta": {
                    "request_id": "550e8400-e29b-41d4-a716-446655440000",
                    "timestamp": "2025-03-27T12:00:00Z",
                    "api_version": "4.3.0"
                  }
                }
              }
            },
            "headers": {
              "x-fapi-interaction-id": {
                "$ref": "#/components/headers/XFapiInteractionIdResponse"
              },
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/XRateLimitLimit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/XRateLimitRemaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/XRateLimitReset"
              },
              "Cache-Control": {
                "$ref": "#/components/headers/CacheControl"
              },
              "ETag": {
                "$ref": "#/components/headers/ETag"
              },
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              },
              "traceparent": {
                "$ref": "#/components/headers/Traceparent"
              },
              "Content-Language": {
                "$ref": "#/components/headers/Content-Language"
              }
            }
          },
          "400": {
            "description": "Bad request",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              },
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                },
                "examples": {
                  "error": {
                    "$ref": "#/components/examples/ErrorBadRequest"
                  }
                }
              }
            },
            "headers": {
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/XRateLimitLimit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/XRateLimitRemaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/XRateLimitReset"
              },
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "403": {
            "$ref": "#/components/responses/Forbidden",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "404": {
            "$ref": "#/components/responses/NotFound",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "409": {
            "$ref": "#/components/responses/Conflict",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "429": {
            "$ref": "#/components/responses/TooManyRequests",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "500": {
            "$ref": "#/components/responses/InternalServerError",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          }
        },
        "x-codeSamples": [
          {
            "lang": "cURL",
            "label": "cURL",
            "source": "curl -X GET \"https://api.kangopenbanking.com/v1/banks/{bankId}/payments\" \\\n  -H \"Authorization: Bearer $KOB_ACCESS_TOKEN\" \\\n  -H \"Content-Type: application/json\""
          },
          {
            "lang": "JavaScript",
            "label": "Node.js",
            "source": "import { KangOpenBanking } from \"@kangopenbanking/sdk\";\n\nconst kob = new KangOpenBanking({ apiKey: process.env.KOB_API_KEY });\nconst res = await kob.request(\"GET\", \"/v1/banks/{bankId}/payments\");\nconsole.log(res);"
          },
          {
            "lang": "Python",
            "label": "Python",
            "source": "from kangopenbanking import KangOpenBanking\n\nkob = KangOpenBanking(api_key=os.environ[\"KOB_API_KEY\"])\nres = kob.request(\"GET\", \"/v1/banks/{bankId}/payments\")\nprint(res)"
          },
          {
            "lang": "PHP",
            "label": "PHP",
            "source": "<?php\n$kob = new KangOpenBanking\\KangOpenBanking(getenv('KOB_API_KEY'));\n$res = $kob->request('GET', '/v1/banks/{bankId}/payments');\nprint_r($res);"
          }
        ]
      }
    },
    "/v1/internal/connectors/{bankId}/payments/status": {
      "post": {
        "tags": [
          "Bank Connectors"
        ],
        "summary": "Payment status callback",
        "description": "Bank connector pushes payment status update.",
        "operationId": "connectorPaymentStatus",
        "security": [
          {
            "mtls": []
          }
        ],
        "parameters": [
          {
            "name": "bankId",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          },
          {
            "$ref": "#/components/parameters/IdempotencyKey"
          },
          {
            "$ref": "#/components/parameters/RequestId"
          },
          {
            "$ref": "#/components/parameters/Traceparent"
          },
          {
            "$ref": "#/components/parameters/Tracestate"
          },
          {
            "$ref": "#/components/parameters/AcceptLanguage"
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "required": [
                  "payment_id",
                  "status"
                ],
                "properties": {
                  "payment_id": {
                    "type": "string"
                  },
                  "status": {
                    "type": "string",
                    "enum": [
                      "accepted",
                      "completed",
                      "failed",
                      "reversed"
                    ]
                  },
                  "details": {
                    "type": "object"
                  }
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Status updated",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "success": {
                      "type": "boolean",
                      "example": true
                    },
                    "message": {
                      "type": "string"
                    }
                  }
                },
                "example": {
                  "success": true,
                  "message": "string"
                }
              }
            },
            "headers": {
              "x-fapi-interaction-id": {
                "$ref": "#/components/headers/XFapiInteractionIdResponse"
              },
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/XRateLimitLimit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/XRateLimitRemaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/XRateLimitReset"
              },
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              },
              "traceparent": {
                "$ref": "#/components/headers/Traceparent"
              },
              "Content-Language": {
                "$ref": "#/components/headers/Content-Language"
              }
            }
          },
          "400": {
            "description": "Bad request",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              },
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                },
                "examples": {
                  "error": {
                    "$ref": "#/components/examples/ErrorBadRequest"
                  }
                }
              }
            },
            "headers": {
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/XRateLimitLimit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/XRateLimitRemaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/XRateLimitReset"
              },
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "403": {
            "$ref": "#/components/responses/Forbidden",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "404": {
            "$ref": "#/components/responses/NotFound",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "409": {
            "$ref": "#/components/responses/Conflict",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "429": {
            "$ref": "#/components/responses/TooManyRequests",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "500": {
            "$ref": "#/components/responses/InternalServerError",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          }
        },
        "x-codeSamples": [
          {
            "lang": "cURL",
            "label": "cURL",
            "source": "curl -X POST \"https://api.kangopenbanking.com/v1/internal/connectors/{bankId}/payments/status\" \\\n  -H \"Authorization: Bearer $KOB_ACCESS_TOKEN\" \\\n  -H \"Content-Type: application/json\" \\\n  -d '{}'"
          },
          {
            "lang": "JavaScript",
            "label": "Node.js",
            "source": "import { KangOpenBanking } from \"@kangopenbanking/sdk\";\n\nconst kob = new KangOpenBanking({ apiKey: process.env.KOB_API_KEY });\nconst res = await kob.request(\"POST\", \"/v1/internal/connectors/{bankId}/payments/status\", { /* payload */ });\nconsole.log(res);"
          },
          {
            "lang": "Python",
            "label": "Python",
            "source": "from kangopenbanking import KangOpenBanking\n\nkob = KangOpenBanking(api_key=os.environ[\"KOB_API_KEY\"])\nres = kob.request(\"POST\", \"/v1/internal/connectors/{bankId}/payments/status\", json={})\nprint(res)"
          },
          {
            "lang": "PHP",
            "label": "PHP",
            "source": "<?php\n$kob = new KangOpenBanking\\KangOpenBanking(getenv('KOB_API_KEY'));\n$res = $kob->request('POST', '/v1/internal/connectors/{bankId}/payments/status', []);\nprint_r($res);"
          }
        ]
      }
    },
    "/v1/pay-by-bank/intents": {
      "post": {
        "tags": [
          "Pay by Bank"
        ],
        "summary": "Create payment intent",
        "operationId": "payByBankCreateIntent",
        "security": [
          {
            "bearerAuth": []
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/CreatePayByBankIntentRequest"
              }
            }
          }
        },
        "responses": {
          "201": {
            "description": "Intent created",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "intent_id": {
                      "type": "string"
                    },
                    "consent_id": {
                      "type": "string"
                    },
                    "authorization_url": {
                      "type": "string"
                    },
                    "expires_at": {
                      "type": "string"
                    },
                    "status": {
                      "type": "string"
                    }
                  }
                },
                "example": {
                  "intent_id": "string",
                  "consent_id": "string",
                  "authorization_url": "string",
                  "expires_at": "string",
                  "status": "string"
                }
              }
            },
            "headers": {
              "x-fapi-interaction-id": {
                "$ref": "#/components/headers/XFapiInteractionIdResponse"
              },
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/XRateLimitLimit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/XRateLimitRemaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/XRateLimitReset"
              },
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              },
              "traceparent": {
                "$ref": "#/components/headers/Traceparent"
              },
              "Content-Language": {
                "$ref": "#/components/headers/Content-Language"
              }
            }
          },
          "400": {
            "description": "Bad request",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              },
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                },
                "examples": {
                  "error": {
                    "$ref": "#/components/examples/ErrorBadRequest"
                  }
                }
              }
            },
            "headers": {
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/XRateLimitLimit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/XRateLimitRemaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/XRateLimitReset"
              },
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "403": {
            "$ref": "#/components/responses/Forbidden",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "404": {
            "$ref": "#/components/responses/NotFound",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "409": {
            "$ref": "#/components/responses/Conflict",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "429": {
            "$ref": "#/components/responses/TooManyRequests",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "500": {
            "$ref": "#/components/responses/InternalServerError",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          }
        },
        "parameters": [
          {
            "$ref": "#/components/parameters/XFapiInteractionId"
          },
          {
            "$ref": "#/components/parameters/XFapiCustomerIpAddress"
          },
          {
            "$ref": "#/components/parameters/XFapiAuthDate"
          },
          {
            "$ref": "#/components/parameters/RequestId"
          },
          {
            "$ref": "#/components/parameters/Traceparent"
          },
          {
            "$ref": "#/components/parameters/Tracestate"
          },
          {
            "$ref": "#/components/parameters/AcceptLanguage"
          }
        ],
        "x-codeSamples": [
          {
            "lang": "cURL",
            "label": "cURL",
            "source": "curl -X POST \"https://api.kangopenbanking.com/v1/pay-by-bank/intents\" \\\n  -H \"Authorization: Bearer $KOB_ACCESS_TOKEN\" \\\n  -H \"Content-Type: application/json\" \\\n  -d '{}'"
          },
          {
            "lang": "JavaScript",
            "label": "Node.js",
            "source": "import { KangOpenBanking } from \"@kangopenbanking/sdk\";\n\nconst kob = new KangOpenBanking({ apiKey: process.env.KOB_API_KEY });\nconst res = await kob.request(\"POST\", \"/v1/pay-by-bank/intents\", { /* payload */ });\nconsole.log(res);"
          },
          {
            "lang": "Python",
            "label": "Python",
            "source": "from kangopenbanking import KangOpenBanking\n\nkob = KangOpenBanking(api_key=os.environ[\"KOB_API_KEY\"])\nres = kob.request(\"POST\", \"/v1/pay-by-bank/intents\", json={})\nprint(res)"
          },
          {
            "lang": "PHP",
            "label": "PHP",
            "source": "<?php\n$kob = new KangOpenBanking\\KangOpenBanking(getenv('KOB_API_KEY'));\n$res = $kob->request('POST', '/v1/pay-by-bank/intents', []);\nprint_r($res);"
          }
        ]
      },
      "get": {
        "tags": [
          "Pay by Bank"
        ],
        "summary": "List merchant payment intents",
        "operationId": "payByBankListIntents",
        "security": [
          {
            "bearerAuth": []
          }
        ],
        "parameters": [
          {
            "name": "status",
            "in": "query",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "limit",
            "in": "query",
            "schema": {
              "type": "integer",
              "default": 25,
              "maximum": 100
            },
            "description": "Items per page"
          },
          {
            "name": "offset",
            "in": "query",
            "schema": {
              "type": "integer",
              "default": 0
            },
            "description": "Items to skip"
          },
          {
            "name": "sort_by",
            "in": "query",
            "schema": {
              "type": "string",
              "default": "created_at"
            },
            "description": "Sort field"
          },
          {
            "name": "sort_order",
            "in": "query",
            "schema": {
              "type": "string",
              "enum": [
                "asc",
                "desc"
              ],
              "default": "desc"
            },
            "description": "Sort direction"
          },
          {
            "$ref": "#/components/parameters/StartingAfter"
          },
          {
            "$ref": "#/components/parameters/EndingBefore"
          },
          {
            "$ref": "#/components/parameters/RequestId"
          },
          {
            "$ref": "#/components/parameters/Traceparent"
          },
          {
            "$ref": "#/components/parameters/Tracestate"
          },
          {
            "$ref": "#/components/parameters/AcceptLanguage"
          }
        ],
        "responses": {
          "200": {
            "description": "Intent list",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "intents": {
                      "type": "array",
                      "items": {
                        "$ref": "#/components/schemas/PayByBankIntent"
                      }
                    }
                  }
                },
                "example": {
                  "intents": [
                    {
                      "id": "00000000-0000-4000-8000-000000000000",
                      "merchant_id": "00000000-0000-4000-8000-000000000000",
                      "consent_id": "string",
                      "amount": "50000",
                      "currency": "XAF",
                      "redirect_uri": "https://api.kangopenbanking.com",
                      "state": "string",
                      "status": "awaiting_auth",
                      "merchant_name": "string",
                      "merchant_logo_url": "https://api.kangopenbanking.com",
                      "description": "string",
                      "authorization_url": "https://api.kangopenbanking.com",
                      "expires_at": "2026-01-01T00:00:00Z",
                      "created_at": "2026-01-01T00:00:00Z",
                      "updated_at": "2026-01-01T00:00:00Z"
                    }
                  ]
                }
              }
            },
            "headers": {
              "x-fapi-interaction-id": {
                "$ref": "#/components/headers/XFapiInteractionIdResponse"
              },
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/XRateLimitLimit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/XRateLimitRemaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/XRateLimitReset"
              },
              "Cache-Control": {
                "$ref": "#/components/headers/CacheControl"
              },
              "ETag": {
                "$ref": "#/components/headers/ETag"
              },
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              },
              "traceparent": {
                "$ref": "#/components/headers/Traceparent"
              },
              "Content-Language": {
                "$ref": "#/components/headers/Content-Language"
              }
            }
          },
          "400": {
            "description": "Bad request",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              },
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                },
                "examples": {
                  "error": {
                    "$ref": "#/components/examples/ErrorBadRequest"
                  }
                }
              }
            },
            "headers": {
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/XRateLimitLimit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/XRateLimitRemaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/XRateLimitReset"
              },
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "403": {
            "$ref": "#/components/responses/Forbidden",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "404": {
            "$ref": "#/components/responses/NotFound",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "409": {
            "$ref": "#/components/responses/Conflict",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "429": {
            "$ref": "#/components/responses/TooManyRequests",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "500": {
            "$ref": "#/components/responses/InternalServerError",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          }
        },
        "x-codeSamples": [
          {
            "lang": "cURL",
            "label": "cURL",
            "source": "curl -X GET \"https://api.kangopenbanking.com/v1/pay-by-bank/intents\" \\\n  -H \"Authorization: Bearer $KOB_ACCESS_TOKEN\" \\\n  -H \"Content-Type: application/json\""
          },
          {
            "lang": "JavaScript",
            "label": "Node.js",
            "source": "import { KangOpenBanking } from \"@kangopenbanking/sdk\";\n\nconst kob = new KangOpenBanking({ apiKey: process.env.KOB_API_KEY });\nconst res = await kob.request(\"GET\", \"/v1/pay-by-bank/intents\");\nconsole.log(res);"
          },
          {
            "lang": "Python",
            "label": "Python",
            "source": "from kangopenbanking import KangOpenBanking\n\nkob = KangOpenBanking(api_key=os.environ[\"KOB_API_KEY\"])\nres = kob.request(\"GET\", \"/v1/pay-by-bank/intents\")\nprint(res)"
          },
          {
            "lang": "PHP",
            "label": "PHP",
            "source": "<?php\n$kob = new KangOpenBanking\\KangOpenBanking(getenv('KOB_API_KEY'));\n$res = $kob->request('GET', '/v1/pay-by-bank/intents');\nprint_r($res);"
          }
        ]
      }
    },
    "/v1/pay-by-bank/intents/{intentId}": {
      "get": {
        "tags": [
          "Pay by Bank"
        ],
        "summary": "Get payment intent status",
        "operationId": "payByBankGetIntent",
        "security": [
          {
            "bearerAuth": []
          }
        ],
        "parameters": [
          {
            "name": "intentId",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          },
          {
            "$ref": "#/components/parameters/RequestId"
          },
          {
            "$ref": "#/components/parameters/Traceparent"
          },
          {
            "$ref": "#/components/parameters/Tracestate"
          },
          {
            "$ref": "#/components/parameters/AcceptLanguage"
          }
        ],
        "responses": {
          "200": {
            "description": "Intent details",
            "content": {
              "application/json": {
                "schema": {
                  "allOf": [
                    {
                      "$ref": "#/components/schemas/StandardResponse"
                    },
                    {
                      "type": "object",
                      "properties": {
                        "data": {
                          "$ref": "#/components/schemas/PayByBankIntent"
                        }
                      }
                    }
                  ]
                },
                "example": {
                  "data": {
                    "id": "00000000-0000-4000-8000-000000000000",
                    "merchant_id": "00000000-0000-4000-8000-000000000000",
                    "consent_id": "string",
                    "amount": "50000",
                    "currency": "XAF",
                    "redirect_uri": "https://api.kangopenbanking.com",
                    "state": "string",
                    "status": "awaiting_auth",
                    "merchant_name": "string",
                    "merchant_logo_url": "https://api.kangopenbanking.com",
                    "description": "string",
                    "authorization_url": "https://api.kangopenbanking.com",
                    "expires_at": "2026-01-01T00:00:00Z",
                    "created_at": "2026-01-01T00:00:00Z",
                    "updated_at": "2026-01-01T00:00:00Z"
                  },
                  "meta": {
                    "request_id": "550e8400-e29b-41d4-a716-446655440000",
                    "timestamp": "2025-03-27T12:00:00Z",
                    "api_version": "4.3.0"
                  }
                }
              }
            },
            "headers": {
              "x-fapi-interaction-id": {
                "$ref": "#/components/headers/XFapiInteractionIdResponse"
              },
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/XRateLimitLimit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/XRateLimitRemaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/XRateLimitReset"
              },
              "Cache-Control": {
                "$ref": "#/components/headers/CacheControl"
              },
              "ETag": {
                "$ref": "#/components/headers/ETag"
              },
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              },
              "traceparent": {
                "$ref": "#/components/headers/Traceparent"
              },
              "Content-Language": {
                "$ref": "#/components/headers/Content-Language"
              }
            }
          },
          "400": {
            "description": "Bad request",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              },
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                },
                "examples": {
                  "error": {
                    "$ref": "#/components/examples/ErrorBadRequest"
                  }
                }
              }
            },
            "headers": {
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/XRateLimitLimit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/XRateLimitRemaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/XRateLimitReset"
              },
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "403": {
            "$ref": "#/components/responses/Forbidden",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "404": {
            "$ref": "#/components/responses/NotFound",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "409": {
            "$ref": "#/components/responses/Conflict",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "429": {
            "$ref": "#/components/responses/TooManyRequests",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "500": {
            "$ref": "#/components/responses/InternalServerError",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          }
        },
        "x-codeSamples": [
          {
            "lang": "cURL",
            "label": "cURL",
            "source": "curl -X GET \"https://api.kangopenbanking.com/v1/pay-by-bank/intents/{intentId}\" \\\n  -H \"Authorization: Bearer $KOB_ACCESS_TOKEN\" \\\n  -H \"Content-Type: application/json\""
          },
          {
            "lang": "JavaScript",
            "label": "Node.js",
            "source": "import { KangOpenBanking } from \"@kangopenbanking/sdk\";\n\nconst kob = new KangOpenBanking({ apiKey: process.env.KOB_API_KEY });\nconst res = await kob.request(\"GET\", \"/v1/pay-by-bank/intents/{intentId}\");\nconsole.log(res);"
          },
          {
            "lang": "Python",
            "label": "Python",
            "source": "from kangopenbanking import KangOpenBanking\n\nkob = KangOpenBanking(api_key=os.environ[\"KOB_API_KEY\"])\nres = kob.request(\"GET\", \"/v1/pay-by-bank/intents/{intentId}\")\nprint(res)"
          },
          {
            "lang": "PHP",
            "label": "PHP",
            "source": "<?php\n$kob = new KangOpenBanking\\KangOpenBanking(getenv('KOB_API_KEY'));\n$res = $kob->request('GET', '/v1/pay-by-bank/intents/{intentId}');\nprint_r($res);"
          }
        ]
      }
    },
    "/v1/pay-by-bank/intents/{intentId}/authorize": {
      "post": {
        "tags": [
          "Pay by Bank"
        ],
        "summary": "Authorize payment (user SCA)",
        "operationId": "payByBankAuthorize",
        "security": [
          {
            "bearerAuth": []
          }
        ],
        "parameters": [
          {
            "name": "intentId",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          },
          {
            "$ref": "#/components/parameters/RequestId"
          },
          {
            "$ref": "#/components/parameters/Traceparent"
          },
          {
            "$ref": "#/components/parameters/Tracestate"
          },
          {
            "$ref": "#/components/parameters/AcceptLanguage"
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "debtor_account": {
                    "type": "string"
                  }
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Payment authorized",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "redirect_url": {
                      "type": "string"
                    },
                    "status": {
                      "type": "string"
                    }
                  }
                },
                "example": {
                  "redirect_url": "string",
                  "status": "string"
                }
              }
            },
            "headers": {
              "x-fapi-interaction-id": {
                "$ref": "#/components/headers/XFapiInteractionIdResponse"
              },
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/XRateLimitLimit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/XRateLimitRemaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/XRateLimitReset"
              },
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              },
              "traceparent": {
                "$ref": "#/components/headers/Traceparent"
              },
              "Content-Language": {
                "$ref": "#/components/headers/Content-Language"
              }
            }
          },
          "400": {
            "description": "Bad request",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              },
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                },
                "examples": {
                  "error": {
                    "$ref": "#/components/examples/ErrorBadRequest"
                  }
                }
              }
            },
            "headers": {
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/XRateLimitLimit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/XRateLimitRemaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/XRateLimitReset"
              },
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "403": {
            "$ref": "#/components/responses/Forbidden",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "404": {
            "$ref": "#/components/responses/NotFound",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "409": {
            "$ref": "#/components/responses/Conflict",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "429": {
            "$ref": "#/components/responses/TooManyRequests",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "500": {
            "$ref": "#/components/responses/InternalServerError",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          }
        },
        "x-codeSamples": [
          {
            "lang": "cURL",
            "label": "cURL",
            "source": "curl -X POST \"https://api.kangopenbanking.com/v1/pay-by-bank/intents/{intentId}/authorize\" \\\n  -H \"Authorization: Bearer $KOB_ACCESS_TOKEN\" \\\n  -H \"Content-Type: application/json\" \\\n  -d '{}'"
          },
          {
            "lang": "JavaScript",
            "label": "Node.js",
            "source": "import { KangOpenBanking } from \"@kangopenbanking/sdk\";\n\nconst kob = new KangOpenBanking({ apiKey: process.env.KOB_API_KEY });\nconst res = await kob.request(\"POST\", \"/v1/pay-by-bank/intents/{intentId}/authorize\", { /* payload */ });\nconsole.log(res);"
          },
          {
            "lang": "Python",
            "label": "Python",
            "source": "from kangopenbanking import KangOpenBanking\n\nkob = KangOpenBanking(api_key=os.environ[\"KOB_API_KEY\"])\nres = kob.request(\"POST\", \"/v1/pay-by-bank/intents/{intentId}/authorize\", json={})\nprint(res)"
          },
          {
            "lang": "PHP",
            "label": "PHP",
            "source": "<?php\n$kob = new KangOpenBanking\\KangOpenBanking(getenv('KOB_API_KEY'));\n$res = $kob->request('POST', '/v1/pay-by-bank/intents/{intentId}/authorize', []);\nprint_r($res);"
          }
        ]
      }
    },
    "/v1/pay-by-bank/intents/{intentId}/reject": {
      "post": {
        "tags": [
          "Pay by Bank"
        ],
        "summary": "Reject payment intent",
        "operationId": "payByBankReject",
        "security": [
          {
            "bearerAuth": []
          }
        ],
        "parameters": [
          {
            "name": "intentId",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          },
          {
            "$ref": "#/components/parameters/RequestId"
          },
          {
            "$ref": "#/components/parameters/Traceparent"
          },
          {
            "$ref": "#/components/parameters/Tracestate"
          },
          {
            "$ref": "#/components/parameters/AcceptLanguage"
          }
        ],
        "responses": {
          "200": {
            "description": "Payment rejected",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "redirect_url": {
                      "type": "string"
                    },
                    "status": {
                      "type": "string"
                    }
                  }
                },
                "example": {
                  "redirect_url": "string",
                  "status": "string"
                }
              }
            },
            "headers": {
              "x-fapi-interaction-id": {
                "$ref": "#/components/headers/XFapiInteractionIdResponse"
              },
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/XRateLimitLimit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/XRateLimitRemaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/XRateLimitReset"
              },
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              },
              "traceparent": {
                "$ref": "#/components/headers/Traceparent"
              },
              "Content-Language": {
                "$ref": "#/components/headers/Content-Language"
              }
            }
          },
          "400": {
            "description": "Bad request",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              },
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                },
                "examples": {
                  "error": {
                    "$ref": "#/components/examples/ErrorBadRequest"
                  }
                }
              }
            },
            "headers": {
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/XRateLimitLimit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/XRateLimitRemaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/XRateLimitReset"
              },
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "403": {
            "$ref": "#/components/responses/Forbidden",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "404": {
            "$ref": "#/components/responses/NotFound",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "409": {
            "$ref": "#/components/responses/Conflict",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "429": {
            "$ref": "#/components/responses/TooManyRequests",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "500": {
            "$ref": "#/components/responses/InternalServerError",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          }
        },
        "x-codeSamples": [
          {
            "lang": "cURL",
            "label": "cURL",
            "source": "curl -X POST \"https://api.kangopenbanking.com/v1/pay-by-bank/intents/{intentId}/reject\" \\\n  -H \"Authorization: Bearer $KOB_ACCESS_TOKEN\" \\\n  -H \"Content-Type: application/json\""
          },
          {
            "lang": "JavaScript",
            "label": "Node.js",
            "source": "import { KangOpenBanking } from \"@kangopenbanking/sdk\";\n\nconst kob = new KangOpenBanking({ apiKey: process.env.KOB_API_KEY });\nconst res = await kob.request(\"POST\", \"/v1/pay-by-bank/intents/{intentId}/reject\");\nconsole.log(res);"
          },
          {
            "lang": "Python",
            "label": "Python",
            "source": "from kangopenbanking import KangOpenBanking\n\nkob = KangOpenBanking(api_key=os.environ[\"KOB_API_KEY\"])\nres = kob.request(\"POST\", \"/v1/pay-by-bank/intents/{intentId}/reject\")\nprint(res)"
          },
          {
            "lang": "PHP",
            "label": "PHP",
            "source": "<?php\n$kob = new KangOpenBanking\\KangOpenBanking(getenv('KOB_API_KEY'));\n$res = $kob->request('POST', '/v1/pay-by-bank/intents/{intentId}/reject');\nprint_r($res);"
          }
        ]
      }
    },
    "/v1/pay-by-bank/callback": {
      "post": {
        "tags": [
          "Pay by Bank"
        ],
        "summary": "Bank connector callback",
        "description": "Internal callback from bank connector confirming payment execution.",
        "operationId": "payByBankCallback",
        "security": [
          {
            "mtls": []
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "required": [
                  "intent_id",
                  "status"
                ],
                "properties": {
                  "intent_id": {
                    "type": "string"
                  },
                  "status": {
                    "type": "string",
                    "enum": [
                      "completed",
                      "failed"
                    ]
                  },
                  "failure_reason": {
                    "type": "string"
                  }
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Callback processed",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "success": {
                      "type": "boolean",
                      "example": true
                    },
                    "message": {
                      "type": "string"
                    }
                  }
                },
                "example": {
                  "success": true,
                  "message": "string"
                }
              }
            },
            "headers": {
              "x-fapi-interaction-id": {
                "$ref": "#/components/headers/XFapiInteractionIdResponse"
              },
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/XRateLimitLimit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/XRateLimitRemaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/XRateLimitReset"
              },
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              },
              "traceparent": {
                "$ref": "#/components/headers/Traceparent"
              },
              "Content-Language": {
                "$ref": "#/components/headers/Content-Language"
              }
            }
          },
          "400": {
            "description": "Bad request",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              },
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                },
                "examples": {
                  "error": {
                    "$ref": "#/components/examples/ErrorBadRequest"
                  }
                }
              }
            },
            "headers": {
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/XRateLimitLimit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/XRateLimitRemaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/XRateLimitReset"
              },
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "403": {
            "$ref": "#/components/responses/Forbidden",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "404": {
            "$ref": "#/components/responses/NotFound",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "409": {
            "$ref": "#/components/responses/Conflict",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "429": {
            "$ref": "#/components/responses/TooManyRequests",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "500": {
            "$ref": "#/components/responses/InternalServerError",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          }
        },
        "parameters": [
          {
            "$ref": "#/components/parameters/RequestId"
          },
          {
            "$ref": "#/components/parameters/Traceparent"
          },
          {
            "$ref": "#/components/parameters/Tracestate"
          },
          {
            "$ref": "#/components/parameters/AcceptLanguage"
          }
        ],
        "x-codeSamples": [
          {
            "lang": "cURL",
            "label": "cURL",
            "source": "curl -X POST \"https://api.kangopenbanking.com/v1/pay-by-bank/callback\" \\\n  -H \"Authorization: Bearer $KOB_ACCESS_TOKEN\" \\\n  -H \"Content-Type: application/json\" \\\n  -d '{}'"
          },
          {
            "lang": "JavaScript",
            "label": "Node.js",
            "source": "import { KangOpenBanking } from \"@kangopenbanking/sdk\";\n\nconst kob = new KangOpenBanking({ apiKey: process.env.KOB_API_KEY });\nconst res = await kob.request(\"POST\", \"/v1/pay-by-bank/callback\", { /* payload */ });\nconsole.log(res);"
          },
          {
            "lang": "Python",
            "label": "Python",
            "source": "from kangopenbanking import KangOpenBanking\n\nkob = KangOpenBanking(api_key=os.environ[\"KOB_API_KEY\"])\nres = kob.request(\"POST\", \"/v1/pay-by-bank/callback\", json={})\nprint(res)"
          },
          {
            "lang": "PHP",
            "label": "PHP",
            "source": "<?php\n$kob = new KangOpenBanking\\KangOpenBanking(getenv('KOB_API_KEY'));\n$res = $kob->request('POST', '/v1/pay-by-bank/callback', []);\nprint_r($res);"
          }
        ]
      }
    },
    "/v1/gateway/merchants/webhooks/{webhookId}/rotate-secret": {
      "post": {
        "tags": [
          "Merchant Onboarding"
        ],
        "summary": "Rotate webhook signing secret",
        "description": "**Deprecated.** Use Webhooks v2 (`/v1/webhooks/v2/endpoints`). Sunset: 2026-12-31.\n\nGenerates a new signing secret for the specified merchant webhook endpoint. The old secret is immediately invalidated. The new secret is returned once — store it securely.\n\n**Migration:** Replace with `webhookV2Update`. Move the endpoint to Webhooks v2 and verify the timestamped `X-Webhook-Signature` described in the webhook definitions.",
        "operationId": "rotateMerchantWebhookSecret",
        "parameters": [
          {
            "name": "webhookId",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          },
          {
            "name": "merchant_id",
            "in": "query",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          },
          {
            "$ref": "#/components/parameters/RequestId"
          },
          {
            "$ref": "#/components/parameters/Traceparent"
          },
          {
            "$ref": "#/components/parameters/Tracestate"
          },
          {
            "$ref": "#/components/parameters/AcceptLanguage"
          }
        ],
        "responses": {
          "200": {
            "description": "New secret generated",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "data": {
                      "type": "object",
                      "properties": {
                        "id": {
                          "type": "string",
                          "format": "uuid"
                        },
                        "secret": {
                          "type": "string",
                          "description": "New webhook signing secret — shown once only"
                        }
                      }
                    },
                    "warning": {
                      "type": "string",
                      "example": "Store the new secret securely. It will not be shown again."
                    }
                  }
                },
                "example": {
                  "data": {
                    "id": "00000000-0000-4000-8000-000000000000",
                    "secret": "string"
                  },
                  "warning": "Store the new secret securely. It will not be shown again."
                }
              }
            },
            "headers": {
              "x-fapi-interaction-id": {
                "$ref": "#/components/headers/XFapiInteractionIdResponse"
              },
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/XRateLimitLimit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/XRateLimitRemaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/XRateLimitReset"
              },
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              },
              "traceparent": {
                "$ref": "#/components/headers/Traceparent"
              },
              "Content-Language": {
                "$ref": "#/components/headers/Content-Language"
              }
            }
          },
          "400": {
            "description": "Bad Request — malformed or unrecognised webhook payload. Provider should NOT retry.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              },
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                },
                "examples": {
                  "error": {
                    "$ref": "#/components/examples/ErrorBadRequest"
                  }
                }
              }
            },
            "headers": {
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/XRateLimitLimit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/XRateLimitRemaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/XRateLimitReset"
              },
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "404": {
            "$ref": "#/components/responses/NotFound",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "429": {
            "$ref": "#/components/responses/TooManyRequests",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "default": {
            "description": "Server error — see ProblemDetails for trace ID.",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            },
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/XRateLimitLimit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/XRateLimitRemaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/XRateLimitReset"
              }
            }
          }
        },
        "security": [
          {
            "bearerAuth": []
          }
        ],
        "deprecated": true,
        "x-sunset-date": "2026-12-31",
        "x-successor": "/v1/webhooks/v2/endpoints",
        "x-codeSamples": [
          {
            "lang": "cURL",
            "label": "cURL",
            "source": "curl -X POST \"https://api.kangopenbanking.com/v1/gateway/merchants/webhooks/{webhookId}/rotate-secret\" \\\n  -H \"Authorization: Bearer $KOB_ACCESS_TOKEN\" \\\n  -H \"Content-Type: application/json\""
          },
          {
            "lang": "JavaScript",
            "label": "Node.js",
            "source": "import { KangOpenBanking } from \"@kangopenbanking/sdk\";\n\nconst kob = new KangOpenBanking({ apiKey: process.env.KOB_API_KEY });\nconst res = await kob.request(\"POST\", \"/v1/gateway/merchants/webhooks/{webhookId}/rotate-secret\");\nconsole.log(res);"
          },
          {
            "lang": "Python",
            "label": "Python",
            "source": "from kangopenbanking import KangOpenBanking\n\nkob = KangOpenBanking(api_key=os.environ[\"KOB_API_KEY\"])\nres = kob.request(\"POST\", \"/v1/gateway/merchants/webhooks/{webhookId}/rotate-secret\")\nprint(res)"
          },
          {
            "lang": "PHP",
            "label": "PHP",
            "source": "<?php\n$kob = new KangOpenBanking\\KangOpenBanking(getenv('KOB_API_KEY'));\n$res = $kob->request('POST', '/v1/gateway/merchants/webhooks/{webhookId}/rotate-secret');\nprint_r($res);"
          }
        ],
        "x-replacement-operation-ids": [
          "webhookV2Update"
        ],
        "x-migration-guide": "Move the endpoint to Webhooks v2 and verify the timestamped `X-Webhook-Signature` described in the webhook definitions."
      }
    },
    "/v1/webhooks/providers/stripe": {
      "post": {
        "tags": [
          "Provider Webhooks (Inbound)"
        ],
        "summary": "Stripe inbound webhook",
        "description": "Receives Stripe webhook events. Verifies `stripe-signature` header using HMAC-SHA256. Deduplicates by event ID via `webhook_inbox` table. Maps Stripe events to internal charge/refund/dispute/payout status updates. Return HTTP 400 for malformed payloads to prevent infinite provider retry loops. Return HTTP 200 for all valid but unhandled event types.",
        "operationId": "receiveStripeWebhook",
        "security": [],
        "parameters": [
          {
            "name": "stripe-signature",
            "in": "header",
            "required": true,
            "schema": {
              "type": "string"
            },
            "description": "Stripe HMAC-SHA256 signature header"
          },
          {
            "$ref": "#/components/parameters/RequestId"
          },
          {
            "$ref": "#/components/parameters/Traceparent"
          },
          {
            "$ref": "#/components/parameters/Tracestate"
          },
          {
            "$ref": "#/components/parameters/AcceptLanguage"
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "id": {
                    "type": "string",
                    "example": "evt_1234567890"
                  },
                  "type": {
                    "type": "string",
                    "example": "payment_intent.succeeded"
                  },
                  "data": {
                    "type": "object"
                  }
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Webhook processed",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "status": {
                      "type": "string",
                      "enum": [
                        "processed",
                        "already_processed"
                      ]
                    },
                    "event_type": {
                      "type": "string"
                    }
                  }
                },
                "example": {
                  "status": "processed",
                  "event_type": "string"
                }
              }
            },
            "headers": {
              "x-fapi-interaction-id": {
                "$ref": "#/components/headers/XFapiInteractionIdResponse"
              },
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/XRateLimitLimit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/XRateLimitRemaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/XRateLimitReset"
              },
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              },
              "traceparent": {
                "$ref": "#/components/headers/Traceparent"
              },
              "Content-Language": {
                "$ref": "#/components/headers/Content-Language"
              }
            }
          },
          "400": {
            "description": "Bad Request — malformed or unrecognised webhook payload. Provider should NOT retry.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              },
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                },
                "examples": {
                  "error": {
                    "$ref": "#/components/examples/ErrorBadRequest"
                  }
                }
              }
            },
            "headers": {
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/XRateLimitLimit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/XRateLimitRemaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/XRateLimitReset"
              },
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "429": {
            "$ref": "#/components/responses/TooManyRequests",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "default": {
            "description": "Server error — see ProblemDetails for trace ID.",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            },
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/XRateLimitLimit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/XRateLimitRemaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/XRateLimitReset"
              }
            }
          }
        },
        "x-codeSamples": [
          {
            "lang": "cURL",
            "label": "cURL",
            "source": "curl -X POST \"https://api.kangopenbanking.com/v1/webhooks/providers/stripe\" \\\n  -H \"Authorization: Bearer $KOB_ACCESS_TOKEN\" \\\n  -H \"Content-Type: application/json\" \\\n  -d '{}'"
          },
          {
            "lang": "JavaScript",
            "label": "Node.js",
            "source": "import { KangOpenBanking } from \"@kangopenbanking/sdk\";\n\nconst kob = new KangOpenBanking({ apiKey: process.env.KOB_API_KEY });\nconst res = await kob.request(\"POST\", \"/v1/webhooks/providers/stripe\", { /* payload */ });\nconsole.log(res);"
          },
          {
            "lang": "Python",
            "label": "Python",
            "source": "from kangopenbanking import KangOpenBanking\n\nkob = KangOpenBanking(api_key=os.environ[\"KOB_API_KEY\"])\nres = kob.request(\"POST\", \"/v1/webhooks/providers/stripe\", json={})\nprint(res)"
          },
          {
            "lang": "PHP",
            "label": "PHP",
            "source": "<?php\n$kob = new KangOpenBanking\\KangOpenBanking(getenv('KOB_API_KEY'));\n$res = $kob->request('POST', '/v1/webhooks/providers/stripe', []);\nprint_r($res);"
          }
        ]
      }
    },
    "/v1/webhooks/providers/flutterwave": {
      "post": {
        "tags": [
          "Provider Webhooks (Inbound)"
        ],
        "summary": "Flutterwave inbound webhook",
        "description": "Receives Flutterwave webhook events. Verifies `verif-hash` header against configured secret. Deduplicates by event ID. Maps Flutterwave events to internal charge/payout/refund status updates. Return HTTP 400 for malformed payloads to prevent infinite provider retry loops. Return HTTP 200 for all valid but unhandled event types.",
        "operationId": "receiveFlutterwaveWebhook",
        "security": [],
        "parameters": [
          {
            "name": "verif-hash",
            "in": "header",
            "required": true,
            "schema": {
              "type": "string"
            },
            "description": "Flutterwave verification hash"
          },
          {
            "$ref": "#/components/parameters/RequestId"
          },
          {
            "$ref": "#/components/parameters/Traceparent"
          },
          {
            "$ref": "#/components/parameters/Tracestate"
          },
          {
            "$ref": "#/components/parameters/AcceptLanguage"
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "event": {
                    "type": "string",
                    "example": "charge.completed"
                  },
                  "data": {
                    "type": "object"
                  }
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Webhook processed",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "status": {
                      "type": "string",
                      "enum": [
                        "processed",
                        "already_processed"
                      ]
                    },
                    "event_type": {
                      "type": "string"
                    }
                  }
                },
                "example": {
                  "status": "processed",
                  "event_type": "string"
                }
              }
            },
            "headers": {
              "x-fapi-interaction-id": {
                "$ref": "#/components/headers/XFapiInteractionIdResponse"
              },
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/XRateLimitLimit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/XRateLimitRemaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/XRateLimitReset"
              },
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              },
              "traceparent": {
                "$ref": "#/components/headers/Traceparent"
              },
              "Content-Language": {
                "$ref": "#/components/headers/Content-Language"
              }
            }
          },
          "400": {
            "description": "Bad Request — malformed or unrecognised webhook payload. Provider should NOT retry.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              },
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                },
                "examples": {
                  "error": {
                    "$ref": "#/components/examples/ErrorBadRequest"
                  }
                }
              }
            },
            "headers": {
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/XRateLimitLimit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/XRateLimitRemaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/XRateLimitReset"
              },
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "429": {
            "$ref": "#/components/responses/TooManyRequests",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "default": {
            "description": "Server error — see ProblemDetails for trace ID.",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            },
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/XRateLimitLimit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/XRateLimitRemaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/XRateLimitReset"
              }
            }
          }
        },
        "x-codeSamples": [
          {
            "lang": "cURL",
            "label": "cURL",
            "source": "curl -X POST \"https://api.kangopenbanking.com/v1/webhooks/providers/flutterwave\" \\\n  -H \"Authorization: Bearer $KOB_ACCESS_TOKEN\" \\\n  -H \"Content-Type: application/json\" \\\n  -d '{}'"
          },
          {
            "lang": "JavaScript",
            "label": "Node.js",
            "source": "import { KangOpenBanking } from \"@kangopenbanking/sdk\";\n\nconst kob = new KangOpenBanking({ apiKey: process.env.KOB_API_KEY });\nconst res = await kob.request(\"POST\", \"/v1/webhooks/providers/flutterwave\", { /* payload */ });\nconsole.log(res);"
          },
          {
            "lang": "Python",
            "label": "Python",
            "source": "from kangopenbanking import KangOpenBanking\n\nkob = KangOpenBanking(api_key=os.environ[\"KOB_API_KEY\"])\nres = kob.request(\"POST\", \"/v1/webhooks/providers/flutterwave\", json={})\nprint(res)"
          },
          {
            "lang": "PHP",
            "label": "PHP",
            "source": "<?php\n$kob = new KangOpenBanking\\KangOpenBanking(getenv('KOB_API_KEY'));\n$res = $kob->request('POST', '/v1/webhooks/providers/flutterwave', []);\nprint_r($res);"
          }
        ]
      }
    },
    "/v1/webhooks/providers/paypal": {
      "post": {
        "tags": [
          "Provider Webhooks (Inbound)"
        ],
        "summary": "PayPal inbound webhook",
        "description": "Receives PayPal webhook events for payment captures, checkout approvals, and payout status updates.\n\n**Signature Verification (Certificate-Based)**\n\nKOB verifies PayPal webhooks using PayPal's `POST /v1/notifications/verify-webhook-signature` API — not local cert validation. The flow:\n\n1. Extract the 5 `paypal-*` headers from the incoming request\n2. POST them along with the raw event body and the configured `PAYPAL_WEBHOOK_ID` to PayPal's verification endpoint\n3. If PayPal returns `verification_status: \"SUCCESS\"`, the event is accepted; otherwise rejected with `401`\n\n**Deduplication**: Events are keyed by `paypal_{event.id}` in the `webhook_inbox` table. Duplicates return `200 {status: \"already_processed\"}`.\n\n**Handled Event Types**:\n- `PAYMENT.CAPTURE.COMPLETED` → funding intent succeeded, triggers ledger credit\n- `CHECKOUT.ORDER.APPROVED` → auto-captures PayPal order\n- `PAYOUTS-ITEM.*` → payout status sync (succeeded/failed/reversed) Return HTTP 400 for malformed payloads to prevent infinite provider retry loops. Return HTTP 200 for all valid but unhandled event types. **Signature Verification:** All inbound PayPal webhooks MUST be verified using the PayPal Webhook Signature Verification API (POST /v1/notifications/verify-webhook-signature). Required headers: PAYPAL-TRANSMISSION-ID, PAYPAL-TRANSMISSION-TIME, PAYPAL-TRANSMISSION-SIG, PAYPAL-CERT-URL, PAYPAL-AUTH-ALGO. The server must validate the transmission signature against the webhook ID before processing any event. Unverified payloads must be rejected with HTTP 401. See: https://developer.paypal.com/docs/api/webhooks/v1/#verify-webhook-signature_post\n\n**PayPal Webhook Request Headers (present on every delivery):**\n\n| Header | Description |\n|--------|-------------|\n| `PayPal-Transmission-Id` | Unique identifier for this webhook transmission. Use for deduplication. |\n| `PayPal-Transmission-Time` | ISO 8601 timestamp when PayPal transmitted the event. |\n| `PayPal-Cert-Url` | HTTPS URL of the PayPal X.509 public certificate used for signing. Cache with ETag. |\n| `PayPal-Auth-Algo` | Signing algorithm, typically `SHA256withRSA`. |\n| `PayPal-Transmission-Sig` | Base64-encoded RSA-SHA256 signature over the verification string. |\n\n**Manual Verification Algorithm (alternative to API-based verification):**\n1. Retrieve the certificate from `PayPal-Cert-Url` (validate it is a paypal.com domain)\n2. Construct the verification string: `{PayPal-Transmission-Id}|{PayPal-Transmission-Time}|{PAYPAL_WEBHOOK_ID}|{CRC32(raw_request_body)}`\n3. Verify `PayPal-Transmission-Sig` against the verification string using the certificate's public key and the algorithm in `PayPal-Auth-Algo`\n4. Reject any request where verification fails — return HTTP 400 to halt retries\n5. For SDK-based verification, use PayPal's Node.js/Java/PHP SDKs which handle the above automatically",
        "operationId": "receivePaypalWebhook",
        "security": [],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "id": {
                    "type": "string",
                    "example": "WH-1234567890"
                  },
                  "event_type": {
                    "type": "string",
                    "example": "PAYMENT.CAPTURE.COMPLETED"
                  },
                  "resource": {
                    "type": "object"
                  }
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Webhook processed",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "status": {
                      "type": "string",
                      "enum": [
                        "processed",
                        "already_processed"
                      ]
                    },
                    "event_type": {
                      "type": "string"
                    }
                  }
                },
                "example": {
                  "status": "processed",
                  "event_type": "string"
                }
              }
            },
            "headers": {
              "x-fapi-interaction-id": {
                "$ref": "#/components/headers/XFapiInteractionIdResponse"
              },
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/XRateLimitLimit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/XRateLimitRemaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/XRateLimitReset"
              },
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              },
              "traceparent": {
                "$ref": "#/components/headers/Traceparent"
              },
              "Content-Language": {
                "$ref": "#/components/headers/Content-Language"
              }
            }
          },
          "400": {
            "description": "Bad Request — malformed or unrecognised webhook payload. Provider should NOT retry.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              },
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                },
                "examples": {
                  "error": {
                    "$ref": "#/components/examples/ErrorBadRequest"
                  }
                }
              }
            },
            "headers": {
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/XRateLimitLimit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/XRateLimitRemaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/XRateLimitReset"
              },
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "429": {
            "$ref": "#/components/responses/TooManyRequests",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "default": {
            "description": "Server error — see ProblemDetails for trace ID.",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            },
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/XRateLimitLimit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/XRateLimitRemaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/XRateLimitReset"
              }
            }
          }
        },
        "parameters": [
          {
            "name": "paypal-auth-algo",
            "in": "header",
            "required": true,
            "schema": {
              "type": "string",
              "example": "SHA256withRSA"
            },
            "description": "Signature algorithm used by PayPal (e.g. SHA256withRSA)"
          },
          {
            "name": "paypal-cert-url",
            "in": "header",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uri",
              "example": "https://api.paypal.com/v1/notifications/certs/CERT-360caa42-fca2a594"
            },
            "description": "URL to PayPal's signing certificate for this webhook"
          },
          {
            "name": "paypal-transmission-id",
            "in": "header",
            "required": true,
            "schema": {
              "type": "string",
              "example": "69cd13f0-d67a-11e5-baa3-778b53f4ae55"
            },
            "description": "Unique transmission ID for this webhook delivery"
          },
          {
            "name": "paypal-transmission-sig",
            "in": "header",
            "required": true,
            "schema": {
              "type": "string"
            },
            "description": "Base64-encoded RSA signature of the transmission"
          },
          {
            "name": "paypal-transmission-time",
            "in": "header",
            "required": true,
            "schema": {
              "type": "string",
              "format": "date-time",
              "example": "2026-03-22T10:00:00Z"
            },
            "description": "ISO 8601 timestamp of webhook transmission"
          },
          {
            "name": "PAYPAL-TRANSMISSION-ID",
            "in": "header",
            "required": true,
            "description": "PayPal-generated unique transmission ID",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "PAYPAL-TRANSMISSION-TIME",
            "in": "header",
            "required": true,
            "description": "PayPal transmission timestamp (ISO 8601)",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "PAYPAL-TRANSMISSION-SIG",
            "in": "header",
            "required": true,
            "description": "PayPal HMAC signature for webhook verification",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "PAYPAL-CERT-URL",
            "in": "header",
            "required": true,
            "description": "URL to the PayPal signing certificate",
            "schema": {
              "type": "string",
              "format": "uri"
            }
          },
          {
            "name": "PAYPAL-AUTH-ALGO",
            "in": "header",
            "required": true,
            "description": "Algorithm used for the signature (e.g. SHA256withRSA)",
            "schema": {
              "type": "string"
            }
          },
          {
            "$ref": "#/components/parameters/RequestId"
          },
          {
            "$ref": "#/components/parameters/Traceparent"
          },
          {
            "$ref": "#/components/parameters/Tracestate"
          },
          {
            "$ref": "#/components/parameters/AcceptLanguage"
          }
        ],
        "x-codeSamples": [
          {
            "lang": "cURL",
            "label": "cURL",
            "source": "curl -X POST \"https://api.kangopenbanking.com/v1/webhooks/providers/paypal\" \\\n  -H \"Authorization: Bearer $KOB_ACCESS_TOKEN\" \\\n  -H \"Content-Type: application/json\" \\\n  -d '{}'"
          },
          {
            "lang": "JavaScript",
            "label": "Node.js",
            "source": "import { KangOpenBanking } from \"@kangopenbanking/sdk\";\n\nconst kob = new KangOpenBanking({ apiKey: process.env.KOB_API_KEY });\nconst res = await kob.request(\"POST\", \"/v1/webhooks/providers/paypal\", { /* payload */ });\nconsole.log(res);"
          },
          {
            "lang": "Python",
            "label": "Python",
            "source": "from kangopenbanking import KangOpenBanking\n\nkob = KangOpenBanking(api_key=os.environ[\"KOB_API_KEY\"])\nres = kob.request(\"POST\", \"/v1/webhooks/providers/paypal\", json={})\nprint(res)"
          },
          {
            "lang": "PHP",
            "label": "PHP",
            "source": "<?php\n$kob = new KangOpenBanking\\KangOpenBanking(getenv('KOB_API_KEY'));\n$res = $kob->request('POST', '/v1/webhooks/providers/paypal', []);\nprint_r($res);"
          }
        ]
      }
    },
    "/v1/savings/accounts/{accountId}": {
      "get": {
        "operationId": "getSavingsAccount",
        "summary": "Get a savings account by ID",
        "description": "Retrieve a single savings account by its unique identifier. Requires a valid AISP consent.",
        "tags": [
          "Savings",
          "AISP"
        ],
        "security": [
          {
            "bearerAuth": []
          }
        ],
        "parameters": [
          {
            "name": "accountId",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid"
            },
            "description": "Savings account unique identifier"
          },
          {
            "name": "x-consent-id",
            "in": "header",
            "required": true,
            "description": "Active AISP consent ID",
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          },
          {
            "$ref": "#/components/parameters/XFapiInteractionId"
          },
          {
            "$ref": "#/components/parameters/RequestId"
          },
          {
            "$ref": "#/components/parameters/Traceparent"
          },
          {
            "$ref": "#/components/parameters/Tracestate"
          },
          {
            "$ref": "#/components/parameters/AcceptLanguage"
          }
        ],
        "responses": {
          "200": {
            "description": "Savings account details",
            "headers": {
              "x-fapi-interaction-id": {
                "$ref": "#/components/headers/XFapiInteractionIdResponse"
              },
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/XRateLimitLimit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/XRateLimitRemaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/XRateLimitReset"
              },
              "Cache-Control": {
                "$ref": "#/components/headers/CacheControl"
              },
              "ETag": {
                "$ref": "#/components/headers/ETag"
              },
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              },
              "traceparent": {
                "$ref": "#/components/headers/Traceparent"
              },
              "Content-Language": {
                "$ref": "#/components/headers/Content-Language"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "allOf": [
                    {
                      "$ref": "#/components/schemas/StandardResponse"
                    },
                    {
                      "type": "object",
                      "properties": {
                        "data": {
                          "$ref": "#/components/schemas/SavingsAccount"
                        }
                      }
                    }
                  ]
                },
                "example": {
                  "data": {
                    "account_id": "00000000-0000-4000-8000-000000000000",
                    "product_id": "string",
                    "account_number": "string",
                    "account_holder_name": "string",
                    "balance": "1000",
                    "currency": "XAF",
                    "status": "active",
                    "interest_rate": 0,
                    "opened_date": "2026-01-01",
                    "maturity_date": "2026-01-01",
                    "created_at": "2026-01-01T00:00:00Z",
                    "updated_at": "2026-01-01T00:00:00Z"
                  },
                  "meta": {
                    "request_id": "550e8400-e29b-41d4-a716-446655440000",
                    "timestamp": "2025-03-27T12:00:00Z",
                    "api_version": "4.3.0"
                  }
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "404": {
            "$ref": "#/components/responses/NotFound",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "429": {
            "$ref": "#/components/responses/TooManyRequests",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "default": {
            "description": "Server error — see ProblemDetails for trace ID.",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            },
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/XRateLimitLimit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/XRateLimitRemaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/XRateLimitReset"
              }
            }
          }
        },
        "x-codeSamples": [
          {
            "lang": "cURL",
            "label": "cURL",
            "source": "curl -X GET \"https://api.kangopenbanking.com/v1/savings/accounts/{accountId}\" \\\n  -H \"Authorization: Bearer $KOB_ACCESS_TOKEN\" \\\n  -H \"Content-Type: application/json\""
          },
          {
            "lang": "JavaScript",
            "label": "Node.js",
            "source": "import { KangOpenBanking } from \"@kangopenbanking/sdk\";\n\nconst kob = new KangOpenBanking({ apiKey: process.env.KOB_API_KEY });\nconst res = await kob.request(\"GET\", \"/v1/savings/accounts/{accountId}\");\nconsole.log(res);"
          },
          {
            "lang": "Python",
            "label": "Python",
            "source": "from kangopenbanking import KangOpenBanking\n\nkob = KangOpenBanking(api_key=os.environ[\"KOB_API_KEY\"])\nres = kob.request(\"GET\", \"/v1/savings/accounts/{accountId}\")\nprint(res)"
          },
          {
            "lang": "PHP",
            "label": "PHP",
            "source": "<?php\n$kob = new KangOpenBanking\\KangOpenBanking(getenv('KOB_API_KEY'));\n$res = $kob->request('GET', '/v1/savings/accounts/{accountId}');\nprint_r($res);"
          }
        ]
      }
    },
    "/v1/standards/iso20022/pacs004/generate": {
      "post": {
        "operationId": "generatePacs004",
        "summary": "Generate pacs.004 (PaymentReturn)",
        "description": "Generate an ISO 20022 pacs.004.001.11 PaymentReturn message for returning a previously settled interbank payment.",
        "tags": [
          "Standards - ISO 20022"
        ],
        "security": [
          {
            "bearerAuth": []
          }
        ],
        "x-iso20022-message": "pacs.004.001.11",
        "parameters": [
          {
            "$ref": "#/components/parameters/XFapiInteractionId"
          },
          {
            "name": "Idempotency-Key",
            "in": "header",
            "required": false,
            "description": "Client-generated UUID for idempotent request deduplication.",
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          },
          {
            "$ref": "#/components/parameters/RequestId"
          },
          {
            "$ref": "#/components/parameters/Traceparent"
          },
          {
            "$ref": "#/components/parameters/Tracestate"
          },
          {
            "$ref": "#/components/parameters/AcceptLanguage"
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "description": "Input fields for pacs.004.001.11 message generation",
                "properties": {
                  "source_data": {
                    "type": "object",
                    "description": "Business data to be mapped into the ISO 20022 message structure"
                  },
                  "output_format": {
                    "type": "string",
                    "enum": [
                      "xml",
                      "json"
                    ],
                    "default": "xml",
                    "description": "Output format for the generated message"
                  }
                },
                "required": [
                  "source_data"
                ]
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Generated pacs.004.001.11 message",
            "headers": {
              "x-fapi-interaction-id": {
                "$ref": "#/components/headers/XFapiInteractionIdResponse"
              },
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/XRateLimitLimit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/XRateLimitRemaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/XRateLimitReset"
              },
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              },
              "traceparent": {
                "$ref": "#/components/headers/Traceparent"
              },
              "Content-Language": {
                "$ref": "#/components/headers/Content-Language"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "message_type": {
                      "type": "string",
                      "example": "pacs.004.001.11"
                    },
                    "xml_content": {
                      "type": "string",
                      "description": "The generated ISO 20022 XML message"
                    },
                    "validation_result": {
                      "type": "object",
                      "properties": {
                        "valid": {
                          "type": "boolean"
                        },
                        "errors": {
                          "type": "array",
                          "items": {
                            "type": "string"
                          }
                        }
                      }
                    }
                  }
                },
                "example": {
                  "message_type": "pacs.004.001.11",
                  "xml_content": "string",
                  "validation_result": {
                    "valid": true,
                    "errors": [
                      "string"
                    ]
                  }
                }
              }
            }
          },
          "400": {
            "description": "Bad Request — invalid input data",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              },
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                },
                "examples": {
                  "error": {
                    "$ref": "#/components/examples/ErrorBadRequest"
                  }
                }
              }
            },
            "headers": {
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/XRateLimitLimit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/XRateLimitRemaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/XRateLimitReset"
              },
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "429": {
            "$ref": "#/components/responses/TooManyRequests",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "default": {
            "description": "Server error — see ProblemDetails for trace ID.",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            },
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/XRateLimitLimit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/XRateLimitRemaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/XRateLimitReset"
              }
            }
          }
        },
        "x-codeSamples": [
          {
            "lang": "cURL",
            "label": "cURL",
            "source": "curl -X POST \"https://api.kangopenbanking.com/v1/standards/iso20022/pacs004/generate\" \\\n  -H \"Authorization: Bearer $KOB_ACCESS_TOKEN\" \\\n  -H \"Content-Type: application/json\" \\\n  -d '{}'"
          },
          {
            "lang": "JavaScript",
            "label": "Node.js",
            "source": "import { KangOpenBanking } from \"@kangopenbanking/sdk\";\n\nconst kob = new KangOpenBanking({ apiKey: process.env.KOB_API_KEY });\nconst res = await kob.request(\"POST\", \"/v1/standards/iso20022/pacs004/generate\", { /* payload */ });\nconsole.log(res);"
          },
          {
            "lang": "Python",
            "label": "Python",
            "source": "from kangopenbanking import KangOpenBanking\n\nkob = KangOpenBanking(api_key=os.environ[\"KOB_API_KEY\"])\nres = kob.request(\"POST\", \"/v1/standards/iso20022/pacs004/generate\", json={})\nprint(res)"
          },
          {
            "lang": "PHP",
            "label": "PHP",
            "source": "<?php\n$kob = new KangOpenBanking\\KangOpenBanking(getenv('KOB_API_KEY'));\n$res = $kob->request('POST', '/v1/standards/iso20022/pacs004/generate', []);\nprint_r($res);"
          }
        ]
      }
    },
    "/v1/standards/iso20022/pacs009/generate": {
      "post": {
        "operationId": "generatePacs009",
        "summary": "Generate pacs.009 (FinancialInstitutionCreditTransfer)",
        "description": "Generate an ISO 20022 pacs.009.001.10 FinancialInstitutionCreditTransfer message for interbank cover payments.",
        "tags": [
          "Standards - ISO 20022"
        ],
        "security": [
          {
            "bearerAuth": []
          }
        ],
        "x-iso20022-message": "pacs.009.001.10",
        "parameters": [
          {
            "$ref": "#/components/parameters/XFapiInteractionId"
          },
          {
            "name": "Idempotency-Key",
            "in": "header",
            "required": false,
            "description": "Client-generated UUID for idempotent request deduplication.",
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          },
          {
            "$ref": "#/components/parameters/RequestId"
          },
          {
            "$ref": "#/components/parameters/Traceparent"
          },
          {
            "$ref": "#/components/parameters/Tracestate"
          },
          {
            "$ref": "#/components/parameters/AcceptLanguage"
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "description": "Input fields for pacs.009.001.10 message generation",
                "properties": {
                  "source_data": {
                    "type": "object",
                    "description": "Business data to be mapped into the ISO 20022 message structure"
                  },
                  "output_format": {
                    "type": "string",
                    "enum": [
                      "xml",
                      "json"
                    ],
                    "default": "xml",
                    "description": "Output format for the generated message"
                  }
                },
                "required": [
                  "source_data"
                ]
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Generated pacs.009.001.10 message",
            "headers": {
              "x-fapi-interaction-id": {
                "$ref": "#/components/headers/XFapiInteractionIdResponse"
              },
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/XRateLimitLimit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/XRateLimitRemaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/XRateLimitReset"
              },
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              },
              "traceparent": {
                "$ref": "#/components/headers/Traceparent"
              },
              "Content-Language": {
                "$ref": "#/components/headers/Content-Language"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "message_type": {
                      "type": "string",
                      "example": "pacs.009.001.10"
                    },
                    "xml_content": {
                      "type": "string",
                      "description": "The generated ISO 20022 XML message"
                    },
                    "validation_result": {
                      "type": "object",
                      "properties": {
                        "valid": {
                          "type": "boolean"
                        },
                        "errors": {
                          "type": "array",
                          "items": {
                            "type": "string"
                          }
                        }
                      }
                    }
                  }
                },
                "example": {
                  "message_type": "pacs.009.001.10",
                  "xml_content": "string",
                  "validation_result": {
                    "valid": true,
                    "errors": [
                      "string"
                    ]
                  }
                }
              }
            }
          },
          "400": {
            "description": "Bad Request — invalid input data",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              },
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                },
                "examples": {
                  "error": {
                    "$ref": "#/components/examples/ErrorBadRequest"
                  }
                }
              }
            },
            "headers": {
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/XRateLimitLimit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/XRateLimitRemaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/XRateLimitReset"
              },
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "429": {
            "$ref": "#/components/responses/TooManyRequests",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "default": {
            "description": "Server error — see ProblemDetails for trace ID.",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            },
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/XRateLimitLimit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/XRateLimitRemaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/XRateLimitReset"
              }
            }
          }
        },
        "x-codeSamples": [
          {
            "lang": "cURL",
            "label": "cURL",
            "source": "curl -X POST \"https://api.kangopenbanking.com/v1/standards/iso20022/pacs009/generate\" \\\n  -H \"Authorization: Bearer $KOB_ACCESS_TOKEN\" \\\n  -H \"Content-Type: application/json\" \\\n  -d '{}'"
          },
          {
            "lang": "JavaScript",
            "label": "Node.js",
            "source": "import { KangOpenBanking } from \"@kangopenbanking/sdk\";\n\nconst kob = new KangOpenBanking({ apiKey: process.env.KOB_API_KEY });\nconst res = await kob.request(\"POST\", \"/v1/standards/iso20022/pacs009/generate\", { /* payload */ });\nconsole.log(res);"
          },
          {
            "lang": "Python",
            "label": "Python",
            "source": "from kangopenbanking import KangOpenBanking\n\nkob = KangOpenBanking(api_key=os.environ[\"KOB_API_KEY\"])\nres = kob.request(\"POST\", \"/v1/standards/iso20022/pacs009/generate\", json={})\nprint(res)"
          },
          {
            "lang": "PHP",
            "label": "PHP",
            "source": "<?php\n$kob = new KangOpenBanking\\KangOpenBanking(getenv('KOB_API_KEY'));\n$res = $kob->request('POST', '/v1/standards/iso20022/pacs009/generate', []);\nprint_r($res);"
          }
        ]
      }
    },
    "/v1/standards/iso20022/camt056/generate": {
      "post": {
        "operationId": "generateCamt056",
        "summary": "Generate camt.056 (FIToFIPaymentCancellationRequest)",
        "description": "Generate an ISO 20022 camt.056.001.10 payment cancellation request for recalling an interbank payment before settlement.",
        "tags": [
          "Standards - ISO 20022"
        ],
        "security": [
          {
            "bearerAuth": []
          }
        ],
        "x-iso20022-message": "camt.056.001.10",
        "parameters": [
          {
            "$ref": "#/components/parameters/XFapiInteractionId"
          },
          {
            "name": "Idempotency-Key",
            "in": "header",
            "required": false,
            "description": "Client-generated UUID for idempotent request deduplication.",
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          },
          {
            "$ref": "#/components/parameters/RequestId"
          },
          {
            "$ref": "#/components/parameters/Traceparent"
          },
          {
            "$ref": "#/components/parameters/Tracestate"
          },
          {
            "$ref": "#/components/parameters/AcceptLanguage"
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "description": "Input fields for camt.056.001.10 message generation",
                "properties": {
                  "source_data": {
                    "type": "object",
                    "description": "Business data to be mapped into the ISO 20022 message structure"
                  },
                  "output_format": {
                    "type": "string",
                    "enum": [
                      "xml",
                      "json"
                    ],
                    "default": "xml",
                    "description": "Output format for the generated message"
                  }
                },
                "required": [
                  "source_data"
                ]
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Generated camt.056.001.10 message",
            "headers": {
              "x-fapi-interaction-id": {
                "$ref": "#/components/headers/XFapiInteractionIdResponse"
              },
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/XRateLimitLimit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/XRateLimitRemaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/XRateLimitReset"
              },
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              },
              "traceparent": {
                "$ref": "#/components/headers/Traceparent"
              },
              "Content-Language": {
                "$ref": "#/components/headers/Content-Language"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "message_type": {
                      "type": "string",
                      "example": "camt.056.001.10"
                    },
                    "xml_content": {
                      "type": "string",
                      "description": "The generated ISO 20022 XML message"
                    },
                    "validation_result": {
                      "type": "object",
                      "properties": {
                        "valid": {
                          "type": "boolean"
                        },
                        "errors": {
                          "type": "array",
                          "items": {
                            "type": "string"
                          }
                        }
                      }
                    }
                  }
                },
                "example": {
                  "message_type": "camt.056.001.10",
                  "xml_content": "string",
                  "validation_result": {
                    "valid": true,
                    "errors": [
                      "string"
                    ]
                  }
                }
              }
            }
          },
          "400": {
            "description": "Bad Request — invalid input data",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              },
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                },
                "examples": {
                  "error": {
                    "$ref": "#/components/examples/ErrorBadRequest"
                  }
                }
              }
            },
            "headers": {
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/XRateLimitLimit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/XRateLimitRemaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/XRateLimitReset"
              },
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "429": {
            "$ref": "#/components/responses/TooManyRequests",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "default": {
            "description": "Server error — see ProblemDetails for trace ID.",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            },
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/XRateLimitLimit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/XRateLimitRemaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/XRateLimitReset"
              }
            }
          }
        },
        "x-codeSamples": [
          {
            "lang": "cURL",
            "label": "cURL",
            "source": "curl -X POST \"https://api.kangopenbanking.com/v1/standards/iso20022/camt056/generate\" \\\n  -H \"Authorization: Bearer $KOB_ACCESS_TOKEN\" \\\n  -H \"Content-Type: application/json\" \\\n  -d '{}'"
          },
          {
            "lang": "JavaScript",
            "label": "Node.js",
            "source": "import { KangOpenBanking } from \"@kangopenbanking/sdk\";\n\nconst kob = new KangOpenBanking({ apiKey: process.env.KOB_API_KEY });\nconst res = await kob.request(\"POST\", \"/v1/standards/iso20022/camt056/generate\", { /* payload */ });\nconsole.log(res);"
          },
          {
            "lang": "Python",
            "label": "Python",
            "source": "from kangopenbanking import KangOpenBanking\n\nkob = KangOpenBanking(api_key=os.environ[\"KOB_API_KEY\"])\nres = kob.request(\"POST\", \"/v1/standards/iso20022/camt056/generate\", json={})\nprint(res)"
          },
          {
            "lang": "PHP",
            "label": "PHP",
            "source": "<?php\n$kob = new KangOpenBanking\\KangOpenBanking(getenv('KOB_API_KEY'));\n$res = $kob->request('POST', '/v1/standards/iso20022/camt056/generate', []);\nprint_r($res);"
          }
        ]
      }
    },
    "/v1/standards/iso20022/camt052/parse": {
      "post": {
        "operationId": "parseISO20022Camt052",
        "summary": "Parse ISO 20022 camt.052 Bank-to-Customer Account Report",
        "description": "Parse and validate an inbound ISO 20022 camt.052.001.08 (Bank-to-Customer Account Report) XML message. This intraday report is sent BY the bank TO the platform to report account balances and transactions during the business day. Generate an ISO 20022 camt.052.001.10 intraday account report for real-time balance and transaction reporting.",
        "tags": [
          "Standards - ISO 20022"
        ],
        "security": [
          {
            "bearerAuth": []
          }
        ],
        "x-iso20022-message": "camt.052.001.08",
        "parameters": [
          {
            "$ref": "#/components/parameters/XFapiInteractionId"
          },
          {
            "name": "Idempotency-Key",
            "in": "header",
            "required": false,
            "description": "Client-generated UUID for idempotent request deduplication.",
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          },
          {
            "$ref": "#/components/parameters/RequestId"
          },
          {
            "$ref": "#/components/parameters/Traceparent"
          },
          {
            "$ref": "#/components/parameters/Tracestate"
          },
          {
            "$ref": "#/components/parameters/AcceptLanguage"
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "description": "Input fields for camt.052.001.10 message generation",
                "properties": {
                  "source_data": {
                    "type": "object",
                    "description": "Business data to be mapped into the ISO 20022 message structure"
                  },
                  "output_format": {
                    "type": "string",
                    "enum": [
                      "xml",
                      "json"
                    ],
                    "default": "xml",
                    "description": "Output format for the generated message"
                  }
                },
                "required": [
                  "source_data"
                ]
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Generated camt.052.001.10 message",
            "headers": {
              "x-fapi-interaction-id": {
                "$ref": "#/components/headers/XFapiInteractionIdResponse"
              },
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/XRateLimitLimit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/XRateLimitRemaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/XRateLimitReset"
              },
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              },
              "traceparent": {
                "$ref": "#/components/headers/Traceparent"
              },
              "Content-Language": {
                "$ref": "#/components/headers/Content-Language"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "message_type": {
                      "type": "string",
                      "example": "camt.052.001.10"
                    },
                    "xml_content": {
                      "type": "string",
                      "description": "The generated ISO 20022 XML message"
                    },
                    "validation_result": {
                      "type": "object",
                      "properties": {
                        "valid": {
                          "type": "boolean"
                        },
                        "errors": {
                          "type": "array",
                          "items": {
                            "type": "string"
                          }
                        }
                      }
                    }
                  }
                },
                "example": {
                  "message_type": "camt.052.001.10",
                  "xml_content": "string",
                  "validation_result": {
                    "valid": true,
                    "errors": [
                      "string"
                    ]
                  }
                }
              }
            }
          },
          "400": {
            "description": "Bad Request — invalid input data",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              },
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                },
                "examples": {
                  "error": {
                    "$ref": "#/components/examples/ErrorBadRequest"
                  }
                }
              }
            },
            "headers": {
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/XRateLimitLimit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/XRateLimitRemaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/XRateLimitReset"
              },
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "429": {
            "$ref": "#/components/responses/TooManyRequests",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "default": {
            "description": "Server error — see ProblemDetails for trace ID.",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            },
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/XRateLimitLimit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/XRateLimitRemaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/XRateLimitReset"
              }
            }
          }
        },
        "x-codeSamples": [
          {
            "lang": "cURL",
            "label": "cURL",
            "source": "curl -X POST \"https://api.kangopenbanking.com/v1/standards/iso20022/camt052/parse\" \\\n  -H \"Authorization: Bearer $KOB_ACCESS_TOKEN\" \\\n  -H \"Content-Type: application/json\" \\\n  -d '{}'"
          },
          {
            "lang": "JavaScript",
            "label": "Node.js",
            "source": "import { KangOpenBanking } from \"@kangopenbanking/sdk\";\n\nconst kob = new KangOpenBanking({ apiKey: process.env.KOB_API_KEY });\nconst res = await kob.request(\"POST\", \"/v1/standards/iso20022/camt052/parse\", { /* payload */ });\nconsole.log(res);"
          },
          {
            "lang": "Python",
            "label": "Python",
            "source": "from kangopenbanking import KangOpenBanking\n\nkob = KangOpenBanking(api_key=os.environ[\"KOB_API_KEY\"])\nres = kob.request(\"POST\", \"/v1/standards/iso20022/camt052/parse\", json={})\nprint(res)"
          },
          {
            "lang": "PHP",
            "label": "PHP",
            "source": "<?php\n$kob = new KangOpenBanking\\KangOpenBanking(getenv('KOB_API_KEY'));\n$res = $kob->request('POST', '/v1/standards/iso20022/camt052/parse', []);\nprint_r($res);"
          }
        ]
      }
    },
    "/v1/standards/iso20022/camt054/parse": {
      "post": {
        "operationId": "parseISO20022Camt054",
        "summary": "Parse ISO 20022 camt.054 Bank-to-Customer Debit Credit Notification",
        "description": "Parse and validate an inbound ISO 20022 camt.054.001.08 (Bank-to-Customer Debit/Credit Notification) XML message. This notification is sent BY the bank TO the platform to report a specific debit or credit to a customer account in real time. Generate an ISO 20022 camt.054.001.10 debit/credit notification for real-time transaction alerting.",
        "tags": [
          "Standards - ISO 20022"
        ],
        "security": [
          {
            "bearerAuth": []
          }
        ],
        "x-iso20022-message": "camt.054.001.08",
        "parameters": [
          {
            "$ref": "#/components/parameters/XFapiInteractionId"
          },
          {
            "name": "Idempotency-Key",
            "in": "header",
            "required": false,
            "description": "Client-generated UUID for idempotent request deduplication.",
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          },
          {
            "$ref": "#/components/parameters/RequestId"
          },
          {
            "$ref": "#/components/parameters/Traceparent"
          },
          {
            "$ref": "#/components/parameters/Tracestate"
          },
          {
            "$ref": "#/components/parameters/AcceptLanguage"
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "description": "Input fields for camt.054.001.10 message generation",
                "properties": {
                  "source_data": {
                    "type": "object",
                    "description": "Business data to be mapped into the ISO 20022 message structure"
                  },
                  "output_format": {
                    "type": "string",
                    "enum": [
                      "xml",
                      "json"
                    ],
                    "default": "xml",
                    "description": "Output format for the generated message"
                  }
                },
                "required": [
                  "source_data"
                ]
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Generated camt.054.001.10 message",
            "headers": {
              "x-fapi-interaction-id": {
                "$ref": "#/components/headers/XFapiInteractionIdResponse"
              },
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/XRateLimitLimit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/XRateLimitRemaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/XRateLimitReset"
              },
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              },
              "traceparent": {
                "$ref": "#/components/headers/Traceparent"
              },
              "Content-Language": {
                "$ref": "#/components/headers/Content-Language"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "message_type": {
                      "type": "string",
                      "example": "camt.054.001.10"
                    },
                    "xml_content": {
                      "type": "string",
                      "description": "The generated ISO 20022 XML message"
                    },
                    "validation_result": {
                      "type": "object",
                      "properties": {
                        "valid": {
                          "type": "boolean"
                        },
                        "errors": {
                          "type": "array",
                          "items": {
                            "type": "string"
                          }
                        }
                      }
                    }
                  }
                },
                "example": {
                  "message_type": "camt.054.001.10",
                  "xml_content": "string",
                  "validation_result": {
                    "valid": true,
                    "errors": [
                      "string"
                    ]
                  }
                }
              }
            }
          },
          "400": {
            "description": "Bad Request — invalid input data",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              },
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                },
                "examples": {
                  "error": {
                    "$ref": "#/components/examples/ErrorBadRequest"
                  }
                }
              }
            },
            "headers": {
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/XRateLimitLimit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/XRateLimitRemaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/XRateLimitReset"
              },
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "429": {
            "$ref": "#/components/responses/TooManyRequests",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "default": {
            "description": "Server error — see ProblemDetails for trace ID.",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            },
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/XRateLimitLimit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/XRateLimitRemaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/XRateLimitReset"
              }
            }
          }
        },
        "x-codeSamples": [
          {
            "lang": "cURL",
            "label": "cURL",
            "source": "curl -X POST \"https://api.kangopenbanking.com/v1/standards/iso20022/camt054/parse\" \\\n  -H \"Authorization: Bearer $KOB_ACCESS_TOKEN\" \\\n  -H \"Content-Type: application/json\" \\\n  -d '{}'"
          },
          {
            "lang": "JavaScript",
            "label": "Node.js",
            "source": "import { KangOpenBanking } from \"@kangopenbanking/sdk\";\n\nconst kob = new KangOpenBanking({ apiKey: process.env.KOB_API_KEY });\nconst res = await kob.request(\"POST\", \"/v1/standards/iso20022/camt054/parse\", { /* payload */ });\nconsole.log(res);"
          },
          {
            "lang": "Python",
            "label": "Python",
            "source": "from kangopenbanking import KangOpenBanking\n\nkob = KangOpenBanking(api_key=os.environ[\"KOB_API_KEY\"])\nres = kob.request(\"POST\", \"/v1/standards/iso20022/camt054/parse\", json={})\nprint(res)"
          },
          {
            "lang": "PHP",
            "label": "PHP",
            "source": "<?php\n$kob = new KangOpenBanking\\KangOpenBanking(getenv('KOB_API_KEY'));\n$res = $kob->request('POST', '/v1/standards/iso20022/camt054/parse', []);\nprint_r($res);"
          }
        ]
      }
    },
    "/healthz": {
      "get": {
        "tags": [
          "Monitoring"
        ],
        "summary": "Security posture self-verification",
        "description": "Reviewer-friendly snapshot of the API's live security posture: OAuth 2.0, OIDC, mTLS (FAPI 1.0 Advanced / RFC 8705), DCR (RFC 7591), PAR (RFC 9126), JAR (RFC 9101), PKCE (RFC 7636 — S256), webhook signing, JWKS rotation, and sandbox status. Returns 200 with cache-control public, max-age=60. No authentication required.",
        "operationId": "securityHealthz",
        "security": [],
        "responses": {
          "200": {
            "description": "Live security posture snapshot",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "additionalProperties": true
                },
                "example": {}
              }
            },
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              },
              "traceparent": {
                "$ref": "#/components/headers/Traceparent"
              },
              "Content-Language": {
                "$ref": "#/components/headers/Content-Language"
              },
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/XRateLimitLimit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/XRateLimitRemaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/XRateLimitReset"
              },
              "x-fapi-interaction-id": {
                "$ref": "#/components/headers/XFapiInteractionId"
              }
            }
          },
          "429": {
            "description": "Rate limit exceeded. Retry after the interval in `Retry-After`.",
            "headers": {
              "Retry-After": {
                "schema": {
                  "type": "integer"
                },
                "description": "Seconds to wait before retrying."
              },
              "X-RateLimit-Limit": {
                "schema": {
                  "type": "integer"
                }
              },
              "X-RateLimit-Remaining": {
                "schema": {
                  "type": "integer"
                }
              },
              "X-RateLimit-Reset": {
                "schema": {
                  "type": "integer"
                }
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                },
                "examples": {
                  "rateLimited": {
                    "$ref": "#/components/examples/ErrorRateLimited"
                  }
                }
              }
            }
          },
          "default": {
            "description": "Server error — see ProblemDetails for trace ID.",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            },
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/XRateLimitLimit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/XRateLimitRemaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/XRateLimitReset"
              }
            }
          }
        },
        "parameters": [
          {
            "$ref": "#/components/parameters/RequestId"
          },
          {
            "$ref": "#/components/parameters/Traceparent"
          },
          {
            "$ref": "#/components/parameters/Tracestate"
          },
          {
            "$ref": "#/components/parameters/AcceptLanguage"
          }
        ],
        "x-codeSamples": [
          {
            "lang": "cURL",
            "label": "cURL",
            "source": "curl -X GET \"https://api.kangopenbanking.com/healthz\" \\\n  -H \"Authorization: Bearer $KOB_ACCESS_TOKEN\" \\\n  -H \"Content-Type: application/json\""
          },
          {
            "lang": "JavaScript",
            "label": "Node.js",
            "source": "import { KangOpenBanking } from \"@kangopenbanking/sdk\";\n\nconst kob = new KangOpenBanking({ apiKey: process.env.KOB_API_KEY });\nconst res = await kob.request(\"GET\", \"/healthz\");\nconsole.log(res);"
          },
          {
            "lang": "Python",
            "label": "Python",
            "source": "from kangopenbanking import KangOpenBanking\n\nkob = KangOpenBanking(api_key=os.environ[\"KOB_API_KEY\"])\nres = kob.request(\"GET\", \"/healthz\")\nprint(res)"
          },
          {
            "lang": "PHP",
            "label": "PHP",
            "source": "<?php\n$kob = new KangOpenBanking\\KangOpenBanking(getenv('KOB_API_KEY'));\n$res = $kob->request('GET', '/healthz');\nprint_r($res);"
          }
        ]
      }
    },
    "/v1/sandbox/events/simulate": {
      "post": {
        "tags": [
          "Sandbox"
        ],
        "summary": "Simulate a sandbox event",
        "description": "Generates a deterministic sandbox event (charge, payment, transfer, settlement) and emits the corresponding webhook to all registered endpoints. Sandbox-only.",
        "operationId": "simulateSandboxEvent",
        "security": [
          {
            "bearerAuth": []
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "required": [
                  "event_type"
                ],
                "properties": {
                  "event_type": {
                    "type": "string",
                    "enum": [
                      "charge.succeeded",
                      "charge.failed",
                      "charge.pending",
                      "charge.refunded",
                      "payment.succeeded",
                      "payment.failed",
                      "transfer.completed",
                      "settlement.paid"
                    ]
                  },
                  "merchant_id": {
                    "type": "string"
                  },
                  "amount": {
                    "type": "string",
                    "pattern": "^[0-9]{1,15}$"
                  },
                  "currency": {
                    "type": "string",
                    "enum": [
                      "XAF",
                      "XOF",
                      "EUR",
                      "USD"
                    ]
                  }
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Event simulated",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/WebhookEvent"
                },
                "example": {
                  "id": "string",
                  "type": "string",
                  "created_at": "2026-01-01T00:00:00Z",
                  "data": {}
                }
              }
            },
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              },
              "traceparent": {
                "$ref": "#/components/headers/Traceparent"
              },
              "Content-Language": {
                "$ref": "#/components/headers/Content-Language"
              },
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/XRateLimitLimit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/XRateLimitRemaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/XRateLimitReset"
              },
              "x-fapi-interaction-id": {
                "$ref": "#/components/headers/XFapiInteractionId"
              }
            }
          },
          "429": {
            "description": "Rate limit exceeded. Retry after the interval in `Retry-After`.",
            "headers": {
              "Retry-After": {
                "schema": {
                  "type": "integer"
                },
                "description": "Seconds to wait before retrying."
              },
              "X-RateLimit-Limit": {
                "schema": {
                  "type": "integer"
                }
              },
              "X-RateLimit-Remaining": {
                "schema": {
                  "type": "integer"
                }
              },
              "X-RateLimit-Reset": {
                "schema": {
                  "type": "integer"
                }
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                },
                "examples": {
                  "rateLimited": {
                    "$ref": "#/components/examples/ErrorRateLimited"
                  }
                }
              }
            }
          },
          "default": {
            "description": "Server error — see ProblemDetails for trace ID.",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            },
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/XRateLimitLimit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/XRateLimitRemaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/XRateLimitReset"
              }
            }
          }
        },
        "parameters": [
          {
            "$ref": "#/components/parameters/RequestId"
          },
          {
            "$ref": "#/components/parameters/Traceparent"
          },
          {
            "$ref": "#/components/parameters/Tracestate"
          },
          {
            "$ref": "#/components/parameters/AcceptLanguage"
          }
        ],
        "x-codeSamples": [
          {
            "lang": "cURL",
            "label": "cURL",
            "source": "curl -X POST \"https://api.kangopenbanking.com/v1/sandbox/events/simulate\" \\\n  -H \"Authorization: Bearer $KOB_ACCESS_TOKEN\" \\\n  -H \"Content-Type: application/json\" \\\n  -d '{}'"
          },
          {
            "lang": "JavaScript",
            "label": "Node.js",
            "source": "import { KangOpenBanking } from \"@kangopenbanking/sdk\";\n\nconst kob = new KangOpenBanking({ apiKey: process.env.KOB_API_KEY });\nconst res = await kob.request(\"POST\", \"/v1/sandbox/events/simulate\", { /* payload */ });\nconsole.log(res);"
          },
          {
            "lang": "Python",
            "label": "Python",
            "source": "from kangopenbanking import KangOpenBanking\n\nkob = KangOpenBanking(api_key=os.environ[\"KOB_API_KEY\"])\nres = kob.request(\"POST\", \"/v1/sandbox/events/simulate\", json={})\nprint(res)"
          },
          {
            "lang": "PHP",
            "label": "PHP",
            "source": "<?php\n$kob = new KangOpenBanking\\KangOpenBanking(getenv('KOB_API_KEY'));\n$res = $kob->request('POST', '/v1/sandbox/events/simulate', []);\nprint_r($res);"
          }
        ]
      }
    },
    "/v1/sandbox/payments/simulate": {
      "post": {
        "tags": [
          "Sandbox"
        ],
        "summary": "Simulate a sandbox payment outcome",
        "description": "Drives a sandbox charge to a target terminal status using deterministic test data (test cards, test mobile-money MSISDNs, test bank accounts).",
        "operationId": "simulateSandboxPayment",
        "security": [
          {
            "bearerAuth": []
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "required": [
                  "channel",
                  "outcome"
                ],
                "properties": {
                  "channel": {
                    "type": "string",
                    "enum": [
                      "mobile_money",
                      "card",
                      "bank_transfer"
                    ]
                  },
                  "outcome": {
                    "type": "string",
                    "enum": [
                      "success",
                      "declined",
                      "insufficient_funds",
                      "timeout",
                      "requires_authentication",
                      "processing_error",
                      "pending"
                    ]
                  },
                  "amount": {
                    "type": "string",
                    "pattern": "^[0-9]{1,15}$"
                  },
                  "currency": {
                    "type": "string"
                  }
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Payment simulated",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                },
                "example": {}
              }
            },
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              },
              "traceparent": {
                "$ref": "#/components/headers/Traceparent"
              },
              "Content-Language": {
                "$ref": "#/components/headers/Content-Language"
              },
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/XRateLimitLimit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/XRateLimitRemaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/XRateLimitReset"
              },
              "x-fapi-interaction-id": {
                "$ref": "#/components/headers/XFapiInteractionId"
              }
            }
          },
          "429": {
            "description": "Rate limit exceeded. Retry after the interval in `Retry-After`.",
            "headers": {
              "Retry-After": {
                "schema": {
                  "type": "integer"
                },
                "description": "Seconds to wait before retrying."
              },
              "X-RateLimit-Limit": {
                "schema": {
                  "type": "integer"
                }
              },
              "X-RateLimit-Remaining": {
                "schema": {
                  "type": "integer"
                }
              },
              "X-RateLimit-Reset": {
                "schema": {
                  "type": "integer"
                }
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                },
                "examples": {
                  "rateLimited": {
                    "$ref": "#/components/examples/ErrorRateLimited"
                  }
                }
              }
            }
          },
          "default": {
            "description": "Server error — see ProblemDetails for trace ID.",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            },
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/XRateLimitLimit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/XRateLimitRemaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/XRateLimitReset"
              }
            }
          }
        },
        "parameters": [
          {
            "$ref": "#/components/parameters/RequestId"
          },
          {
            "$ref": "#/components/parameters/Traceparent"
          },
          {
            "$ref": "#/components/parameters/Tracestate"
          },
          {
            "$ref": "#/components/parameters/AcceptLanguage"
          }
        ],
        "x-codeSamples": [
          {
            "lang": "cURL",
            "label": "cURL",
            "source": "curl -X POST \"https://api.kangopenbanking.com/v1/sandbox/payments/simulate\" \\\n  -H \"Authorization: Bearer $KOB_ACCESS_TOKEN\" \\\n  -H \"Content-Type: application/json\" \\\n  -d '{}'"
          },
          {
            "lang": "JavaScript",
            "label": "Node.js",
            "source": "import { KangOpenBanking } from \"@kangopenbanking/sdk\";\n\nconst kob = new KangOpenBanking({ apiKey: process.env.KOB_API_KEY });\nconst res = await kob.request(\"POST\", \"/v1/sandbox/payments/simulate\", { /* payload */ });\nconsole.log(res);"
          },
          {
            "lang": "Python",
            "label": "Python",
            "source": "from kangopenbanking import KangOpenBanking\n\nkob = KangOpenBanking(api_key=os.environ[\"KOB_API_KEY\"])\nres = kob.request(\"POST\", \"/v1/sandbox/payments/simulate\", json={})\nprint(res)"
          },
          {
            "lang": "PHP",
            "label": "PHP",
            "source": "<?php\n$kob = new KangOpenBanking\\KangOpenBanking(getenv('KOB_API_KEY'));\n$res = $kob->request('POST', '/v1/sandbox/payments/simulate', []);\nprint_r($res);"
          }
        ]
      }
    },
    "/v1/sandbox/webhooks/send-test": {
      "post": {
        "tags": [
          "Sandbox"
        ],
        "summary": "Send a test webhook to a registered endpoint",
        "operationId": "sendTestWebhook",
        "security": [
          {
            "bearerAuth": []
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "required": [
                  "endpoint_id"
                ],
                "properties": {
                  "endpoint_id": {
                    "type": "string"
                  },
                  "event_type": {
                    "type": "string"
                  }
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Test webhook dispatched",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "success": {
                      "type": "boolean",
                      "example": true
                    },
                    "message": {
                      "type": "string"
                    }
                  },
                  "required": [
                    "success"
                  ]
                },
                "example": {
                  "success": true,
                  "message": "string"
                }
              }
            },
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              },
              "traceparent": {
                "$ref": "#/components/headers/Traceparent"
              },
              "Content-Language": {
                "$ref": "#/components/headers/Content-Language"
              },
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/XRateLimitLimit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/XRateLimitRemaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/XRateLimitReset"
              },
              "x-fapi-interaction-id": {
                "$ref": "#/components/headers/XFapiInteractionId"
              }
            }
          },
          "429": {
            "description": "Rate limit exceeded. Retry after the interval in `Retry-After`.",
            "headers": {
              "Retry-After": {
                "schema": {
                  "type": "integer"
                },
                "description": "Seconds to wait before retrying."
              },
              "X-RateLimit-Limit": {
                "schema": {
                  "type": "integer"
                }
              },
              "X-RateLimit-Remaining": {
                "schema": {
                  "type": "integer"
                }
              },
              "X-RateLimit-Reset": {
                "schema": {
                  "type": "integer"
                }
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                },
                "examples": {
                  "rateLimited": {
                    "$ref": "#/components/examples/ErrorRateLimited"
                  }
                }
              }
            }
          },
          "default": {
            "description": "Server error — see ProblemDetails for trace ID.",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            },
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/XRateLimitLimit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/XRateLimitRemaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/XRateLimitReset"
              }
            }
          }
        },
        "parameters": [
          {
            "$ref": "#/components/parameters/RequestId"
          },
          {
            "$ref": "#/components/parameters/Traceparent"
          },
          {
            "$ref": "#/components/parameters/Tracestate"
          },
          {
            "$ref": "#/components/parameters/AcceptLanguage"
          }
        ],
        "x-codeSamples": [
          {
            "lang": "cURL",
            "label": "cURL",
            "source": "curl -X POST \"https://api.kangopenbanking.com/v1/sandbox/webhooks/send-test\" \\\n  -H \"Authorization: Bearer $KOB_ACCESS_TOKEN\" \\\n  -H \"Content-Type: application/json\" \\\n  -d '{}'"
          },
          {
            "lang": "JavaScript",
            "label": "Node.js",
            "source": "import { KangOpenBanking } from \"@kangopenbanking/sdk\";\n\nconst kob = new KangOpenBanking({ apiKey: process.env.KOB_API_KEY });\nconst res = await kob.request(\"POST\", \"/v1/sandbox/webhooks/send-test\", { /* payload */ });\nconsole.log(res);"
          },
          {
            "lang": "Python",
            "label": "Python",
            "source": "from kangopenbanking import KangOpenBanking\n\nkob = KangOpenBanking(api_key=os.environ[\"KOB_API_KEY\"])\nres = kob.request(\"POST\", \"/v1/sandbox/webhooks/send-test\", json={})\nprint(res)"
          },
          {
            "lang": "PHP",
            "label": "PHP",
            "source": "<?php\n$kob = new KangOpenBanking\\KangOpenBanking(getenv('KOB_API_KEY'));\n$res = $kob->request('POST', '/v1/sandbox/webhooks/send-test', []);\nprint_r($res);"
          }
        ]
      }
    },
    "/v1/sandbox/reset": {
      "post": {
        "tags": [
          "Sandbox"
        ],
        "summary": "Reset sandbox data for the calling merchant",
        "description": "Truncates the caller's sandbox charges, payments, and webhook delivery history. Production data is never affected.",
        "operationId": "resetSandbox",
        "security": [
          {
            "bearerAuth": []
          }
        ],
        "responses": {
          "200": {
            "description": "Sandbox reset complete",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "success": {
                      "type": "boolean",
                      "example": true
                    },
                    "message": {
                      "type": "string"
                    }
                  },
                  "required": [
                    "success"
                  ]
                },
                "example": {
                  "success": true,
                  "message": "string"
                }
              }
            },
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              },
              "traceparent": {
                "$ref": "#/components/headers/Traceparent"
              },
              "Content-Language": {
                "$ref": "#/components/headers/Content-Language"
              },
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/XRateLimitLimit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/XRateLimitRemaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/XRateLimitReset"
              },
              "x-fapi-interaction-id": {
                "$ref": "#/components/headers/XFapiInteractionId"
              }
            }
          },
          "429": {
            "description": "Rate limit exceeded. Retry after the interval in `Retry-After`.",
            "headers": {
              "Retry-After": {
                "schema": {
                  "type": "integer"
                },
                "description": "Seconds to wait before retrying."
              },
              "X-RateLimit-Limit": {
                "schema": {
                  "type": "integer"
                }
              },
              "X-RateLimit-Remaining": {
                "schema": {
                  "type": "integer"
                }
              },
              "X-RateLimit-Reset": {
                "schema": {
                  "type": "integer"
                }
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                },
                "examples": {
                  "rateLimited": {
                    "$ref": "#/components/examples/ErrorRateLimited"
                  }
                }
              }
            }
          },
          "default": {
            "description": "Server error — see ProblemDetails for trace ID.",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            },
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/XRateLimitLimit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/XRateLimitRemaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/XRateLimitReset"
              }
            }
          }
        },
        "parameters": [
          {
            "$ref": "#/components/parameters/RequestId"
          },
          {
            "$ref": "#/components/parameters/Traceparent"
          },
          {
            "$ref": "#/components/parameters/Tracestate"
          },
          {
            "$ref": "#/components/parameters/AcceptLanguage"
          }
        ],
        "x-codeSamples": [
          {
            "lang": "cURL",
            "label": "cURL",
            "source": "curl -X POST \"https://api.kangopenbanking.com/v1/sandbox/reset\" \\\n  -H \"Authorization: Bearer $KOB_ACCESS_TOKEN\" \\\n  -H \"Content-Type: application/json\""
          },
          {
            "lang": "JavaScript",
            "label": "Node.js",
            "source": "import { KangOpenBanking } from \"@kangopenbanking/sdk\";\n\nconst kob = new KangOpenBanking({ apiKey: process.env.KOB_API_KEY });\nconst res = await kob.request(\"POST\", \"/v1/sandbox/reset\");\nconsole.log(res);"
          },
          {
            "lang": "Python",
            "label": "Python",
            "source": "from kangopenbanking import KangOpenBanking\n\nkob = KangOpenBanking(api_key=os.environ[\"KOB_API_KEY\"])\nres = kob.request(\"POST\", \"/v1/sandbox/reset\")\nprint(res)"
          },
          {
            "lang": "PHP",
            "label": "PHP",
            "source": "<?php\n$kob = new KangOpenBanking\\KangOpenBanking(getenv('KOB_API_KEY'));\n$res = $kob->request('POST', '/v1/sandbox/reset');\nprint_r($res);"
          }
        ]
      }
    },
    "/v1/payment-intents": {
      "post": {
        "tags": [
          "Payments"
        ],
        "operationId": "createPaymentIntent",
        "summary": "Create a payment intent (async)",
        "description": "Creates a rail-agnostic payment intent. Returns `202 Accepted` immediately. Clients should poll `GET /v1/payment-intents/{id}` or subscribe to `payment_intent.*` webhooks for terminal state.",
        "security": [
          {
            "bearerAuth": []
          }
        ],
        "parameters": [
          {
            "$ref": "#/components/parameters/IdempotencyKey"
          },
          {
            "$ref": "#/components/parameters/Traceparent"
          },
          {
            "$ref": "#/components/parameters/Tracestate"
          },
          {
            "$ref": "#/components/parameters/AcceptLanguage"
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/PaymentIntentCreate"
              }
            }
          }
        },
        "responses": {
          "202": {
            "description": "Payment intent accepted for processing.",
            "headers": {
              "X-Idempotent-Replay": {
                "$ref": "#/components/headers/X-Idempotent-Replay"
              },
              "X-Idempotency-Status": {
                "$ref": "#/components/headers/X-Idempotency-Status"
              },
              "traceparent": {
                "$ref": "#/components/headers/Traceparent"
              },
              "Content-Language": {
                "$ref": "#/components/headers/Content-Language"
              },
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/XRateLimitLimit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/XRateLimitRemaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/XRateLimitReset"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/PaymentIntent"
                },
                "example": {
                  "id": "00000000-0000-4000-8000-000000000000",
                  "amount": "1000.00",
                  "currency": "XAF",
                  "status": "requires_payment_method",
                  "payment_method_types": [
                    "mobile_money"
                  ],
                  "next_action": {
                    "type": "redirect_to_url",
                    "redirect_to_url": {
                      "url": "https://api.kangopenbanking.com",
                      "return_url": "https://api.kangopenbanking.com"
                    },
                    "display_qr": {
                      "qr_payload": "string"
                    },
                    "use_stk_push": {
                      "msisdn": "string",
                      "operator": "string"
                    }
                  },
                  "last_error": {
                    "code": "string",
                    "message": "string"
                  },
                  "description": "string",
                  "metadata": {},
                  "customer_id": "00000000-0000-4000-8000-000000000000",
                  "child_intent_id": "00000000-0000-4000-8000-000000000000",
                  "child_resource": null,
                  "created_at": "2026-01-01T00:00:00Z",
                  "updated_at": "2026-01-01T00:00:00Z",
                  "succeeded_at": "2026-01-01T00:00:00Z",
                  "canceled_at": "2026-01-01T00:00:00Z"
                }
              }
            }
          },
          "400": {
            "description": "Bad Request",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                },
                "examples": {
                  "ProblemDetailsValidation": {
                    "$ref": "#/components/examples/ProblemDetailsValidation"
                  }
                }
              }
            },
            "headers": {
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/XRateLimitLimit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/XRateLimitRemaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/XRateLimitReset"
              }
            }
          },
          "401": {
            "description": "Unauthorized",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                },
                "examples": {
                  "error": {
                    "$ref": "#/components/examples/ErrorUnauthorized"
                  }
                }
              }
            },
            "headers": {
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/XRateLimitLimit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/XRateLimitRemaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/XRateLimitReset"
              }
            }
          },
          "409": {
            "description": "Conflict",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                },
                "examples": {
                  "ProblemDetailsConflict": {
                    "$ref": "#/components/examples/ProblemDetailsConflict"
                  }
                }
              }
            },
            "headers": {
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/XRateLimitLimit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/XRateLimitRemaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/XRateLimitReset"
              }
            }
          },
          "422": {
            "description": "Unprocessable Entity",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                },
                "examples": {
                  "error": {
                    "$ref": "#/components/examples/ErrorUnprocessable"
                  }
                }
              }
            },
            "headers": {
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/XRateLimitLimit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/XRateLimitRemaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/XRateLimitReset"
              }
            }
          },
          "429": {
            "description": "Rate Limited",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                },
                "examples": {
                  "ProblemDetailsRateLimited": {
                    "$ref": "#/components/examples/ProblemDetailsRateLimited"
                  }
                }
              }
            },
            "headers": {
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/XRateLimitLimit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/XRateLimitRemaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/XRateLimitReset"
              },
              "Retry-After": {
                "$ref": "#/components/headers/RetryAfter"
              }
            }
          }
        },
        "x-codeSamples": [
          {
            "lang": "cURL",
            "label": "cURL",
            "source": "curl -X POST \"https://api.kangopenbanking.com/v1/payment-intents\" \\\n  -H \"Authorization: Bearer $KOB_ACCESS_TOKEN\" \\\n  -H \"Content-Type: application/json\" \\\n  -d '{}'"
          },
          {
            "lang": "JavaScript",
            "label": "Node.js",
            "source": "import { KangOpenBanking } from \"@kangopenbanking/sdk\";\n\nconst kob = new KangOpenBanking({ apiKey: process.env.KOB_API_KEY });\nconst res = await kob.request(\"POST\", \"/v1/payment-intents\", { /* payload */ });\nconsole.log(res);"
          },
          {
            "lang": "Python",
            "label": "Python",
            "source": "from kangopenbanking import KangOpenBanking\n\nkob = KangOpenBanking(api_key=os.environ[\"KOB_API_KEY\"])\nres = kob.request(\"POST\", \"/v1/payment-intents\", json={})\nprint(res)"
          },
          {
            "lang": "PHP",
            "label": "PHP",
            "source": "<?php\n$kob = new KangOpenBanking\\KangOpenBanking(getenv('KOB_API_KEY'));\n$res = $kob->request('POST', '/v1/payment-intents', []);\nprint_r($res);"
          }
        ]
      },
      "get": {
        "tags": [
          "Payments"
        ],
        "operationId": "listPaymentIntents",
        "summary": "List payment intents",
        "security": [
          {
            "bearerAuth": []
          }
        ],
        "parameters": [
          {
            "name": "limit",
            "in": "query",
            "schema": {
              "type": "integer",
              "minimum": 1,
              "maximum": 100,
              "default": 25
            }
          },
          {
            "name": "cursor",
            "in": "query",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "status",
            "in": "query",
            "schema": {
              "type": "string",
              "enum": [
                "requires_payment_method",
                "requires_confirmation",
                "processing",
                "requires_action",
                "succeeded",
                "canceled",
                "failed"
              ]
            }
          },
          {
            "$ref": "#/components/parameters/Traceparent"
          },
          {
            "$ref": "#/components/parameters/Tracestate"
          },
          {
            "$ref": "#/components/parameters/AcceptLanguage"
          }
        ],
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/PaymentIntentList"
                },
                "example": {
                  "data": [
                    {
                      "id": "f1d6f4a0-1d4e-4a3a-9e0a-1a2b3c4d5e6f",
                      "amount": "1000",
                      "currency": "XAF",
                      "status": "requires_payment_method",
                      "payment_method_types": [
                        "mobile_money"
                      ],
                      "next_action": {},
                      "last_error": {},
                      "description": "XAF",
                      "metadata": {},
                      "customer_id": "f1d6f4a0-1d4e-4a3a-9e0a-1a2b3c4d5e6f",
                      "child_intent_id": "f1d6f4a0-1d4e-4a3a-9e0a-1a2b3c4d5e6f",
                      "child_resource": null,
                      "created_at": "2026-01-31T12:00:00Z",
                      "updated_at": "2026-01-31T12:00:00Z",
                      "succeeded_at": "2026-01-31T12:00:00Z",
                      "canceled_at": "2026-01-31T12:00:00Z"
                    }
                  ],
                  "has_more": true,
                  "next_cursor": "string"
                }
              }
            },
            "headers": {
              "traceparent": {
                "$ref": "#/components/headers/Traceparent"
              },
              "Content-Language": {
                "$ref": "#/components/headers/Content-Language"
              },
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/XRateLimitLimit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/XRateLimitRemaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/XRateLimitReset"
              },
              "x-fapi-interaction-id": {
                "$ref": "#/components/headers/XFapiInteractionId"
              }
            }
          },
          "400": {
            "description": "Bad Request",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                },
                "examples": {
                  "ProblemDetailsValidation": {
                    "$ref": "#/components/examples/ProblemDetailsValidation"
                  }
                }
              }
            },
            "headers": {
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/XRateLimitLimit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/XRateLimitRemaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/XRateLimitReset"
              }
            }
          },
          "401": {
            "description": "Unauthorized",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                },
                "examples": {
                  "error": {
                    "$ref": "#/components/examples/ErrorUnauthorized"
                  }
                }
              }
            },
            "headers": {
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/XRateLimitLimit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/XRateLimitRemaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/XRateLimitReset"
              }
            }
          },
          "409": {
            "description": "Conflict",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                },
                "examples": {
                  "ProblemDetailsConflict": {
                    "$ref": "#/components/examples/ProblemDetailsConflict"
                  }
                }
              }
            },
            "headers": {
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/XRateLimitLimit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/XRateLimitRemaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/XRateLimitReset"
              }
            }
          },
          "422": {
            "description": "Unprocessable Entity",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                },
                "examples": {
                  "error": {
                    "$ref": "#/components/examples/ErrorUnprocessable"
                  }
                }
              }
            },
            "headers": {
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/XRateLimitLimit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/XRateLimitRemaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/XRateLimitReset"
              }
            }
          },
          "429": {
            "description": "Rate Limited",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                },
                "examples": {
                  "ProblemDetailsRateLimited": {
                    "$ref": "#/components/examples/ProblemDetailsRateLimited"
                  }
                }
              }
            },
            "headers": {
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/XRateLimitLimit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/XRateLimitRemaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/XRateLimitReset"
              },
              "Retry-After": {
                "$ref": "#/components/headers/RetryAfter"
              }
            }
          }
        },
        "x-codeSamples": [
          {
            "lang": "cURL",
            "label": "cURL",
            "source": "curl -X GET \"https://api.kangopenbanking.com/v1/payment-intents\" \\\n  -H \"Authorization: Bearer $KOB_ACCESS_TOKEN\" \\\n  -H \"Content-Type: application/json\""
          },
          {
            "lang": "JavaScript",
            "label": "Node.js",
            "source": "import { KangOpenBanking } from \"@kangopenbanking/sdk\";\n\nconst kob = new KangOpenBanking({ apiKey: process.env.KOB_API_KEY });\nconst res = await kob.request(\"GET\", \"/v1/payment-intents\");\nconsole.log(res);"
          },
          {
            "lang": "Python",
            "label": "Python",
            "source": "from kangopenbanking import KangOpenBanking\n\nkob = KangOpenBanking(api_key=os.environ[\"KOB_API_KEY\"])\nres = kob.request(\"GET\", \"/v1/payment-intents\")\nprint(res)"
          },
          {
            "lang": "PHP",
            "label": "PHP",
            "source": "<?php\n$kob = new KangOpenBanking\\KangOpenBanking(getenv('KOB_API_KEY'));\n$res = $kob->request('GET', '/v1/payment-intents');\nprint_r($res);"
          }
        ]
      }
    },
    "/v1/payment-intents/{id}": {
      "get": {
        "tags": [
          "Payments"
        ],
        "operationId": "getPaymentIntent",
        "summary": "Retrieve a payment intent",
        "security": [
          {
            "bearerAuth": []
          }
        ],
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          },
          {
            "$ref": "#/components/parameters/Traceparent"
          },
          {
            "$ref": "#/components/parameters/Tracestate"
          },
          {
            "$ref": "#/components/parameters/AcceptLanguage"
          }
        ],
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/PaymentIntent"
                },
                "example": {
                  "id": "00000000-0000-4000-8000-000000000000",
                  "amount": "1000.00",
                  "currency": "XAF",
                  "status": "requires_payment_method",
                  "payment_method_types": [
                    "mobile_money"
                  ],
                  "next_action": {
                    "type": "redirect_to_url",
                    "redirect_to_url": {
                      "url": "https://api.kangopenbanking.com",
                      "return_url": "https://api.kangopenbanking.com"
                    },
                    "display_qr": {
                      "qr_payload": "string"
                    },
                    "use_stk_push": {
                      "msisdn": "string",
                      "operator": "string"
                    }
                  },
                  "last_error": {
                    "code": "string",
                    "message": "string"
                  },
                  "description": "string",
                  "metadata": {},
                  "customer_id": "00000000-0000-4000-8000-000000000000",
                  "child_intent_id": "00000000-0000-4000-8000-000000000000",
                  "child_resource": null,
                  "created_at": "2026-01-01T00:00:00Z",
                  "updated_at": "2026-01-01T00:00:00Z",
                  "succeeded_at": "2026-01-01T00:00:00Z",
                  "canceled_at": "2026-01-01T00:00:00Z"
                }
              }
            },
            "headers": {
              "traceparent": {
                "$ref": "#/components/headers/Traceparent"
              },
              "Content-Language": {
                "$ref": "#/components/headers/Content-Language"
              },
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/XRateLimitLimit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/XRateLimitRemaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/XRateLimitReset"
              },
              "x-fapi-interaction-id": {
                "$ref": "#/components/headers/XFapiInteractionId"
              }
            }
          },
          "400": {
            "description": "Bad Request",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                },
                "examples": {
                  "ProblemDetailsValidation": {
                    "$ref": "#/components/examples/ProblemDetailsValidation"
                  }
                }
              }
            },
            "headers": {
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/XRateLimitLimit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/XRateLimitRemaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/XRateLimitReset"
              }
            }
          },
          "401": {
            "description": "Unauthorized",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                },
                "examples": {
                  "error": {
                    "$ref": "#/components/examples/ErrorUnauthorized"
                  }
                }
              }
            },
            "headers": {
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/XRateLimitLimit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/XRateLimitRemaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/XRateLimitReset"
              }
            }
          },
          "404": {
            "description": "Not Found",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                },
                "examples": {
                  "error": {
                    "$ref": "#/components/examples/ErrorNotFound"
                  }
                }
              }
            },
            "headers": {
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/XRateLimitLimit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/XRateLimitRemaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/XRateLimitReset"
              }
            }
          },
          "409": {
            "description": "Conflict",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                },
                "examples": {
                  "ProblemDetailsConflict": {
                    "$ref": "#/components/examples/ProblemDetailsConflict"
                  }
                }
              }
            },
            "headers": {
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/XRateLimitLimit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/XRateLimitRemaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/XRateLimitReset"
              }
            }
          },
          "422": {
            "description": "Unprocessable Entity",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                },
                "examples": {
                  "error": {
                    "$ref": "#/components/examples/ErrorUnprocessable"
                  }
                }
              }
            },
            "headers": {
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/XRateLimitLimit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/XRateLimitRemaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/XRateLimitReset"
              }
            }
          },
          "429": {
            "description": "Rate Limited",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                },
                "examples": {
                  "ProblemDetailsRateLimited": {
                    "$ref": "#/components/examples/ProblemDetailsRateLimited"
                  }
                }
              }
            },
            "headers": {
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/XRateLimitLimit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/XRateLimitRemaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/XRateLimitReset"
              },
              "Retry-After": {
                "$ref": "#/components/headers/RetryAfter"
              }
            }
          }
        },
        "x-codeSamples": [
          {
            "lang": "cURL",
            "label": "cURL",
            "source": "curl -X GET \"https://api.kangopenbanking.com/v1/payment-intents/{id}\" \\\n  -H \"Authorization: Bearer $KOB_ACCESS_TOKEN\" \\\n  -H \"Content-Type: application/json\""
          },
          {
            "lang": "JavaScript",
            "label": "Node.js",
            "source": "import { KangOpenBanking } from \"@kangopenbanking/sdk\";\n\nconst kob = new KangOpenBanking({ apiKey: process.env.KOB_API_KEY });\nconst res = await kob.request(\"GET\", \"/v1/payment-intents/{id}\");\nconsole.log(res);"
          },
          {
            "lang": "Python",
            "label": "Python",
            "source": "from kangopenbanking import KangOpenBanking\n\nkob = KangOpenBanking(api_key=os.environ[\"KOB_API_KEY\"])\nres = kob.request(\"GET\", \"/v1/payment-intents/{id}\")\nprint(res)"
          },
          {
            "lang": "PHP",
            "label": "PHP",
            "source": "<?php\n$kob = new KangOpenBanking\\KangOpenBanking(getenv('KOB_API_KEY'));\n$res = $kob->request('GET', '/v1/payment-intents/{id}');\nprint_r($res);"
          }
        ]
      }
    },
    "/v1/payment-intents/{id}/confirm": {
      "post": {
        "tags": [
          "Payments"
        ],
        "operationId": "confirmPaymentIntent",
        "summary": "Confirm a payment intent",
        "description": "Transitions a `requires_confirmation` intent to `processing`. Idempotent.",
        "security": [
          {
            "bearerAuth": []
          }
        ],
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          },
          {
            "$ref": "#/components/parameters/IdempotencyKey"
          },
          {
            "$ref": "#/components/parameters/Traceparent"
          },
          {
            "$ref": "#/components/parameters/Tracestate"
          },
          {
            "$ref": "#/components/parameters/AcceptLanguage"
          }
        ],
        "requestBody": {
          "required": false,
          "content": {
            "application/json": {
              "schema": {
                "type": "object"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "OK",
            "headers": {
              "X-Idempotent-Replay": {
                "$ref": "#/components/headers/X-Idempotent-Replay"
              },
              "X-Idempotency-Status": {
                "$ref": "#/components/headers/X-Idempotency-Status"
              },
              "traceparent": {
                "$ref": "#/components/headers/Traceparent"
              },
              "Content-Language": {
                "$ref": "#/components/headers/Content-Language"
              },
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/XRateLimitLimit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/XRateLimitRemaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/XRateLimitReset"
              },
              "x-fapi-interaction-id": {
                "$ref": "#/components/headers/XFapiInteractionId"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/PaymentIntent"
                },
                "example": {
                  "id": "00000000-0000-4000-8000-000000000000",
                  "amount": "1000.00",
                  "currency": "XAF",
                  "status": "requires_payment_method",
                  "payment_method_types": [
                    "mobile_money"
                  ],
                  "next_action": {
                    "type": "redirect_to_url",
                    "redirect_to_url": {
                      "url": "https://api.kangopenbanking.com",
                      "return_url": "https://api.kangopenbanking.com"
                    },
                    "display_qr": {
                      "qr_payload": "string"
                    },
                    "use_stk_push": {
                      "msisdn": "string",
                      "operator": "string"
                    }
                  },
                  "last_error": {
                    "code": "string",
                    "message": "string"
                  },
                  "description": "string",
                  "metadata": {},
                  "customer_id": "00000000-0000-4000-8000-000000000000",
                  "child_intent_id": "00000000-0000-4000-8000-000000000000",
                  "child_resource": null,
                  "created_at": "2026-01-01T00:00:00Z",
                  "updated_at": "2026-01-01T00:00:00Z",
                  "succeeded_at": "2026-01-01T00:00:00Z",
                  "canceled_at": "2026-01-01T00:00:00Z"
                }
              }
            }
          },
          "400": {
            "description": "Bad Request",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                },
                "examples": {
                  "ProblemDetailsValidation": {
                    "$ref": "#/components/examples/ProblemDetailsValidation"
                  }
                }
              }
            },
            "headers": {
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/XRateLimitLimit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/XRateLimitRemaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/XRateLimitReset"
              }
            }
          },
          "401": {
            "description": "Unauthorized",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                },
                "examples": {
                  "error": {
                    "$ref": "#/components/examples/ErrorUnauthorized"
                  }
                }
              }
            },
            "headers": {
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/XRateLimitLimit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/XRateLimitRemaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/XRateLimitReset"
              }
            }
          },
          "409": {
            "description": "Conflict",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                },
                "examples": {
                  "ProblemDetailsConflict": {
                    "$ref": "#/components/examples/ProblemDetailsConflict"
                  }
                }
              }
            },
            "headers": {
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/XRateLimitLimit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/XRateLimitRemaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/XRateLimitReset"
              }
            }
          },
          "422": {
            "description": "Unprocessable Entity",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                },
                "examples": {
                  "error": {
                    "$ref": "#/components/examples/ErrorUnprocessable"
                  }
                }
              }
            },
            "headers": {
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/XRateLimitLimit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/XRateLimitRemaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/XRateLimitReset"
              }
            }
          },
          "429": {
            "description": "Rate Limited",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                },
                "examples": {
                  "ProblemDetailsRateLimited": {
                    "$ref": "#/components/examples/ProblemDetailsRateLimited"
                  }
                }
              }
            },
            "headers": {
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/XRateLimitLimit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/XRateLimitRemaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/XRateLimitReset"
              },
              "Retry-After": {
                "$ref": "#/components/headers/RetryAfter"
              }
            }
          }
        },
        "x-codeSamples": [
          {
            "lang": "cURL",
            "label": "cURL",
            "source": "curl -X POST \"https://api.kangopenbanking.com/v1/payment-intents/{id}/confirm\" \\\n  -H \"Authorization: Bearer $KOB_ACCESS_TOKEN\" \\\n  -H \"Content-Type: application/json\" \\\n  -d '{}'"
          },
          {
            "lang": "JavaScript",
            "label": "Node.js",
            "source": "import { KangOpenBanking } from \"@kangopenbanking/sdk\";\n\nconst kob = new KangOpenBanking({ apiKey: process.env.KOB_API_KEY });\nconst res = await kob.request(\"POST\", \"/v1/payment-intents/{id}/confirm\", { /* payload */ });\nconsole.log(res);"
          },
          {
            "lang": "Python",
            "label": "Python",
            "source": "from kangopenbanking import KangOpenBanking\n\nkob = KangOpenBanking(api_key=os.environ[\"KOB_API_KEY\"])\nres = kob.request(\"POST\", \"/v1/payment-intents/{id}/confirm\", json={})\nprint(res)"
          },
          {
            "lang": "PHP",
            "label": "PHP",
            "source": "<?php\n$kob = new KangOpenBanking\\KangOpenBanking(getenv('KOB_API_KEY'));\n$res = $kob->request('POST', '/v1/payment-intents/{id}/confirm', []);\nprint_r($res);"
          }
        ]
      }
    },
    "/v1/payment-intents/{id}/cancel": {
      "post": {
        "tags": [
          "Payments"
        ],
        "operationId": "cancelPaymentIntent",
        "summary": "Cancel a payment intent",
        "security": [
          {
            "bearerAuth": []
          }
        ],
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          },
          {
            "$ref": "#/components/parameters/IdempotencyKey"
          },
          {
            "$ref": "#/components/parameters/Traceparent"
          },
          {
            "$ref": "#/components/parameters/Tracestate"
          },
          {
            "$ref": "#/components/parameters/AcceptLanguage"
          }
        ],
        "responses": {
          "200": {
            "description": "OK",
            "headers": {
              "X-Idempotent-Replay": {
                "$ref": "#/components/headers/X-Idempotent-Replay"
              },
              "X-Idempotency-Status": {
                "$ref": "#/components/headers/X-Idempotency-Status"
              },
              "traceparent": {
                "$ref": "#/components/headers/Traceparent"
              },
              "Content-Language": {
                "$ref": "#/components/headers/Content-Language"
              },
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/XRateLimitLimit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/XRateLimitRemaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/XRateLimitReset"
              },
              "x-fapi-interaction-id": {
                "$ref": "#/components/headers/XFapiInteractionId"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/PaymentIntent"
                },
                "example": {
                  "id": "00000000-0000-4000-8000-000000000000",
                  "amount": "1000.00",
                  "currency": "XAF",
                  "status": "requires_payment_method",
                  "payment_method_types": [
                    "mobile_money"
                  ],
                  "next_action": {
                    "type": "redirect_to_url",
                    "redirect_to_url": {
                      "url": "https://api.kangopenbanking.com",
                      "return_url": "https://api.kangopenbanking.com"
                    },
                    "display_qr": {
                      "qr_payload": "string"
                    },
                    "use_stk_push": {
                      "msisdn": "string",
                      "operator": "string"
                    }
                  },
                  "last_error": {
                    "code": "string",
                    "message": "string"
                  },
                  "description": "string",
                  "metadata": {},
                  "customer_id": "00000000-0000-4000-8000-000000000000",
                  "child_intent_id": "00000000-0000-4000-8000-000000000000",
                  "child_resource": null,
                  "created_at": "2026-01-01T00:00:00Z",
                  "updated_at": "2026-01-01T00:00:00Z",
                  "succeeded_at": "2026-01-01T00:00:00Z",
                  "canceled_at": "2026-01-01T00:00:00Z"
                }
              }
            }
          },
          "400": {
            "description": "Bad Request",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                },
                "examples": {
                  "ProblemDetailsValidation": {
                    "$ref": "#/components/examples/ProblemDetailsValidation"
                  }
                }
              }
            },
            "headers": {
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/XRateLimitLimit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/XRateLimitRemaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/XRateLimitReset"
              }
            }
          },
          "401": {
            "description": "Unauthorized",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                },
                "examples": {
                  "error": {
                    "$ref": "#/components/examples/ErrorUnauthorized"
                  }
                }
              }
            },
            "headers": {
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/XRateLimitLimit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/XRateLimitRemaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/XRateLimitReset"
              }
            }
          },
          "409": {
            "description": "Conflict",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                },
                "examples": {
                  "ProblemDetailsConflict": {
                    "$ref": "#/components/examples/ProblemDetailsConflict"
                  }
                }
              }
            },
            "headers": {
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/XRateLimitLimit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/XRateLimitRemaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/XRateLimitReset"
              }
            }
          },
          "422": {
            "description": "Unprocessable Entity",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                },
                "examples": {
                  "error": {
                    "$ref": "#/components/examples/ErrorUnprocessable"
                  }
                }
              }
            },
            "headers": {
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/XRateLimitLimit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/XRateLimitRemaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/XRateLimitReset"
              }
            }
          },
          "429": {
            "description": "Rate Limited",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                },
                "examples": {
                  "ProblemDetailsRateLimited": {
                    "$ref": "#/components/examples/ProblemDetailsRateLimited"
                  }
                }
              }
            },
            "headers": {
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/XRateLimitLimit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/XRateLimitRemaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/XRateLimitReset"
              },
              "Retry-After": {
                "$ref": "#/components/headers/RetryAfter"
              }
            }
          }
        },
        "x-codeSamples": [
          {
            "lang": "cURL",
            "label": "cURL",
            "source": "curl -X POST \"https://api.kangopenbanking.com/v1/payment-intents/{id}/cancel\" \\\n  -H \"Authorization: Bearer $KOB_ACCESS_TOKEN\" \\\n  -H \"Content-Type: application/json\""
          },
          {
            "lang": "JavaScript",
            "label": "Node.js",
            "source": "import { KangOpenBanking } from \"@kangopenbanking/sdk\";\n\nconst kob = new KangOpenBanking({ apiKey: process.env.KOB_API_KEY });\nconst res = await kob.request(\"POST\", \"/v1/payment-intents/{id}/cancel\");\nconsole.log(res);"
          },
          {
            "lang": "Python",
            "label": "Python",
            "source": "from kangopenbanking import KangOpenBanking\n\nkob = KangOpenBanking(api_key=os.environ[\"KOB_API_KEY\"])\nres = kob.request(\"POST\", \"/v1/payment-intents/{id}/cancel\")\nprint(res)"
          },
          {
            "lang": "PHP",
            "label": "PHP",
            "source": "<?php\n$kob = new KangOpenBanking\\KangOpenBanking(getenv('KOB_API_KEY'));\n$res = $kob->request('POST', '/v1/payment-intents/{id}/cancel');\nprint_r($res);"
          }
        ]
      }
    },
    "/v1/webhooks/events/{eventId}/replay": {
      "post": {
        "tags": [
          "Webhooks"
        ],
        "operationId": "replayWebhookEvent",
        "summary": "Replay a webhook event (canonical façade)",
        "description": "Manually redeliver a webhook event by event_id. Looks up the originating endpoint and delivery, then re-queues. Convenience wrapper over `/v1/webhooks/v2/endpoints/{endpointId}/deliveries/{deliveryId}/replay`.",
        "security": [
          {
            "bearerAuth": []
          }
        ],
        "parameters": [
          {
            "name": "eventId",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          },
          {
            "$ref": "#/components/parameters/IdempotencyKey"
          },
          {
            "$ref": "#/components/parameters/Traceparent"
          },
          {
            "$ref": "#/components/parameters/Tracestate"
          },
          {
            "$ref": "#/components/parameters/AcceptLanguage"
          }
        ],
        "responses": {
          "202": {
            "description": "Event re-queued for delivery.",
            "headers": {
              "X-Idempotent-Replay": {
                "$ref": "#/components/headers/X-Idempotent-Replay"
              },
              "X-Idempotency-Status": {
                "$ref": "#/components/headers/X-Idempotency-Status"
              },
              "traceparent": {
                "$ref": "#/components/headers/Traceparent"
              },
              "Content-Language": {
                "$ref": "#/components/headers/Content-Language"
              },
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/XRateLimitLimit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/XRateLimitRemaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/XRateLimitReset"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "delivery_id": {
                      "type": "string",
                      "format": "uuid"
                    },
                    "status": {
                      "type": "string"
                    }
                  }
                },
                "example": {
                  "delivery_id": "00000000-0000-4000-8000-000000000000",
                  "status": "string"
                }
              }
            }
          },
          "400": {
            "description": "Bad Request",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                },
                "examples": {
                  "ProblemDetailsValidation": {
                    "$ref": "#/components/examples/ProblemDetailsValidation"
                  }
                }
              }
            },
            "headers": {
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/XRateLimitLimit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/XRateLimitRemaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/XRateLimitReset"
              }
            }
          },
          "401": {
            "description": "Unauthorized",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                },
                "examples": {
                  "error": {
                    "$ref": "#/components/examples/ErrorUnauthorized"
                  }
                }
              }
            },
            "headers": {
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/XRateLimitLimit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/XRateLimitRemaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/XRateLimitReset"
              }
            }
          },
          "404": {
            "description": "Event not found",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                },
                "examples": {
                  "error": {
                    "$ref": "#/components/examples/ErrorNotFound"
                  }
                }
              }
            },
            "headers": {
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/XRateLimitLimit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/XRateLimitRemaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/XRateLimitReset"
              }
            }
          },
          "409": {
            "description": "Conflict",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                },
                "examples": {
                  "ProblemDetailsConflict": {
                    "$ref": "#/components/examples/ProblemDetailsConflict"
                  }
                }
              }
            },
            "headers": {
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/XRateLimitLimit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/XRateLimitRemaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/XRateLimitReset"
              }
            }
          },
          "422": {
            "description": "Unprocessable Entity",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                },
                "examples": {
                  "error": {
                    "$ref": "#/components/examples/ErrorUnprocessable"
                  }
                }
              }
            },
            "headers": {
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/XRateLimitLimit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/XRateLimitRemaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/XRateLimitReset"
              }
            }
          },
          "429": {
            "description": "Rate Limited",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                },
                "examples": {
                  "ProblemDetailsRateLimited": {
                    "$ref": "#/components/examples/ProblemDetailsRateLimited"
                  }
                }
              }
            },
            "headers": {
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/XRateLimitLimit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/XRateLimitRemaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/XRateLimitReset"
              },
              "Retry-After": {
                "$ref": "#/components/headers/RetryAfter"
              }
            }
          }
        },
        "x-codeSamples": [
          {
            "lang": "cURL",
            "label": "cURL",
            "source": "curl -X POST \"https://api.kangopenbanking.com/v1/webhooks/events/{eventId}/replay\" \\\n  -H \"Authorization: Bearer $KOB_ACCESS_TOKEN\" \\\n  -H \"Content-Type: application/json\""
          },
          {
            "lang": "JavaScript",
            "label": "Node.js",
            "source": "import { KangOpenBanking } from \"@kangopenbanking/sdk\";\n\nconst kob = new KangOpenBanking({ apiKey: process.env.KOB_API_KEY });\nconst res = await kob.request(\"POST\", \"/v1/webhooks/events/{eventId}/replay\");\nconsole.log(res);"
          },
          {
            "lang": "Python",
            "label": "Python",
            "source": "from kangopenbanking import KangOpenBanking\n\nkob = KangOpenBanking(api_key=os.environ[\"KOB_API_KEY\"])\nres = kob.request(\"POST\", \"/v1/webhooks/events/{eventId}/replay\")\nprint(res)"
          },
          {
            "lang": "PHP",
            "label": "PHP",
            "source": "<?php\n$kob = new KangOpenBanking\\KangOpenBanking(getenv('KOB_API_KEY'));\n$res = $kob->request('POST', '/v1/webhooks/events/{eventId}/replay');\nprint_r($res);"
          }
        ]
      }
    },
    "/v1/webhooks/dlq": {
      "get": {
        "tags": [
          "Webhooks"
        ],
        "operationId": "listWebhookDlq",
        "summary": "List dead-letter webhook deliveries",
        "description": "Returns deliveries that exhausted the 7-attempt retry schedule.",
        "security": [
          {
            "bearerAuth": []
          }
        ],
        "parameters": [
          {
            "name": "limit",
            "in": "query",
            "schema": {
              "type": "integer",
              "minimum": 1,
              "maximum": 100,
              "default": 25
            }
          },
          {
            "name": "cursor",
            "in": "query",
            "schema": {
              "type": "string"
            }
          },
          {
            "$ref": "#/components/parameters/Traceparent"
          },
          {
            "$ref": "#/components/parameters/Tracestate"
          },
          {
            "$ref": "#/components/parameters/AcceptLanguage"
          }
        ],
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "allOf": [
                    {
                      "$ref": "#/components/schemas/PaginatedResponse"
                    },
                    {
                      "type": "object",
                      "properties": {
                        "data": {
                          "type": "array",
                          "items": {
                            "type": "object"
                          }
                        }
                      }
                    }
                  ]
                },
                "example": {
                  "data": [
                    {}
                  ],
                  "pagination": {
                    "page": 1,
                    "limit": 20,
                    "total": 150,
                    "has_next": true,
                    "next_cursor": "eyJpZCI6IjEyMyJ9"
                  },
                  "meta": {
                    "request_id": "550e8400-e29b-41d4-a716-446655440000",
                    "timestamp": "2025-03-27T12:00:00Z",
                    "api_version": "4.3.0"
                  }
                }
              }
            },
            "headers": {
              "traceparent": {
                "$ref": "#/components/headers/Traceparent"
              },
              "Content-Language": {
                "$ref": "#/components/headers/Content-Language"
              },
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/XRateLimitLimit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/XRateLimitRemaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/XRateLimitReset"
              },
              "x-fapi-interaction-id": {
                "$ref": "#/components/headers/XFapiInteractionId"
              }
            }
          },
          "400": {
            "description": "Bad Request",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                },
                "examples": {
                  "ProblemDetailsValidation": {
                    "$ref": "#/components/examples/ProblemDetailsValidation"
                  }
                }
              }
            },
            "headers": {
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/XRateLimitLimit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/XRateLimitRemaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/XRateLimitReset"
              }
            }
          },
          "401": {
            "description": "Unauthorized",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                },
                "examples": {
                  "error": {
                    "$ref": "#/components/examples/ErrorUnauthorized"
                  }
                }
              }
            },
            "headers": {
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/XRateLimitLimit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/XRateLimitRemaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/XRateLimitReset"
              }
            }
          },
          "409": {
            "description": "Conflict",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                },
                "examples": {
                  "ProblemDetailsConflict": {
                    "$ref": "#/components/examples/ProblemDetailsConflict"
                  }
                }
              }
            },
            "headers": {
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/XRateLimitLimit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/XRateLimitRemaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/XRateLimitReset"
              }
            }
          },
          "422": {
            "description": "Unprocessable Entity",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                },
                "examples": {
                  "error": {
                    "$ref": "#/components/examples/ErrorUnprocessable"
                  }
                }
              }
            },
            "headers": {
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/XRateLimitLimit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/XRateLimitRemaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/XRateLimitReset"
              }
            }
          },
          "429": {
            "description": "Rate Limited",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                },
                "examples": {
                  "ProblemDetailsRateLimited": {
                    "$ref": "#/components/examples/ProblemDetailsRateLimited"
                  }
                }
              }
            },
            "headers": {
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/XRateLimitLimit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/XRateLimitRemaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/XRateLimitReset"
              },
              "Retry-After": {
                "$ref": "#/components/headers/RetryAfter"
              }
            }
          }
        },
        "x-codeSamples": [
          {
            "lang": "cURL",
            "label": "cURL",
            "source": "curl -X GET \"https://api.kangopenbanking.com/v1/webhooks/dlq\" \\\n  -H \"Authorization: Bearer $KOB_ACCESS_TOKEN\" \\\n  -H \"Content-Type: application/json\""
          },
          {
            "lang": "JavaScript",
            "label": "Node.js",
            "source": "import { KangOpenBanking } from \"@kangopenbanking/sdk\";\n\nconst kob = new KangOpenBanking({ apiKey: process.env.KOB_API_KEY });\nconst res = await kob.request(\"GET\", \"/v1/webhooks/dlq\");\nconsole.log(res);"
          },
          {
            "lang": "Python",
            "label": "Python",
            "source": "from kangopenbanking import KangOpenBanking\n\nkob = KangOpenBanking(api_key=os.environ[\"KOB_API_KEY\"])\nres = kob.request(\"GET\", \"/v1/webhooks/dlq\")\nprint(res)"
          },
          {
            "lang": "PHP",
            "label": "PHP",
            "source": "<?php\n$kob = new KangOpenBanking\\KangOpenBanking(getenv('KOB_API_KEY'));\n$res = $kob->request('GET', '/v1/webhooks/dlq');\nprint_r($res);"
          }
        ]
      }
    },
    "/v1/webhooks/dlq/{deliveryId}/requeue": {
      "post": {
        "tags": [
          "Webhooks"
        ],
        "operationId": "requeueWebhookDlq",
        "summary": "Requeue a dead-letter webhook delivery",
        "security": [
          {
            "bearerAuth": []
          }
        ],
        "parameters": [
          {
            "name": "deliveryId",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          },
          {
            "$ref": "#/components/parameters/IdempotencyKey"
          },
          {
            "$ref": "#/components/parameters/Traceparent"
          },
          {
            "$ref": "#/components/parameters/Tracestate"
          },
          {
            "$ref": "#/components/parameters/AcceptLanguage"
          }
        ],
        "responses": {
          "202": {
            "description": "Delivery requeued.",
            "headers": {
              "X-Idempotent-Replay": {
                "$ref": "#/components/headers/X-Idempotent-Replay"
              },
              "X-Idempotency-Status": {
                "$ref": "#/components/headers/X-Idempotency-Status"
              },
              "traceparent": {
                "$ref": "#/components/headers/Traceparent"
              },
              "Content-Language": {
                "$ref": "#/components/headers/Content-Language"
              },
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/XRateLimitLimit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/XRateLimitRemaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/XRateLimitReset"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                },
                "example": {}
              }
            }
          },
          "400": {
            "description": "Bad Request",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                },
                "examples": {
                  "ProblemDetailsValidation": {
                    "$ref": "#/components/examples/ProblemDetailsValidation"
                  }
                }
              }
            },
            "headers": {
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/XRateLimitLimit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/XRateLimitRemaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/XRateLimitReset"
              }
            }
          },
          "401": {
            "description": "Unauthorized",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                },
                "examples": {
                  "error": {
                    "$ref": "#/components/examples/ErrorUnauthorized"
                  }
                }
              }
            },
            "headers": {
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/XRateLimitLimit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/XRateLimitRemaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/XRateLimitReset"
              }
            }
          },
          "409": {
            "description": "Conflict",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                },
                "examples": {
                  "ProblemDetailsConflict": {
                    "$ref": "#/components/examples/ProblemDetailsConflict"
                  }
                }
              }
            },
            "headers": {
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/XRateLimitLimit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/XRateLimitRemaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/XRateLimitReset"
              }
            }
          },
          "422": {
            "description": "Unprocessable Entity",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                },
                "examples": {
                  "error": {
                    "$ref": "#/components/examples/ErrorUnprocessable"
                  }
                }
              }
            },
            "headers": {
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/XRateLimitLimit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/XRateLimitRemaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/XRateLimitReset"
              }
            }
          },
          "429": {
            "description": "Rate Limited",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                },
                "examples": {
                  "ProblemDetailsRateLimited": {
                    "$ref": "#/components/examples/ProblemDetailsRateLimited"
                  }
                }
              }
            },
            "headers": {
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/XRateLimitLimit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/XRateLimitRemaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/XRateLimitReset"
              },
              "Retry-After": {
                "$ref": "#/components/headers/RetryAfter"
              }
            }
          }
        },
        "x-codeSamples": [
          {
            "lang": "cURL",
            "label": "cURL",
            "source": "curl -X POST \"https://api.kangopenbanking.com/v1/webhooks/dlq/{deliveryId}/requeue\" \\\n  -H \"Authorization: Bearer $KOB_ACCESS_TOKEN\" \\\n  -H \"Content-Type: application/json\""
          },
          {
            "lang": "JavaScript",
            "label": "Node.js",
            "source": "import { KangOpenBanking } from \"@kangopenbanking/sdk\";\n\nconst kob = new KangOpenBanking({ apiKey: process.env.KOB_API_KEY });\nconst res = await kob.request(\"POST\", \"/v1/webhooks/dlq/{deliveryId}/requeue\");\nconsole.log(res);"
          },
          {
            "lang": "Python",
            "label": "Python",
            "source": "from kangopenbanking import KangOpenBanking\n\nkob = KangOpenBanking(api_key=os.environ[\"KOB_API_KEY\"])\nres = kob.request(\"POST\", \"/v1/webhooks/dlq/{deliveryId}/requeue\")\nprint(res)"
          },
          {
            "lang": "PHP",
            "label": "PHP",
            "source": "<?php\n$kob = new KangOpenBanking\\KangOpenBanking(getenv('KOB_API_KEY'));\n$res = $kob->request('POST', '/v1/webhooks/dlq/{deliveryId}/requeue');\nprint_r($res);"
          }
        ]
      }
    },
    "/v1/sandbox/trigger": {
      "post": {
        "tags": [
          "Sandbox"
        ],
        "operationId": "triggerSandboxFault",
        "summary": "Trigger a sandbox fault-injection event",
        "description": "Forces a specific failure mode on the next matching operation. Auth-scoped to the developer's sandbox.",
        "security": [
          {
            "bearerAuth": []
          }
        ],
        "parameters": [
          {
            "$ref": "#/components/parameters/IdempotencyKey"
          },
          {
            "$ref": "#/components/parameters/Traceparent"
          },
          {
            "$ref": "#/components/parameters/Tracestate"
          },
          {
            "$ref": "#/components/parameters/AcceptLanguage"
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "required": [
                  "event"
                ],
                "properties": {
                  "event": {
                    "type": "string",
                    "enum": [
                      "bank_timeout",
                      "network_unreachable",
                      "insufficient_funds",
                      "operator_unavailable",
                      "customer_not_registered",
                      "daily_limit_exceeded",
                      "rate_limited_429",
                      "provider_504"
                    ]
                  },
                  "target_id": {
                    "type": "string",
                    "description": "Optional charge/intent ID to target."
                  },
                  "delay_ms": {
                    "type": "integer",
                    "minimum": 0,
                    "maximum": 60000,
                    "default": 0
                  }
                }
              }
            }
          }
        },
        "responses": {
          "202": {
            "description": "Fault armed for next matching call.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "trigger_id": {
                      "type": "string",
                      "format": "uuid"
                    }
                  }
                },
                "example": {
                  "trigger_id": "00000000-0000-4000-8000-000000000000"
                }
              }
            },
            "headers": {
              "traceparent": {
                "$ref": "#/components/headers/Traceparent"
              },
              "Content-Language": {
                "$ref": "#/components/headers/Content-Language"
              },
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/XRateLimitLimit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/XRateLimitRemaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/XRateLimitReset"
              }
            }
          },
          "400": {
            "description": "Bad Request",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                },
                "examples": {
                  "ProblemDetailsValidation": {
                    "$ref": "#/components/examples/ProblemDetailsValidation"
                  }
                }
              }
            },
            "headers": {
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/XRateLimitLimit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/XRateLimitRemaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/XRateLimitReset"
              }
            }
          },
          "401": {
            "description": "Unauthorized",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                },
                "examples": {
                  "error": {
                    "$ref": "#/components/examples/ErrorUnauthorized"
                  }
                }
              }
            },
            "headers": {
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/XRateLimitLimit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/XRateLimitRemaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/XRateLimitReset"
              }
            }
          },
          "409": {
            "description": "Conflict",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                },
                "examples": {
                  "ProblemDetailsConflict": {
                    "$ref": "#/components/examples/ProblemDetailsConflict"
                  }
                }
              }
            },
            "headers": {
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/XRateLimitLimit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/XRateLimitRemaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/XRateLimitReset"
              }
            }
          },
          "422": {
            "description": "Unprocessable Entity",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                },
                "examples": {
                  "error": {
                    "$ref": "#/components/examples/ErrorUnprocessable"
                  }
                }
              }
            },
            "headers": {
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/XRateLimitLimit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/XRateLimitRemaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/XRateLimitReset"
              }
            }
          },
          "429": {
            "description": "Rate Limited",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                },
                "examples": {
                  "ProblemDetailsRateLimited": {
                    "$ref": "#/components/examples/ProblemDetailsRateLimited"
                  }
                }
              }
            },
            "headers": {
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/XRateLimitLimit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/XRateLimitRemaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/XRateLimitReset"
              },
              "Retry-After": {
                "$ref": "#/components/headers/RetryAfter"
              }
            }
          }
        },
        "x-codeSamples": [
          {
            "lang": "cURL",
            "label": "cURL",
            "source": "curl -X POST \"https://api.kangopenbanking.com/v1/sandbox/trigger\" \\\n  -H \"Authorization: Bearer $KOB_ACCESS_TOKEN\" \\\n  -H \"Content-Type: application/json\" \\\n  -d '{}'"
          },
          {
            "lang": "JavaScript",
            "label": "Node.js",
            "source": "import { KangOpenBanking } from \"@kangopenbanking/sdk\";\n\nconst kob = new KangOpenBanking({ apiKey: process.env.KOB_API_KEY });\nconst res = await kob.request(\"POST\", \"/v1/sandbox/trigger\", { /* payload */ });\nconsole.log(res);"
          },
          {
            "lang": "Python",
            "label": "Python",
            "source": "from kangopenbanking import KangOpenBanking\n\nkob = KangOpenBanking(api_key=os.environ[\"KOB_API_KEY\"])\nres = kob.request(\"POST\", \"/v1/sandbox/trigger\", json={})\nprint(res)"
          },
          {
            "lang": "PHP",
            "label": "PHP",
            "source": "<?php\n$kob = new KangOpenBanking\\KangOpenBanking(getenv('KOB_API_KEY'));\n$res = $kob->request('POST', '/v1/sandbox/trigger', []);\nprint_r($res);"
          }
        ]
      }
    },
    "/v1/sandbox/charges/{chargeId}/simulate": {
      "post": {
        "tags": [
          "Sandbox"
        ],
        "operationId": "simulateSandboxChargeOutcome",
        "summary": "Simulate an outcome on a sandbox charge",
        "description": "Charge-scoped façade over `/v1/sandbox/payments/simulate`.",
        "security": [
          {
            "bearerAuth": []
          }
        ],
        "parameters": [
          {
            "name": "chargeId",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "$ref": "#/components/parameters/IdempotencyKey"
          },
          {
            "$ref": "#/components/parameters/Traceparent"
          },
          {
            "$ref": "#/components/parameters/Tracestate"
          },
          {
            "$ref": "#/components/parameters/AcceptLanguage"
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "required": [
                  "action"
                ],
                "properties": {
                  "action": {
                    "type": "string",
                    "enum": [
                      "approve",
                      "decline",
                      "timeout",
                      "reverse"
                    ]
                  },
                  "decline_code": {
                    "type": "string"
                  },
                  "delay_ms": {
                    "type": "integer",
                    "minimum": 0,
                    "maximum": 60000,
                    "default": 0
                  }
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Simulation applied.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                },
                "example": {}
              }
            },
            "headers": {
              "traceparent": {
                "$ref": "#/components/headers/Traceparent"
              },
              "Content-Language": {
                "$ref": "#/components/headers/Content-Language"
              },
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/XRateLimitLimit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/XRateLimitRemaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/XRateLimitReset"
              },
              "x-fapi-interaction-id": {
                "$ref": "#/components/headers/XFapiInteractionId"
              }
            }
          },
          "400": {
            "description": "Bad Request",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                },
                "examples": {
                  "ProblemDetailsValidation": {
                    "$ref": "#/components/examples/ProblemDetailsValidation"
                  }
                }
              }
            },
            "headers": {
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/XRateLimitLimit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/XRateLimitRemaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/XRateLimitReset"
              }
            }
          },
          "401": {
            "description": "Unauthorized",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                },
                "examples": {
                  "error": {
                    "$ref": "#/components/examples/ErrorUnauthorized"
                  }
                }
              }
            },
            "headers": {
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/XRateLimitLimit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/XRateLimitRemaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/XRateLimitReset"
              }
            }
          },
          "409": {
            "description": "Conflict",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                },
                "examples": {
                  "ProblemDetailsConflict": {
                    "$ref": "#/components/examples/ProblemDetailsConflict"
                  }
                }
              }
            },
            "headers": {
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/XRateLimitLimit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/XRateLimitRemaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/XRateLimitReset"
              }
            }
          },
          "422": {
            "description": "Unprocessable Entity",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                },
                "examples": {
                  "error": {
                    "$ref": "#/components/examples/ErrorUnprocessable"
                  }
                }
              }
            },
            "headers": {
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/XRateLimitLimit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/XRateLimitRemaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/XRateLimitReset"
              }
            }
          },
          "429": {
            "description": "Rate Limited",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                },
                "examples": {
                  "ProblemDetailsRateLimited": {
                    "$ref": "#/components/examples/ProblemDetailsRateLimited"
                  }
                }
              }
            },
            "headers": {
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/XRateLimitLimit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/XRateLimitRemaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/XRateLimitReset"
              },
              "Retry-After": {
                "$ref": "#/components/headers/RetryAfter"
              }
            }
          }
        },
        "x-codeSamples": [
          {
            "lang": "cURL",
            "label": "cURL",
            "source": "curl -X POST \"https://api.kangopenbanking.com/v1/sandbox/charges/{chargeId}/simulate\" \\\n  -H \"Authorization: Bearer $KOB_ACCESS_TOKEN\" \\\n  -H \"Content-Type: application/json\" \\\n  -d '{}'"
          },
          {
            "lang": "JavaScript",
            "label": "Node.js",
            "source": "import { KangOpenBanking } from \"@kangopenbanking/sdk\";\n\nconst kob = new KangOpenBanking({ apiKey: process.env.KOB_API_KEY });\nconst res = await kob.request(\"POST\", \"/v1/sandbox/charges/{chargeId}/simulate\", { /* payload */ });\nconsole.log(res);"
          },
          {
            "lang": "Python",
            "label": "Python",
            "source": "from kangopenbanking import KangOpenBanking\n\nkob = KangOpenBanking(api_key=os.environ[\"KOB_API_KEY\"])\nres = kob.request(\"POST\", \"/v1/sandbox/charges/{chargeId}/simulate\", json={})\nprint(res)"
          },
          {
            "lang": "PHP",
            "label": "PHP",
            "source": "<?php\n$kob = new KangOpenBanking\\KangOpenBanking(getenv('KOB_API_KEY'));\n$res = $kob->request('POST', '/v1/sandbox/charges/{chargeId}/simulate', []);\nprint_r($res);"
          }
        ]
      }
    },
    "/v1/consents/{consentId}": {
      "parameters": [
        {
          "name": "consentId",
          "in": "path",
          "required": true,
          "schema": {
            "type": "string"
          }
        }
      ],
      "get": {
        "tags": [
          "Consents"
        ],
        "summary": "Get consent",
        "operationId": "getConsent",
        "parameters": [
          {
            "$ref": "#/components/parameters/Traceparent"
          },
          {
            "$ref": "#/components/parameters/Tracestate"
          },
          {
            "$ref": "#/components/parameters/AcceptLanguage"
          }
        ],
        "responses": {
          "200": {
            "description": "Consent record.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Consent"
                },
                "example": {
                  "consent_id": "string",
                  "status": "AwaitingAuthorisation",
                  "permissions": [
                    "string"
                  ],
                  "expiration_date": "2026-01-01T00:00:00Z",
                  "created_at": "2026-01-01T00:00:00Z"
                }
              }
            },
            "headers": {
              "traceparent": {
                "$ref": "#/components/headers/Traceparent"
              },
              "Content-Language": {
                "$ref": "#/components/headers/Content-Language"
              },
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/XRateLimitLimit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/XRateLimitRemaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/XRateLimitReset"
              },
              "x-fapi-interaction-id": {
                "$ref": "#/components/headers/XFapiInteractionId"
              }
            }
          },
          "429": {
            "description": "Rate limit exceeded. Retry after the interval in `Retry-After`.",
            "headers": {
              "Retry-After": {
                "schema": {
                  "type": "integer"
                },
                "description": "Seconds to wait before retrying."
              },
              "X-RateLimit-Limit": {
                "schema": {
                  "type": "integer"
                }
              },
              "X-RateLimit-Remaining": {
                "schema": {
                  "type": "integer"
                }
              },
              "X-RateLimit-Reset": {
                "schema": {
                  "type": "integer"
                }
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                },
                "examples": {
                  "rateLimited": {
                    "$ref": "#/components/examples/ErrorRateLimited"
                  }
                }
              }
            }
          }
        },
        "x-codeSamples": [
          {
            "lang": "cURL",
            "label": "cURL",
            "source": "curl -X GET \"https://api.kangopenbanking.com/v1/consents/{consentId}\" \\\n  -H \"Authorization: Bearer $KOB_ACCESS_TOKEN\" \\\n  -H \"Content-Type: application/json\""
          },
          {
            "lang": "JavaScript",
            "label": "Node.js",
            "source": "import { KangOpenBanking } from \"@kangopenbanking/sdk\";\n\nconst kob = new KangOpenBanking({ apiKey: process.env.KOB_API_KEY });\nconst res = await kob.request(\"GET\", \"/v1/consents/{consentId}\");\nconsole.log(res);"
          },
          {
            "lang": "Python",
            "label": "Python",
            "source": "from kangopenbanking import KangOpenBanking\n\nkob = KangOpenBanking(api_key=os.environ[\"KOB_API_KEY\"])\nres = kob.request(\"GET\", \"/v1/consents/{consentId}\")\nprint(res)"
          },
          {
            "lang": "PHP",
            "label": "PHP",
            "source": "<?php\n$kob = new KangOpenBanking\\KangOpenBanking(getenv('KOB_API_KEY'));\n$res = $kob->request('GET', '/v1/consents/{consentId}');\nprint_r($res);"
          }
        ]
      },
      "delete": {
        "tags": [
          "Consents"
        ],
        "summary": "Revoke consent",
        "operationId": "revokeConsent",
        "parameters": [
          {
            "$ref": "#/components/parameters/Traceparent"
          },
          {
            "$ref": "#/components/parameters/Tracestate"
          },
          {
            "$ref": "#/components/parameters/IdempotencyKey"
          },
          {
            "$ref": "#/components/parameters/AcceptLanguage"
          }
        ],
        "responses": {
          "204": {
            "description": "Consent revoked.",
            "headers": {
              "traceparent": {
                "$ref": "#/components/headers/Traceparent"
              },
              "Content-Language": {
                "$ref": "#/components/headers/Content-Language"
              },
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/XRateLimitLimit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/XRateLimitRemaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/XRateLimitReset"
              }
            }
          },
          "429": {
            "description": "Rate limit exceeded. Retry after the interval in `Retry-After`.",
            "headers": {
              "Retry-After": {
                "schema": {
                  "type": "integer"
                },
                "description": "Seconds to wait before retrying."
              },
              "X-RateLimit-Limit": {
                "schema": {
                  "type": "integer"
                }
              },
              "X-RateLimit-Remaining": {
                "schema": {
                  "type": "integer"
                }
              },
              "X-RateLimit-Reset": {
                "schema": {
                  "type": "integer"
                }
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                },
                "examples": {
                  "rateLimited": {
                    "$ref": "#/components/examples/ErrorRateLimited"
                  }
                }
              }
            }
          }
        },
        "x-codeSamples": [
          {
            "lang": "cURL",
            "label": "cURL",
            "source": "curl -X DELETE \"https://api.kangopenbanking.com/v1/consents/{consentId}\" \\\n  -H \"Authorization: Bearer $KOB_ACCESS_TOKEN\" \\\n  -H \"Content-Type: application/json\""
          },
          {
            "lang": "JavaScript",
            "label": "Node.js",
            "source": "import { KangOpenBanking } from \"@kangopenbanking/sdk\";\n\nconst kob = new KangOpenBanking({ apiKey: process.env.KOB_API_KEY });\nconst res = await kob.request(\"DELETE\", \"/v1/consents/{consentId}\");\nconsole.log(res);"
          },
          {
            "lang": "Python",
            "label": "Python",
            "source": "from kangopenbanking import KangOpenBanking\n\nkob = KangOpenBanking(api_key=os.environ[\"KOB_API_KEY\"])\nres = kob.request(\"DELETE\", \"/v1/consents/{consentId}\")\nprint(res)"
          },
          {
            "lang": "PHP",
            "label": "PHP",
            "source": "<?php\n$kob = new KangOpenBanking\\KangOpenBanking(getenv('KOB_API_KEY'));\n$res = $kob->request('DELETE', '/v1/consents/{consentId}');\nprint_r($res);"
          }
        ]
      }
    },
    "/v1/consents/{consentId}/extend": {
      "parameters": [
        {
          "name": "consentId",
          "in": "path",
          "required": true,
          "schema": {
            "type": "string"
          }
        }
      ],
      "post": {
        "tags": [
          "Consents"
        ],
        "summary": "Extend consent expiration",
        "operationId": "extendConsent",
        "parameters": [
          {
            "$ref": "#/components/parameters/Traceparent"
          },
          {
            "$ref": "#/components/parameters/Tracestate"
          },
          {
            "$ref": "#/components/parameters/IdempotencyKey"
          },
          {
            "$ref": "#/components/parameters/AcceptLanguage"
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "required": [
                  "expiration_date"
                ],
                "properties": {
                  "expiration_date": {
                    "type": "string",
                    "format": "date-time"
                  }
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Consent extended.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Consent"
                },
                "example": {
                  "consent_id": "string",
                  "status": "AwaitingAuthorisation",
                  "permissions": [
                    "string"
                  ],
                  "expiration_date": "2026-01-01T00:00:00Z",
                  "created_at": "2026-01-01T00:00:00Z"
                }
              }
            },
            "headers": {
              "traceparent": {
                "$ref": "#/components/headers/Traceparent"
              },
              "Content-Language": {
                "$ref": "#/components/headers/Content-Language"
              },
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/XRateLimitLimit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/XRateLimitRemaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/XRateLimitReset"
              },
              "x-fapi-interaction-id": {
                "$ref": "#/components/headers/XFapiInteractionId"
              }
            }
          },
          "429": {
            "description": "Rate limit exceeded. Retry after the interval in `Retry-After`.",
            "headers": {
              "Retry-After": {
                "schema": {
                  "type": "integer"
                },
                "description": "Seconds to wait before retrying."
              },
              "X-RateLimit-Limit": {
                "schema": {
                  "type": "integer"
                }
              },
              "X-RateLimit-Remaining": {
                "schema": {
                  "type": "integer"
                }
              },
              "X-RateLimit-Reset": {
                "schema": {
                  "type": "integer"
                }
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                },
                "examples": {
                  "rateLimited": {
                    "$ref": "#/components/examples/ErrorRateLimited"
                  }
                }
              }
            }
          }
        },
        "x-codeSamples": [
          {
            "lang": "cURL",
            "label": "cURL",
            "source": "curl -X POST \"https://api.kangopenbanking.com/v1/consents/{consentId}/extend\" \\\n  -H \"Authorization: Bearer $KOB_ACCESS_TOKEN\" \\\n  -H \"Content-Type: application/json\" \\\n  -d '{}'"
          },
          {
            "lang": "JavaScript",
            "label": "Node.js",
            "source": "import { KangOpenBanking } from \"@kangopenbanking/sdk\";\n\nconst kob = new KangOpenBanking({ apiKey: process.env.KOB_API_KEY });\nconst res = await kob.request(\"POST\", \"/v1/consents/{consentId}/extend\", { /* payload */ });\nconsole.log(res);"
          },
          {
            "lang": "Python",
            "label": "Python",
            "source": "from kangopenbanking import KangOpenBanking\n\nkob = KangOpenBanking(api_key=os.environ[\"KOB_API_KEY\"])\nres = kob.request(\"POST\", \"/v1/consents/{consentId}/extend\", json={})\nprint(res)"
          },
          {
            "lang": "PHP",
            "label": "PHP",
            "source": "<?php\n$kob = new KangOpenBanking\\KangOpenBanking(getenv('KOB_API_KEY'));\n$res = $kob->request('POST', '/v1/consents/{consentId}/extend', []);\nprint_r($res);"
          }
        ]
      }
    },
    "/v1/statements": {
      "post": {
        "tags": [
          "Statements"
        ],
        "summary": "Request statement (camt.053 / pdf / csv)",
        "description": "Generates an ISO 20022 camt.053.001.08 BankToCustomerStatement XML document by default. PDF and CSV formats are produced in parallel for the same period.",
        "operationId": "createStatement",
        "parameters": [
          {
            "$ref": "#/components/parameters/Traceparent"
          },
          {
            "$ref": "#/components/parameters/Tracestate"
          },
          {
            "$ref": "#/components/parameters/IdempotencyKey"
          },
          {
            "$ref": "#/components/parameters/AcceptLanguage"
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/StatementRequest"
              }
            }
          }
        },
        "responses": {
          "202": {
            "description": "Statement job accepted.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Statement"
                },
                "example": {
                  "statement_id": "00000000-0000-4000-8000-000000000000",
                  "account_id": "00000000-0000-4000-8000-000000000000",
                  "period_from": "2026-01-01",
                  "period_to": "2026-01-01",
                  "format": "camt053",
                  "status": "pending",
                  "download_url": "https://api.kangopenbanking.com",
                  "generated_at": "2026-01-01T00:00:00Z"
                }
              }
            },
            "headers": {
              "traceparent": {
                "$ref": "#/components/headers/Traceparent"
              },
              "Content-Language": {
                "$ref": "#/components/headers/Content-Language"
              },
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/XRateLimitLimit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/XRateLimitRemaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/XRateLimitReset"
              }
            }
          },
          "429": {
            "description": "Rate limit exceeded. Retry after the interval in `Retry-After`.",
            "headers": {
              "Retry-After": {
                "schema": {
                  "type": "integer"
                },
                "description": "Seconds to wait before retrying."
              },
              "X-RateLimit-Limit": {
                "schema": {
                  "type": "integer"
                }
              },
              "X-RateLimit-Remaining": {
                "schema": {
                  "type": "integer"
                }
              },
              "X-RateLimit-Reset": {
                "schema": {
                  "type": "integer"
                }
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                },
                "examples": {
                  "rateLimited": {
                    "$ref": "#/components/examples/ErrorRateLimited"
                  }
                }
              }
            }
          }
        },
        "x-codeSamples": [
          {
            "lang": "cURL",
            "label": "cURL",
            "source": "curl -X POST \"https://api.kangopenbanking.com/v1/statements\" \\\n  -H \"Authorization: Bearer $KOB_ACCESS_TOKEN\" \\\n  -H \"Content-Type: application/json\" \\\n  -d '{}'"
          },
          {
            "lang": "JavaScript",
            "label": "Node.js",
            "source": "import { KangOpenBanking } from \"@kangopenbanking/sdk\";\n\nconst kob = new KangOpenBanking({ apiKey: process.env.KOB_API_KEY });\nconst res = await kob.request(\"POST\", \"/v1/statements\", { /* payload */ });\nconsole.log(res);"
          },
          {
            "lang": "Python",
            "label": "Python",
            "source": "from kangopenbanking import KangOpenBanking\n\nkob = KangOpenBanking(api_key=os.environ[\"KOB_API_KEY\"])\nres = kob.request(\"POST\", \"/v1/statements\", json={})\nprint(res)"
          },
          {
            "lang": "PHP",
            "label": "PHP",
            "source": "<?php\n$kob = new KangOpenBanking\\KangOpenBanking(getenv('KOB_API_KEY'));\n$res = $kob->request('POST', '/v1/statements', []);\nprint_r($res);"
          }
        ]
      }
    },
    "/v1/statements/{statementId}": {
      "parameters": [
        {
          "name": "statementId",
          "in": "path",
          "required": true,
          "schema": {
            "type": "string",
            "format": "uuid"
          }
        }
      ],
      "get": {
        "tags": [
          "Statements"
        ],
        "summary": "Get statement metadata",
        "operationId": "getStatement",
        "parameters": [
          {
            "$ref": "#/components/parameters/Traceparent"
          },
          {
            "$ref": "#/components/parameters/Tracestate"
          },
          {
            "$ref": "#/components/parameters/AcceptLanguage"
          }
        ],
        "responses": {
          "200": {
            "description": "Statement record.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Statement"
                },
                "example": {
                  "statement_id": "00000000-0000-4000-8000-000000000000",
                  "account_id": "00000000-0000-4000-8000-000000000000",
                  "period_from": "2026-01-01",
                  "period_to": "2026-01-01",
                  "format": "camt053",
                  "status": "pending",
                  "download_url": "https://api.kangopenbanking.com",
                  "generated_at": "2026-01-01T00:00:00Z"
                }
              }
            },
            "headers": {
              "traceparent": {
                "$ref": "#/components/headers/Traceparent"
              },
              "Content-Language": {
                "$ref": "#/components/headers/Content-Language"
              },
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/XRateLimitLimit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/XRateLimitRemaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/XRateLimitReset"
              },
              "x-fapi-interaction-id": {
                "$ref": "#/components/headers/XFapiInteractionId"
              }
            }
          },
          "429": {
            "description": "Rate limit exceeded. Retry after the interval in `Retry-After`.",
            "headers": {
              "Retry-After": {
                "schema": {
                  "type": "integer"
                },
                "description": "Seconds to wait before retrying."
              },
              "X-RateLimit-Limit": {
                "schema": {
                  "type": "integer"
                }
              },
              "X-RateLimit-Remaining": {
                "schema": {
                  "type": "integer"
                }
              },
              "X-RateLimit-Reset": {
                "schema": {
                  "type": "integer"
                }
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                },
                "examples": {
                  "rateLimited": {
                    "$ref": "#/components/examples/ErrorRateLimited"
                  }
                }
              }
            }
          }
        },
        "x-codeSamples": [
          {
            "lang": "cURL",
            "label": "cURL",
            "source": "curl -X GET \"https://api.kangopenbanking.com/v1/statements/{statementId}\" \\\n  -H \"Authorization: Bearer $KOB_ACCESS_TOKEN\" \\\n  -H \"Content-Type: application/json\""
          },
          {
            "lang": "JavaScript",
            "label": "Node.js",
            "source": "import { KangOpenBanking } from \"@kangopenbanking/sdk\";\n\nconst kob = new KangOpenBanking({ apiKey: process.env.KOB_API_KEY });\nconst res = await kob.request(\"GET\", \"/v1/statements/{statementId}\");\nconsole.log(res);"
          },
          {
            "lang": "Python",
            "label": "Python",
            "source": "from kangopenbanking import KangOpenBanking\n\nkob = KangOpenBanking(api_key=os.environ[\"KOB_API_KEY\"])\nres = kob.request(\"GET\", \"/v1/statements/{statementId}\")\nprint(res)"
          },
          {
            "lang": "PHP",
            "label": "PHP",
            "source": "<?php\n$kob = new KangOpenBanking\\KangOpenBanking(getenv('KOB_API_KEY'));\n$res = $kob->request('GET', '/v1/statements/{statementId}');\nprint_r($res);"
          }
        ]
      }
    },
    "/v1/statements/{statementId}/content": {
      "parameters": [
        {
          "name": "statementId",
          "in": "path",
          "required": true,
          "schema": {
            "type": "string",
            "format": "uuid"
          }
        }
      ],
      "get": {
        "tags": [
          "Statements"
        ],
        "summary": "Download statement content",
        "description": "Returns the raw statement bytes. Content-Type matches the requested format (application/xml for camt.053, application/pdf, text/csv).",
        "operationId": "getStatementContent",
        "parameters": [
          {
            "$ref": "#/components/parameters/Traceparent"
          },
          {
            "$ref": "#/components/parameters/Tracestate"
          },
          {
            "$ref": "#/components/parameters/AcceptLanguage"
          }
        ],
        "responses": {
          "200": {
            "description": "Statement content.",
            "content": {
              "application/xml": {
                "schema": {
                  "type": "string",
                  "description": "camt.053.001.08 XML."
                }
              },
              "application/pdf": {
                "schema": {
                  "type": "string",
                  "format": "binary"
                }
              },
              "text/csv": {
                "schema": {
                  "type": "string"
                }
              }
            },
            "headers": {
              "traceparent": {
                "$ref": "#/components/headers/Traceparent"
              },
              "Content-Language": {
                "$ref": "#/components/headers/Content-Language"
              },
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/XRateLimitLimit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/XRateLimitRemaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/XRateLimitReset"
              },
              "x-fapi-interaction-id": {
                "$ref": "#/components/headers/XFapiInteractionId"
              }
            }
          },
          "429": {
            "description": "Rate limit exceeded. Retry after the interval in `Retry-After`.",
            "headers": {
              "Retry-After": {
                "schema": {
                  "type": "integer"
                },
                "description": "Seconds to wait before retrying."
              },
              "X-RateLimit-Limit": {
                "schema": {
                  "type": "integer"
                }
              },
              "X-RateLimit-Remaining": {
                "schema": {
                  "type": "integer"
                }
              },
              "X-RateLimit-Reset": {
                "schema": {
                  "type": "integer"
                }
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                },
                "examples": {
                  "rateLimited": {
                    "$ref": "#/components/examples/ErrorRateLimited"
                  }
                }
              }
            }
          }
        },
        "x-codeSamples": [
          {
            "lang": "cURL",
            "label": "cURL",
            "source": "curl -X GET \"https://api.kangopenbanking.com/v1/statements/{statementId}/content\" \\\n  -H \"Authorization: Bearer $KOB_ACCESS_TOKEN\" \\\n  -H \"Content-Type: application/json\""
          },
          {
            "lang": "JavaScript",
            "label": "Node.js",
            "source": "import { KangOpenBanking } from \"@kangopenbanking/sdk\";\n\nconst kob = new KangOpenBanking({ apiKey: process.env.KOB_API_KEY });\nconst res = await kob.request(\"GET\", \"/v1/statements/{statementId}/content\");\nconsole.log(res);"
          },
          {
            "lang": "Python",
            "label": "Python",
            "source": "from kangopenbanking import KangOpenBanking\n\nkob = KangOpenBanking(api_key=os.environ[\"KOB_API_KEY\"])\nres = kob.request(\"GET\", \"/v1/statements/{statementId}/content\")\nprint(res)"
          },
          {
            "lang": "PHP",
            "label": "PHP",
            "source": "<?php\n$kob = new KangOpenBanking\\KangOpenBanking(getenv('KOB_API_KEY'));\n$res = $kob->request('GET', '/v1/statements/{statementId}/content');\nprint_r($res);"
          }
        ]
      }
    },
    "/v1/rate-limits": {
      "get": {
        "tags": [
          "Platform"
        ],
        "summary": "Published rate limits per tier",
        "description": "Returns the canonical per-tier rate-limit numbers. Mirrors the values enforced by the gateway and surfaced via `X-RateLimit-Limit` / `X-RateLimit-Remaining` response headers.",
        "operationId": "getRateLimits",
        "parameters": [
          {
            "$ref": "#/components/parameters/Traceparent"
          },
          {
            "$ref": "#/components/parameters/Tracestate"
          },
          {
            "$ref": "#/components/parameters/AcceptLanguage"
          }
        ],
        "responses": {
          "200": {
            "description": "Tier table.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/RateLimitTiers"
                },
                "example": {
                  "data": [
                    {
                      "tier": "free",
                      "requests_per_minute": 60,
                      "burst": 120,
                      "concurrent_connections": 10,
                      "webhook_deliveries_per_minute": 30,
                      "idempotency_window_hours": 24
                    },
                    {
                      "tier": "pro",
                      "requests_per_minute": 600,
                      "burst": 1200,
                      "concurrent_connections": 100,
                      "webhook_deliveries_per_minute": 300,
                      "idempotency_window_hours": 24
                    },
                    {
                      "tier": "enterprise",
                      "requests_per_minute": 6000,
                      "burst": 12000,
                      "concurrent_connections": 1000,
                      "webhook_deliveries_per_minute": 3000,
                      "idempotency_window_hours": 168
                    }
                  ]
                }
              }
            },
            "headers": {
              "traceparent": {
                "$ref": "#/components/headers/Traceparent"
              },
              "Content-Language": {
                "$ref": "#/components/headers/Content-Language"
              },
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/XRateLimitLimit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/XRateLimitRemaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/XRateLimitReset"
              },
              "x-fapi-interaction-id": {
                "$ref": "#/components/headers/XFapiInteractionId"
              }
            }
          },
          "429": {
            "description": "Rate limit exceeded. Retry after the interval in `Retry-After`.",
            "headers": {
              "Retry-After": {
                "schema": {
                  "type": "integer"
                },
                "description": "Seconds to wait before retrying."
              },
              "X-RateLimit-Limit": {
                "schema": {
                  "type": "integer"
                }
              },
              "X-RateLimit-Remaining": {
                "schema": {
                  "type": "integer"
                }
              },
              "X-RateLimit-Reset": {
                "schema": {
                  "type": "integer"
                }
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                },
                "examples": {
                  "rateLimited": {
                    "$ref": "#/components/examples/ErrorRateLimited"
                  }
                }
              }
            }
          }
        },
        "x-codeSamples": [
          {
            "lang": "cURL",
            "label": "cURL",
            "source": "curl -X GET \"https://api.kangopenbanking.com/v1/rate-limits\" \\\n  -H \"Authorization: Bearer $KOB_ACCESS_TOKEN\" \\\n  -H \"Content-Type: application/json\""
          },
          {
            "lang": "JavaScript",
            "label": "Node.js",
            "source": "import { KangOpenBanking } from \"@kangopenbanking/sdk\";\n\nconst kob = new KangOpenBanking({ apiKey: process.env.KOB_API_KEY });\nconst res = await kob.request(\"GET\", \"/v1/rate-limits\");\nconsole.log(res);"
          },
          {
            "lang": "Python",
            "label": "Python",
            "source": "from kangopenbanking import KangOpenBanking\n\nkob = KangOpenBanking(api_key=os.environ[\"KOB_API_KEY\"])\nres = kob.request(\"GET\", \"/v1/rate-limits\")\nprint(res)"
          },
          {
            "lang": "PHP",
            "label": "PHP",
            "source": "<?php\n$kob = new KangOpenBanking\\KangOpenBanking(getenv('KOB_API_KEY'));\n$res = $kob->request('GET', '/v1/rate-limits');\nprint_r($res);"
          }
        ]
      }
    },
    "/v1/errors/{code}": {
      "get": {
        "operationId": "getLocalizedError",
        "tags": [
          "Reference"
        ],
        "summary": "Look up an error code with localized title and detail",
        "description": "Returns the localized title and detail for any RFC 7807 error code emitted by KOB. Useful for bilingual call-centre tooling.",
        "parameters": [
          {
            "name": "code",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "pattern": "^[A-Z]{2,6}_[0-9]{3,4}$"
            },
            "example": "AUTH_001"
          },
          {
            "name": "lang",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string",
              "enum": [
                "en",
                "fr",
                "fr-CM",
                "en-CM"
              ],
              "default": "en"
            }
          },
          {
            "$ref": "#/components/parameters/AcceptLanguage"
          }
        ],
        "responses": {
          "200": {
            "description": "Localized error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/LocalizedError"
                },
                "example": {
                  "code": "AUTH_001",
                  "type": "https://docs.kangopenbanking.com/errors/AUTH_001",
                  "title_en": "Invalid access token",
                  "title_fr": "Jeton d'accès invalide",
                  "detail_en": "string",
                  "detail_fr": "string",
                  "status": 401,
                  "remediation_url": "https://api.kangopenbanking.com"
                }
              }
            },
            "headers": {
              "Content-Language": {
                "$ref": "#/components/headers/Content-Language"
              },
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/XRateLimitLimit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/XRateLimitRemaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/XRateLimitReset"
              },
              "x-fapi-interaction-id": {
                "$ref": "#/components/headers/XFapiInteractionId"
              }
            }
          },
          "404": {
            "description": "Unknown code",
            "headers": {
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/XRateLimitLimit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/XRateLimitRemaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/XRateLimitReset"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                },
                "examples": {
                  "error": {
                    "$ref": "#/components/examples/ErrorNotFound"
                  }
                }
              }
            }
          },
          "429": {
            "description": "Rate limit exceeded. Retry after the interval in `Retry-After`.",
            "headers": {
              "Retry-After": {
                "schema": {
                  "type": "integer"
                },
                "description": "Seconds to wait before retrying."
              },
              "X-RateLimit-Limit": {
                "schema": {
                  "type": "integer"
                }
              },
              "X-RateLimit-Remaining": {
                "schema": {
                  "type": "integer"
                }
              },
              "X-RateLimit-Reset": {
                "schema": {
                  "type": "integer"
                }
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                },
                "examples": {
                  "rateLimited": {
                    "$ref": "#/components/examples/ErrorRateLimited"
                  }
                }
              }
            }
          }
        },
        "x-codeSamples": [
          {
            "lang": "cURL",
            "label": "cURL",
            "source": "curl -X GET \"https://api.kangopenbanking.com/v1/errors/{code}\" \\\n  -H \"Authorization: Bearer $KOB_ACCESS_TOKEN\" \\\n  -H \"Content-Type: application/json\""
          },
          {
            "lang": "JavaScript",
            "label": "Node.js",
            "source": "import { KangOpenBanking } from \"@kangopenbanking/sdk\";\n\nconst kob = new KangOpenBanking({ apiKey: process.env.KOB_API_KEY });\nconst res = await kob.request(\"GET\", \"/v1/errors/{code}\");\nconsole.log(res);"
          },
          {
            "lang": "Python",
            "label": "Python",
            "source": "from kangopenbanking import KangOpenBanking\n\nkob = KangOpenBanking(api_key=os.environ[\"KOB_API_KEY\"])\nres = kob.request(\"GET\", \"/v1/errors/{code}\")\nprint(res)"
          },
          {
            "lang": "PHP",
            "label": "PHP",
            "source": "<?php\n$kob = new KangOpenBanking\\KangOpenBanking(getenv('KOB_API_KEY'));\n$res = $kob->request('GET', '/v1/errors/{code}');\nprint_r($res);"
          }
        ]
      }
    },
    "/v1/verify/nin": {
      "post": {
        "operationId": "verifyNin",
        "tags": [
          "Identity & KYC"
        ],
        "summary": "Verify a CEMAC Numéro d'Identification National (NIN)",
        "description": "Resolves a CEMAC NIN against the national identity registry (ANTIC for Cameroon; equivalent issuers for GA/CG/TD/CF/GQ). Requires a customer consent referenced by `consent_id`.",
        "security": [
          {
            "bearerAuth": []
          }
        ],
        "parameters": [
          {
            "$ref": "#/components/parameters/AcceptLanguage"
          },
          {
            "$ref": "#/components/parameters/IdempotencyKey"
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/NinVerificationRequest"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Verification result",
            "headers": {
              "Content-Language": {
                "schema": {
                  "type": "string",
                  "example": "en"
                }
              },
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/XRateLimitLimit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/XRateLimitRemaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/XRateLimitReset"
              },
              "x-fapi-interaction-id": {
                "$ref": "#/components/headers/XFapiInteractionId"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/NinVerificationResult"
                },
                "example": {
                  "match": true,
                  "score": 97,
                  "holder_full_name": "MBALLA NGONO Jean",
                  "holder_dob": "2026-01-01",
                  "issuing_authority": "ANTIC Cameroun",
                  "issued_at": "2026-01-01",
                  "expires_at": "2026-01-01",
                  "verified_at": "2026-01-01T00:00:00Z"
                }
              }
            }
          },
          "400": {
            "description": "Invalid request",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                },
                "examples": {
                  "error": {
                    "$ref": "#/components/examples/ErrorBadRequest"
                  }
                }
              }
            },
            "headers": {
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/XRateLimitLimit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/XRateLimitRemaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/XRateLimitReset"
              }
            }
          },
          "401": {
            "description": "Unauthorized",
            "headers": {
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/XRateLimitLimit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/XRateLimitRemaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/XRateLimitReset"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                },
                "examples": {
                  "error": {
                    "$ref": "#/components/examples/ErrorUnauthorized"
                  }
                }
              }
            }
          },
          "404": {
            "description": "Not found in registry",
            "headers": {
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/XRateLimitLimit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/XRateLimitRemaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/XRateLimitReset"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                },
                "examples": {
                  "error": {
                    "$ref": "#/components/examples/ErrorNotFound"
                  }
                }
              }
            }
          },
          "429": {
            "description": "Rate limit exceeded. Retry after the interval in `Retry-After`.",
            "headers": {
              "Retry-After": {
                "schema": {
                  "type": "integer"
                },
                "description": "Seconds to wait before retrying."
              },
              "X-RateLimit-Limit": {
                "schema": {
                  "type": "integer"
                }
              },
              "X-RateLimit-Remaining": {
                "schema": {
                  "type": "integer"
                }
              },
              "X-RateLimit-Reset": {
                "schema": {
                  "type": "integer"
                }
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                },
                "examples": {
                  "rateLimited": {
                    "$ref": "#/components/examples/ErrorRateLimited"
                  }
                }
              }
            }
          }
        },
        "x-codeSamples": [
          {
            "lang": "cURL",
            "label": "cURL",
            "source": "curl -X POST \"https://api.kangopenbanking.com/v1/verify/nin\" \\\n  -H \"Authorization: Bearer $KOB_ACCESS_TOKEN\" \\\n  -H \"Content-Type: application/json\" \\\n  -d '{}'"
          },
          {
            "lang": "JavaScript",
            "label": "Node.js",
            "source": "import { KangOpenBanking } from \"@kangopenbanking/sdk\";\n\nconst kob = new KangOpenBanking({ apiKey: process.env.KOB_API_KEY });\nconst res = await kob.request(\"POST\", \"/v1/verify/nin\", { /* payload */ });\nconsole.log(res);"
          },
          {
            "lang": "Python",
            "label": "Python",
            "source": "from kangopenbanking import KangOpenBanking\n\nkob = KangOpenBanking(api_key=os.environ[\"KOB_API_KEY\"])\nres = kob.request(\"POST\", \"/v1/verify/nin\", json={})\nprint(res)"
          },
          {
            "lang": "PHP",
            "label": "PHP",
            "source": "<?php\n$kob = new KangOpenBanking\\KangOpenBanking(getenv('KOB_API_KEY'));\n$res = $kob->request('POST', '/v1/verify/nin', []);\nprint_r($res);"
          }
        ]
      }
    },
    "/v1/verify/cni": {
      "post": {
        "operationId": "verifyCni",
        "tags": [
          "Identity & KYC"
        ],
        "summary": "Verify a CEMAC Carte Nationale d'Identité (CNI)",
        "description": "Resolves a CEMAC national ID card. Mirrors /v1/verify/nin but keyed on the card serial rather than the lifetime NIN.",
        "security": [
          {
            "bearerAuth": []
          }
        ],
        "parameters": [
          {
            "$ref": "#/components/parameters/AcceptLanguage"
          },
          {
            "$ref": "#/components/parameters/IdempotencyKey"
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/CniVerificationRequest"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Verification result",
            "headers": {
              "Content-Language": {
                "schema": {
                  "type": "string",
                  "example": "fr"
                }
              },
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/XRateLimitLimit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/XRateLimitRemaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/XRateLimitReset"
              },
              "x-fapi-interaction-id": {
                "$ref": "#/components/headers/XFapiInteractionId"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/CniVerificationResult"
                },
                "example": {
                  "match": true,
                  "score": 97,
                  "holder_full_name": "MBALLA NGONO Jean",
                  "holder_dob": "2026-01-01",
                  "issuing_authority": "ANTIC Cameroun",
                  "issued_at": "2026-01-01",
                  "expires_at": "2026-01-01",
                  "verified_at": "2026-01-01T00:00:00Z"
                }
              }
            }
          },
          "400": {
            "description": "Invalid request",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                },
                "examples": {
                  "error": {
                    "$ref": "#/components/examples/ErrorBadRequest"
                  }
                }
              }
            },
            "headers": {
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/XRateLimitLimit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/XRateLimitRemaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/XRateLimitReset"
              }
            }
          },
          "401": {
            "description": "Unauthorized",
            "headers": {
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/XRateLimitLimit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/XRateLimitRemaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/XRateLimitReset"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                },
                "examples": {
                  "error": {
                    "$ref": "#/components/examples/ErrorUnauthorized"
                  }
                }
              }
            }
          },
          "404": {
            "description": "Not found in registry",
            "headers": {
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/XRateLimitLimit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/XRateLimitRemaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/XRateLimitReset"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                },
                "examples": {
                  "error": {
                    "$ref": "#/components/examples/ErrorNotFound"
                  }
                }
              }
            }
          },
          "429": {
            "description": "Rate limit exceeded. Retry after the interval in `Retry-After`.",
            "headers": {
              "Retry-After": {
                "schema": {
                  "type": "integer"
                },
                "description": "Seconds to wait before retrying."
              },
              "X-RateLimit-Limit": {
                "schema": {
                  "type": "integer"
                }
              },
              "X-RateLimit-Remaining": {
                "schema": {
                  "type": "integer"
                }
              },
              "X-RateLimit-Reset": {
                "schema": {
                  "type": "integer"
                }
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                },
                "examples": {
                  "rateLimited": {
                    "$ref": "#/components/examples/ErrorRateLimited"
                  }
                }
              }
            }
          }
        },
        "x-codeSamples": [
          {
            "lang": "cURL",
            "label": "cURL",
            "source": "curl -X POST \"https://api.kangopenbanking.com/v1/verify/cni\" \\\n  -H \"Authorization: Bearer $KOB_ACCESS_TOKEN\" \\\n  -H \"Content-Type: application/json\" \\\n  -d '{}'"
          },
          {
            "lang": "JavaScript",
            "label": "Node.js",
            "source": "import { KangOpenBanking } from \"@kangopenbanking/sdk\";\n\nconst kob = new KangOpenBanking({ apiKey: process.env.KOB_API_KEY });\nconst res = await kob.request(\"POST\", \"/v1/verify/cni\", { /* payload */ });\nconsole.log(res);"
          },
          {
            "lang": "Python",
            "label": "Python",
            "source": "from kangopenbanking import KangOpenBanking\n\nkob = KangOpenBanking(api_key=os.environ[\"KOB_API_KEY\"])\nres = kob.request(\"POST\", \"/v1/verify/cni\", json={})\nprint(res)"
          },
          {
            "lang": "PHP",
            "label": "PHP",
            "source": "<?php\n$kob = new KangOpenBanking\\KangOpenBanking(getenv('KOB_API_KEY'));\n$res = $kob->request('POST', '/v1/verify/cni', []);\nprint_r($res);"
          }
        ]
      }
    },
    "/v1/agents": {
      "get": {
        "tags": [
          "Agents"
        ],
        "summary": "Discover agents (geo + region filter)",
        "operationId": "agentList",
        "parameters": [
          {
            "name": "country_code",
            "in": "query",
            "schema": {
              "type": "string",
              "enum": [
                "CM",
                "GA",
                "CG",
                "TD",
                "CF",
                "GQ"
              ]
            }
          },
          {
            "name": "region",
            "in": "query",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "status",
            "in": "query",
            "schema": {
              "type": "string",
              "enum": [
                "active",
                "pending",
                "suspended",
                "terminated"
              ],
              "default": "active"
            }
          },
          {
            "name": "limit",
            "in": "query",
            "schema": {
              "type": "integer",
              "minimum": 1,
              "maximum": 200,
              "default": 50
            }
          },
          {
            "name": "Accept-Language",
            "in": "header",
            "required": false,
            "schema": {
              "type": "string",
              "example": "fr"
            }
          },
          {
            "name": "cursor",
            "in": "query",
            "required": false,
            "description": "Opaque, signed forward cursor returned as `pagination.next_cursor`. Cursors expire after 1800 seconds.",
            "schema": {
              "type": "string",
              "maxLength": 512
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Agent list",
            "content": {
              "application/json": {
                "schema": {
                  "allOf": [
                    {
                      "$ref": "#/components/schemas/PaginatedResponse"
                    },
                    {
                      "type": "object",
                      "properties": {
                        "data": {
                          "type": "array",
                          "items": {
                            "$ref": "#/components/schemas/Agent"
                          }
                        }
                      }
                    }
                  ]
                },
                "example": {
                  "data": [
                    {
                      "id": "f1d6f4a0-1d4e-4a3a-9e0a-1a2b3c4d5e6f",
                      "agent_code": "AG3K7M2P",
                      "business_name": "Mama Africa Mobile Money",
                      "legal_name": "XAF",
                      "msisdn": "+237671234567",
                      "email": "agent@example.cm",
                      "country_code": "CM",
                      "region": "Centre",
                      "city": "Yaoundé",
                      "address": "XAF",
                      "latitude": 3.848,
                      "longitude": 11.502,
                      "status": "pending",
                      "tier": "standard",
                      "commission_rate": 0.01,
                      "created_at": "2026-01-31T12:00:00Z"
                    }
                  ],
                  "pagination": {
                    "page": 1,
                    "limit": 20,
                    "total": 150,
                    "has_next": true,
                    "next_cursor": "eyJpZCI6IjEyMyJ9"
                  },
                  "meta": {
                    "request_id": "550e8400-e29b-41d4-a716-446655440000",
                    "timestamp": "2025-03-27T12:00:00Z",
                    "api_version": "4.3.0"
                  }
                }
              }
            },
            "headers": {
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/XRateLimitLimit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/XRateLimitRemaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/XRateLimitReset"
              },
              "x-fapi-interaction-id": {
                "$ref": "#/components/headers/XFapiInteractionId"
              }
            }
          },
          "429": {
            "description": "Rate limit exceeded. Retry after the interval in `Retry-After`.",
            "headers": {
              "Retry-After": {
                "schema": {
                  "type": "integer"
                },
                "description": "Seconds to wait before retrying."
              },
              "X-RateLimit-Limit": {
                "schema": {
                  "type": "integer"
                }
              },
              "X-RateLimit-Remaining": {
                "schema": {
                  "type": "integer"
                }
              },
              "X-RateLimit-Reset": {
                "schema": {
                  "type": "integer"
                }
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                },
                "examples": {
                  "rateLimited": {
                    "$ref": "#/components/examples/ErrorRateLimited"
                  }
                }
              }
            }
          }
        },
        "x-codeSamples": [
          {
            "lang": "cURL",
            "label": "cURL",
            "source": "curl -X GET \"https://api.kangopenbanking.com/v1/agents\" \\\n  -H \"Authorization: Bearer $KOB_ACCESS_TOKEN\" \\\n  -H \"Content-Type: application/json\""
          },
          {
            "lang": "JavaScript",
            "label": "Node.js",
            "source": "import { KangOpenBanking } from \"@kangopenbanking/sdk\";\n\nconst kob = new KangOpenBanking({ apiKey: process.env.KOB_API_KEY });\nconst res = await kob.request(\"GET\", \"/v1/agents\");\nconsole.log(res);"
          },
          {
            "lang": "Python",
            "label": "Python",
            "source": "from kangopenbanking import KangOpenBanking\n\nkob = KangOpenBanking(api_key=os.environ[\"KOB_API_KEY\"])\nres = kob.request(\"GET\", \"/v1/agents\")\nprint(res)"
          },
          {
            "lang": "PHP",
            "label": "PHP",
            "source": "<?php\n$kob = new KangOpenBanking\\KangOpenBanking(getenv('KOB_API_KEY'));\n$res = $kob->request('GET', '/v1/agents');\nprint_r($res);"
          }
        ]
      },
      "post": {
        "tags": [
          "Agents"
        ],
        "summary": "Register a new agent",
        "operationId": "agentRegister",
        "parameters": [
          {
            "name": "Accept-Language",
            "in": "header",
            "required": false,
            "schema": {
              "type": "string",
              "example": "fr"
            }
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/AgentRegisterRequest"
              }
            }
          }
        },
        "responses": {
          "201": {
            "description": "Created",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Agent"
                },
                "example": {
                  "id": "00000000-0000-4000-8000-000000000000",
                  "agent_code": "AG3K7M2P",
                  "business_name": "Mama Africa Mobile Money",
                  "legal_name": "string",
                  "msisdn": "+237671234567",
                  "email": "agent@example.cm",
                  "country_code": "CM",
                  "region": "Centre",
                  "city": "Yaoundé",
                  "address": "string",
                  "latitude": 3.848,
                  "longitude": 11.502,
                  "status": "pending",
                  "tier": "standard",
                  "commission_rate": 0.01,
                  "created_at": "2026-01-01T00:00:00Z"
                }
              }
            },
            "headers": {
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/XRateLimitLimit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/XRateLimitRemaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/XRateLimitReset"
              },
              "x-fapi-interaction-id": {
                "$ref": "#/components/headers/XFapiInteractionId"
              }
            }
          },
          "400": {
            "description": "Validation error",
            "headers": {
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/XRateLimitLimit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/XRateLimitRemaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/XRateLimitReset"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                },
                "examples": {
                  "error": {
                    "$ref": "#/components/examples/ErrorBadRequest"
                  }
                }
              }
            }
          },
          "429": {
            "description": "Rate limit exceeded. Retry after the interval in `Retry-After`.",
            "headers": {
              "Retry-After": {
                "schema": {
                  "type": "integer"
                },
                "description": "Seconds to wait before retrying."
              },
              "X-RateLimit-Limit": {
                "schema": {
                  "type": "integer"
                }
              },
              "X-RateLimit-Remaining": {
                "schema": {
                  "type": "integer"
                }
              },
              "X-RateLimit-Reset": {
                "schema": {
                  "type": "integer"
                }
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                },
                "examples": {
                  "rateLimited": {
                    "$ref": "#/components/examples/ErrorRateLimited"
                  }
                }
              }
            }
          }
        },
        "x-codeSamples": [
          {
            "lang": "cURL",
            "label": "cURL",
            "source": "curl -X POST \"https://api.kangopenbanking.com/v1/agents\" \\\n  -H \"Authorization: Bearer $KOB_ACCESS_TOKEN\" \\\n  -H \"Content-Type: application/json\" \\\n  -d '{}'"
          },
          {
            "lang": "JavaScript",
            "label": "Node.js",
            "source": "import { KangOpenBanking } from \"@kangopenbanking/sdk\";\n\nconst kob = new KangOpenBanking({ apiKey: process.env.KOB_API_KEY });\nconst res = await kob.request(\"POST\", \"/v1/agents\", { /* payload */ });\nconsole.log(res);"
          },
          {
            "lang": "Python",
            "label": "Python",
            "source": "from kangopenbanking import KangOpenBanking\n\nkob = KangOpenBanking(api_key=os.environ[\"KOB_API_KEY\"])\nres = kob.request(\"POST\", \"/v1/agents\", json={})\nprint(res)"
          },
          {
            "lang": "PHP",
            "label": "PHP",
            "source": "<?php\n$kob = new KangOpenBanking\\KangOpenBanking(getenv('KOB_API_KEY'));\n$res = $kob->request('POST', '/v1/agents', []);\nprint_r($res);"
          }
        ]
      }
    },
    "/v1/agents/{agentId}": {
      "get": {
        "tags": [
          "Agents"
        ],
        "summary": "Read agent (including float balances)",
        "operationId": "agentGet",
        "parameters": [
          {
            "name": "agentId",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          },
          {
            "name": "Accept-Language",
            "in": "header",
            "required": false,
            "schema": {
              "type": "string",
              "example": "fr"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Agent with embedded floats",
            "content": {
              "application/json": {
                "schema": {
                  "allOf": [
                    {
                      "$ref": "#/components/schemas/Agent"
                    },
                    {
                      "type": "object",
                      "properties": {
                        "agent_floats": {
                          "type": "array",
                          "items": {
                            "$ref": "#/components/schemas/AgentFloat"
                          }
                        }
                      }
                    }
                  ]
                },
                "example": {
                  "id": "00000000-0000-4000-8000-000000000000",
                  "agent_code": "AG3K7M2P",
                  "business_name": "Mama Africa Mobile Money",
                  "legal_name": "string",
                  "msisdn": "+237671234567",
                  "email": "agent@example.cm",
                  "country_code": "CM",
                  "region": "Centre",
                  "city": "Yaoundé",
                  "address": "string",
                  "latitude": 3.848,
                  "longitude": 11.502,
                  "status": "pending",
                  "tier": "standard",
                  "commission_rate": 0.01,
                  "created_at": "2026-01-01T00:00:00Z",
                  "agent_floats": [
                    {
                      "currency": "XAF",
                      "float_balance": 250000,
                      "cash_balance": 75000,
                      "low_threshold": 50000,
                      "last_topup_at": "2026-01-31T12:00:00Z"
                    }
                  ]
                }
              }
            },
            "headers": {
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/XRateLimitLimit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/XRateLimitRemaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/XRateLimitReset"
              },
              "x-fapi-interaction-id": {
                "$ref": "#/components/headers/XFapiInteractionId"
              }
            }
          },
          "404": {
            "description": "Not found",
            "headers": {
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/XRateLimitLimit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/XRateLimitRemaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/XRateLimitReset"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                },
                "examples": {
                  "error": {
                    "$ref": "#/components/examples/ErrorNotFound"
                  }
                }
              }
            }
          },
          "429": {
            "description": "Rate limit exceeded. Retry after the interval in `Retry-After`.",
            "headers": {
              "Retry-After": {
                "schema": {
                  "type": "integer"
                },
                "description": "Seconds to wait before retrying."
              },
              "X-RateLimit-Limit": {
                "schema": {
                  "type": "integer"
                }
              },
              "X-RateLimit-Remaining": {
                "schema": {
                  "type": "integer"
                }
              },
              "X-RateLimit-Reset": {
                "schema": {
                  "type": "integer"
                }
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                },
                "examples": {
                  "rateLimited": {
                    "$ref": "#/components/examples/ErrorRateLimited"
                  }
                }
              }
            }
          }
        },
        "x-codeSamples": [
          {
            "lang": "cURL",
            "label": "cURL",
            "source": "curl -X GET \"https://api.kangopenbanking.com/v1/agents/{agentId}\" \\\n  -H \"Authorization: Bearer $KOB_ACCESS_TOKEN\" \\\n  -H \"Content-Type: application/json\""
          },
          {
            "lang": "JavaScript",
            "label": "Node.js",
            "source": "import { KangOpenBanking } from \"@kangopenbanking/sdk\";\n\nconst kob = new KangOpenBanking({ apiKey: process.env.KOB_API_KEY });\nconst res = await kob.request(\"GET\", \"/v1/agents/{agentId}\");\nconsole.log(res);"
          },
          {
            "lang": "Python",
            "label": "Python",
            "source": "from kangopenbanking import KangOpenBanking\n\nkob = KangOpenBanking(api_key=os.environ[\"KOB_API_KEY\"])\nres = kob.request(\"GET\", \"/v1/agents/{agentId}\")\nprint(res)"
          },
          {
            "lang": "PHP",
            "label": "PHP",
            "source": "<?php\n$kob = new KangOpenBanking\\KangOpenBanking(getenv('KOB_API_KEY'));\n$res = $kob->request('GET', '/v1/agents/{agentId}');\nprint_r($res);"
          }
        ]
      }
    },
    "/v1/agents/{agentId}/float/topup": {
      "post": {
        "tags": [
          "Agents"
        ],
        "summary": "Top up agent float",
        "operationId": "agentFloatTopup",
        "parameters": [
          {
            "name": "agentId",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          },
          {
            "name": "Idempotency-Key",
            "in": "header",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid"
            },
            "description": "UUIDv4. Replays with the same key return the original transaction."
          },
          {
            "name": "Accept-Language",
            "in": "header",
            "required": false,
            "schema": {
              "type": "string",
              "example": "fr"
            }
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/AgentFloatMutationRequest"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Idempotent replay",
            "headers": {
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/XRateLimitLimit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/XRateLimitRemaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/XRateLimitReset"
              },
              "x-fapi-interaction-id": {
                "$ref": "#/components/headers/XFapiInteractionId"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/GenericSuccessResponse"
                },
                "example": {
                  "success": true,
                  "data": {},
                  "request_id": "string"
                }
              }
            }
          },
          "201": {
            "description": "Transaction recorded",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/AgentCashTransaction"
                },
                "example": {
                  "id": "00000000-0000-4000-8000-000000000000",
                  "agent_id": "00000000-0000-4000-8000-000000000000",
                  "customer_msisdn": "string",
                  "customer_user_id": "00000000-0000-4000-8000-000000000000",
                  "tx_type": "cash_in",
                  "amount": "1000",
                  "currency": "string",
                  "commission_amount": 0,
                  "status": "pending",
                  "idempotency_key": "00000000-0000-4000-8000-000000000000",
                  "created_at": "2026-01-01T00:00:00Z",
                  "completed_at": "2026-01-01T00:00:00Z"
                }
              }
            },
            "headers": {
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/XRateLimitLimit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/XRateLimitRemaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/XRateLimitReset"
              },
              "x-fapi-interaction-id": {
                "$ref": "#/components/headers/XFapiInteractionId"
              }
            }
          },
          "409": {
            "description": "Insufficient float",
            "headers": {
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/XRateLimitLimit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/XRateLimitRemaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/XRateLimitReset"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                },
                "examples": {
                  "error": {
                    "$ref": "#/components/examples/ErrorConflict"
                  }
                }
              }
            }
          },
          "429": {
            "description": "Rate limit exceeded. Retry after the interval in `Retry-After`.",
            "headers": {
              "Retry-After": {
                "schema": {
                  "type": "integer"
                },
                "description": "Seconds to wait before retrying."
              },
              "X-RateLimit-Limit": {
                "schema": {
                  "type": "integer"
                }
              },
              "X-RateLimit-Remaining": {
                "schema": {
                  "type": "integer"
                }
              },
              "X-RateLimit-Reset": {
                "schema": {
                  "type": "integer"
                }
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                },
                "examples": {
                  "rateLimited": {
                    "$ref": "#/components/examples/ErrorRateLimited"
                  }
                }
              }
            }
          }
        },
        "x-codeSamples": [
          {
            "lang": "cURL",
            "label": "cURL",
            "source": "curl -X POST \"https://api.kangopenbanking.com/v1/agents/{agentId}/float/topup\" \\\n  -H \"Authorization: Bearer $KOB_ACCESS_TOKEN\" \\\n  -H \"Content-Type: application/json\" \\\n  -d '{}'"
          },
          {
            "lang": "JavaScript",
            "label": "Node.js",
            "source": "import { KangOpenBanking } from \"@kangopenbanking/sdk\";\n\nconst kob = new KangOpenBanking({ apiKey: process.env.KOB_API_KEY });\nconst res = await kob.request(\"POST\", \"/v1/agents/{agentId}/float/topup\", { /* payload */ });\nconsole.log(res);"
          },
          {
            "lang": "Python",
            "label": "Python",
            "source": "from kangopenbanking import KangOpenBanking\n\nkob = KangOpenBanking(api_key=os.environ[\"KOB_API_KEY\"])\nres = kob.request(\"POST\", \"/v1/agents/{agentId}/float/topup\", json={})\nprint(res)"
          },
          {
            "lang": "PHP",
            "label": "PHP",
            "source": "<?php\n$kob = new KangOpenBanking\\KangOpenBanking(getenv('KOB_API_KEY'));\n$res = $kob->request('POST', '/v1/agents/{agentId}/float/topup', []);\nprint_r($res);"
          }
        ]
      }
    },
    "/v1/agents/{agentId}/float/withdraw": {
      "post": {
        "tags": [
          "Agents"
        ],
        "summary": "Withdraw from agent float",
        "operationId": "agentFloatWithdraw",
        "parameters": [
          {
            "name": "agentId",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          },
          {
            "name": "Idempotency-Key",
            "in": "header",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid"
            },
            "description": "UUIDv4. Replays with the same key return the original transaction."
          },
          {
            "name": "Accept-Language",
            "in": "header",
            "required": false,
            "schema": {
              "type": "string",
              "example": "fr"
            }
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/AgentFloatMutationRequest"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Idempotent replay",
            "headers": {
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/XRateLimitLimit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/XRateLimitRemaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/XRateLimitReset"
              },
              "x-fapi-interaction-id": {
                "$ref": "#/components/headers/XFapiInteractionId"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/GenericSuccessResponse"
                },
                "example": {
                  "success": true,
                  "data": {},
                  "request_id": "string"
                }
              }
            }
          },
          "201": {
            "description": "Transaction recorded",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/AgentCashTransaction"
                },
                "example": {
                  "id": "00000000-0000-4000-8000-000000000000",
                  "agent_id": "00000000-0000-4000-8000-000000000000",
                  "customer_msisdn": "string",
                  "customer_user_id": "00000000-0000-4000-8000-000000000000",
                  "tx_type": "cash_in",
                  "amount": "1000",
                  "currency": "string",
                  "commission_amount": 0,
                  "status": "pending",
                  "idempotency_key": "00000000-0000-4000-8000-000000000000",
                  "created_at": "2026-01-01T00:00:00Z",
                  "completed_at": "2026-01-01T00:00:00Z"
                }
              }
            },
            "headers": {
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/XRateLimitLimit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/XRateLimitRemaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/XRateLimitReset"
              },
              "x-fapi-interaction-id": {
                "$ref": "#/components/headers/XFapiInteractionId"
              }
            }
          },
          "409": {
            "description": "Insufficient float",
            "headers": {
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/XRateLimitLimit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/XRateLimitRemaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/XRateLimitReset"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                },
                "examples": {
                  "error": {
                    "$ref": "#/components/examples/ErrorConflict"
                  }
                }
              }
            }
          },
          "429": {
            "description": "Rate limit exceeded. Retry after the interval in `Retry-After`.",
            "headers": {
              "Retry-After": {
                "schema": {
                  "type": "integer"
                },
                "description": "Seconds to wait before retrying."
              },
              "X-RateLimit-Limit": {
                "schema": {
                  "type": "integer"
                }
              },
              "X-RateLimit-Remaining": {
                "schema": {
                  "type": "integer"
                }
              },
              "X-RateLimit-Reset": {
                "schema": {
                  "type": "integer"
                }
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                },
                "examples": {
                  "rateLimited": {
                    "$ref": "#/components/examples/ErrorRateLimited"
                  }
                }
              }
            }
          }
        },
        "x-codeSamples": [
          {
            "lang": "cURL",
            "label": "cURL",
            "source": "curl -X POST \"https://api.kangopenbanking.com/v1/agents/{agentId}/float/withdraw\" \\\n  -H \"Authorization: Bearer $KOB_ACCESS_TOKEN\" \\\n  -H \"Content-Type: application/json\" \\\n  -d '{}'"
          },
          {
            "lang": "JavaScript",
            "label": "Node.js",
            "source": "import { KangOpenBanking } from \"@kangopenbanking/sdk\";\n\nconst kob = new KangOpenBanking({ apiKey: process.env.KOB_API_KEY });\nconst res = await kob.request(\"POST\", \"/v1/agents/{agentId}/float/withdraw\", { /* payload */ });\nconsole.log(res);"
          },
          {
            "lang": "Python",
            "label": "Python",
            "source": "from kangopenbanking import KangOpenBanking\n\nkob = KangOpenBanking(api_key=os.environ[\"KOB_API_KEY\"])\nres = kob.request(\"POST\", \"/v1/agents/{agentId}/float/withdraw\", json={})\nprint(res)"
          },
          {
            "lang": "PHP",
            "label": "PHP",
            "source": "<?php\n$kob = new KangOpenBanking\\KangOpenBanking(getenv('KOB_API_KEY'));\n$res = $kob->request('POST', '/v1/agents/{agentId}/float/withdraw', []);\nprint_r($res);"
          }
        ]
      }
    },
    "/v1/agents/{agentId}/cash-in": {
      "post": {
        "tags": [
          "Agents"
        ],
        "summary": "Customer deposits cash with agent",
        "operationId": "agentCashIn",
        "parameters": [
          {
            "name": "agentId",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          },
          {
            "name": "Idempotency-Key",
            "in": "header",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid"
            },
            "description": "UUIDv4. Replays with the same key return the original transaction."
          },
          {
            "name": "Accept-Language",
            "in": "header",
            "required": false,
            "schema": {
              "type": "string",
              "example": "fr"
            }
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/AgentCashRequest"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Idempotent replay",
            "headers": {
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/XRateLimitLimit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/XRateLimitRemaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/XRateLimitReset"
              },
              "x-fapi-interaction-id": {
                "$ref": "#/components/headers/XFapiInteractionId"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/GenericSuccessResponse"
                },
                "example": {
                  "success": true,
                  "data": {},
                  "request_id": "string"
                }
              }
            }
          },
          "201": {
            "description": "Transaction recorded",
            "headers": {
              "X-Float-Warning": {
                "description": "Set to 'low_float' when the agent's float balance falls below low_threshold.",
                "schema": {
                  "type": "string",
                  "enum": [
                    "low_float"
                  ]
                }
              },
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/XRateLimitLimit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/XRateLimitRemaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/XRateLimitReset"
              },
              "x-fapi-interaction-id": {
                "$ref": "#/components/headers/XFapiInteractionId"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/AgentCashTransaction"
                },
                "example": {
                  "id": "00000000-0000-4000-8000-000000000000",
                  "agent_id": "00000000-0000-4000-8000-000000000000",
                  "customer_msisdn": "string",
                  "customer_user_id": "00000000-0000-4000-8000-000000000000",
                  "tx_type": "cash_in",
                  "amount": "1000",
                  "currency": "string",
                  "commission_amount": 0,
                  "status": "pending",
                  "idempotency_key": "00000000-0000-4000-8000-000000000000",
                  "created_at": "2026-01-01T00:00:00Z",
                  "completed_at": "2026-01-01T00:00:00Z"
                }
              }
            }
          },
          "409": {
            "description": "Insufficient float or cash",
            "headers": {
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/XRateLimitLimit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/XRateLimitRemaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/XRateLimitReset"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                },
                "examples": {
                  "error": {
                    "$ref": "#/components/examples/ErrorConflict"
                  }
                }
              }
            }
          },
          "429": {
            "description": "Rate limit exceeded. Retry after the interval in `Retry-After`.",
            "headers": {
              "Retry-After": {
                "schema": {
                  "type": "integer"
                },
                "description": "Seconds to wait before retrying."
              },
              "X-RateLimit-Limit": {
                "schema": {
                  "type": "integer"
                }
              },
              "X-RateLimit-Remaining": {
                "schema": {
                  "type": "integer"
                }
              },
              "X-RateLimit-Reset": {
                "schema": {
                  "type": "integer"
                }
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                },
                "examples": {
                  "rateLimited": {
                    "$ref": "#/components/examples/ErrorRateLimited"
                  }
                }
              }
            }
          }
        },
        "x-codeSamples": [
          {
            "lang": "cURL",
            "label": "cURL",
            "source": "curl -X POST \"https://api.kangopenbanking.com/v1/agents/{agentId}/cash-in\" \\\n  -H \"Authorization: Bearer $KOB_ACCESS_TOKEN\" \\\n  -H \"Content-Type: application/json\" \\\n  -d '{}'"
          },
          {
            "lang": "JavaScript",
            "label": "Node.js",
            "source": "import { KangOpenBanking } from \"@kangopenbanking/sdk\";\n\nconst kob = new KangOpenBanking({ apiKey: process.env.KOB_API_KEY });\nconst res = await kob.request(\"POST\", \"/v1/agents/{agentId}/cash-in\", { /* payload */ });\nconsole.log(res);"
          },
          {
            "lang": "Python",
            "label": "Python",
            "source": "from kangopenbanking import KangOpenBanking\n\nkob = KangOpenBanking(api_key=os.environ[\"KOB_API_KEY\"])\nres = kob.request(\"POST\", \"/v1/agents/{agentId}/cash-in\", json={})\nprint(res)"
          },
          {
            "lang": "PHP",
            "label": "PHP",
            "source": "<?php\n$kob = new KangOpenBanking\\KangOpenBanking(getenv('KOB_API_KEY'));\n$res = $kob->request('POST', '/v1/agents/{agentId}/cash-in', []);\nprint_r($res);"
          }
        ]
      }
    },
    "/v1/agents/{agentId}/cash-out": {
      "post": {
        "tags": [
          "Agents"
        ],
        "summary": "Customer withdraws cash from agent",
        "operationId": "agentCashOut",
        "parameters": [
          {
            "name": "agentId",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          },
          {
            "name": "Idempotency-Key",
            "in": "header",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid"
            },
            "description": "UUIDv4. Replays with the same key return the original transaction."
          },
          {
            "name": "Accept-Language",
            "in": "header",
            "required": false,
            "schema": {
              "type": "string",
              "example": "fr"
            }
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/AgentCashRequest"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Idempotent replay",
            "headers": {
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/XRateLimitLimit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/XRateLimitRemaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/XRateLimitReset"
              },
              "x-fapi-interaction-id": {
                "$ref": "#/components/headers/XFapiInteractionId"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/GenericSuccessResponse"
                },
                "example": {
                  "success": true,
                  "data": {},
                  "request_id": "string"
                }
              }
            }
          },
          "201": {
            "description": "Transaction recorded",
            "headers": {
              "X-Float-Warning": {
                "description": "Set to 'low_float' when the agent's float balance falls below low_threshold.",
                "schema": {
                  "type": "string",
                  "enum": [
                    "low_float"
                  ]
                }
              },
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/XRateLimitLimit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/XRateLimitRemaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/XRateLimitReset"
              },
              "x-fapi-interaction-id": {
                "$ref": "#/components/headers/XFapiInteractionId"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/AgentCashTransaction"
                },
                "example": {
                  "id": "00000000-0000-4000-8000-000000000000",
                  "agent_id": "00000000-0000-4000-8000-000000000000",
                  "customer_msisdn": "string",
                  "customer_user_id": "00000000-0000-4000-8000-000000000000",
                  "tx_type": "cash_in",
                  "amount": "1000",
                  "currency": "string",
                  "commission_amount": 0,
                  "status": "pending",
                  "idempotency_key": "00000000-0000-4000-8000-000000000000",
                  "created_at": "2026-01-01T00:00:00Z",
                  "completed_at": "2026-01-01T00:00:00Z"
                }
              }
            }
          },
          "409": {
            "description": "Insufficient float or cash",
            "headers": {
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/XRateLimitLimit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/XRateLimitRemaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/XRateLimitReset"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                },
                "examples": {
                  "error": {
                    "$ref": "#/components/examples/ErrorConflict"
                  }
                }
              }
            }
          },
          "429": {
            "description": "Rate limit exceeded. Retry after the interval in `Retry-After`.",
            "headers": {
              "Retry-After": {
                "schema": {
                  "type": "integer"
                },
                "description": "Seconds to wait before retrying."
              },
              "X-RateLimit-Limit": {
                "schema": {
                  "type": "integer"
                }
              },
              "X-RateLimit-Remaining": {
                "schema": {
                  "type": "integer"
                }
              },
              "X-RateLimit-Reset": {
                "schema": {
                  "type": "integer"
                }
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                },
                "examples": {
                  "rateLimited": {
                    "$ref": "#/components/examples/ErrorRateLimited"
                  }
                }
              }
            }
          }
        },
        "x-codeSamples": [
          {
            "lang": "cURL",
            "label": "cURL",
            "source": "curl -X POST \"https://api.kangopenbanking.com/v1/agents/{agentId}/cash-out\" \\\n  -H \"Authorization: Bearer $KOB_ACCESS_TOKEN\" \\\n  -H \"Content-Type: application/json\" \\\n  -d '{}'"
          },
          {
            "lang": "JavaScript",
            "label": "Node.js",
            "source": "import { KangOpenBanking } from \"@kangopenbanking/sdk\";\n\nconst kob = new KangOpenBanking({ apiKey: process.env.KOB_API_KEY });\nconst res = await kob.request(\"POST\", \"/v1/agents/{agentId}/cash-out\", { /* payload */ });\nconsole.log(res);"
          },
          {
            "lang": "Python",
            "label": "Python",
            "source": "from kangopenbanking import KangOpenBanking\n\nkob = KangOpenBanking(api_key=os.environ[\"KOB_API_KEY\"])\nres = kob.request(\"POST\", \"/v1/agents/{agentId}/cash-out\", json={})\nprint(res)"
          },
          {
            "lang": "PHP",
            "label": "PHP",
            "source": "<?php\n$kob = new KangOpenBanking\\KangOpenBanking(getenv('KOB_API_KEY'));\n$res = $kob->request('POST', '/v1/agents/{agentId}/cash-out', []);\nprint_r($res);"
          }
        ]
      }
    },
    "/v1/agents/{agentId}/transactions": {
      "get": {
        "tags": [
          "Agents"
        ],
        "summary": "List agent cash transactions",
        "operationId": "agentTransactionList",
        "parameters": [
          {
            "name": "agentId",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          },
          {
            "name": "limit",
            "in": "query",
            "schema": {
              "type": "integer",
              "minimum": 1,
              "maximum": 200,
              "default": 50
            }
          },
          {
            "name": "Accept-Language",
            "in": "header",
            "required": false,
            "schema": {
              "type": "string",
              "example": "fr"
            }
          },
          {
            "name": "cursor",
            "in": "query",
            "required": false,
            "description": "Opaque, signed forward cursor returned as `pagination.next_cursor`. Cursors expire after 1800 seconds.",
            "schema": {
              "type": "string",
              "maxLength": 512
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Transaction list",
            "content": {
              "application/json": {
                "schema": {
                  "allOf": [
                    {
                      "$ref": "#/components/schemas/PaginatedResponse"
                    },
                    {
                      "type": "object",
                      "properties": {
                        "data": {
                          "type": "array",
                          "items": {
                            "$ref": "#/components/schemas/AgentCashTransaction"
                          }
                        }
                      }
                    }
                  ]
                },
                "example": {
                  "data": [
                    {
                      "id": "f1d6f4a0-1d4e-4a3a-9e0a-1a2b3c4d5e6f",
                      "agent_id": "f1d6f4a0-1d4e-4a3a-9e0a-1a2b3c4d5e6f",
                      "customer_msisdn": "XAF",
                      "customer_user_id": "f1d6f4a0-1d4e-4a3a-9e0a-1a2b3c4d5e6f",
                      "tx_type": "cash_in",
                      "amount": "1000",
                      "currency": "XAF",
                      "commission_amount": 1,
                      "status": "pending",
                      "idempotency_key": "f1d6f4a0-1d4e-4a3a-9e0a-1a2b3c4d5e6f",
                      "created_at": "2026-01-31T12:00:00Z",
                      "completed_at": "2026-01-31T12:00:00Z"
                    }
                  ],
                  "pagination": {
                    "page": 1,
                    "limit": 20,
                    "total": 150,
                    "has_next": true,
                    "next_cursor": "eyJpZCI6IjEyMyJ9"
                  },
                  "meta": {
                    "request_id": "550e8400-e29b-41d4-a716-446655440000",
                    "timestamp": "2025-03-27T12:00:00Z",
                    "api_version": "4.3.0"
                  }
                }
              }
            },
            "headers": {
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/XRateLimitLimit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/XRateLimitRemaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/XRateLimitReset"
              },
              "x-fapi-interaction-id": {
                "$ref": "#/components/headers/XFapiInteractionId"
              }
            }
          },
          "429": {
            "description": "Rate limit exceeded. Retry after the interval in `Retry-After`.",
            "headers": {
              "Retry-After": {
                "schema": {
                  "type": "integer"
                },
                "description": "Seconds to wait before retrying."
              },
              "X-RateLimit-Limit": {
                "schema": {
                  "type": "integer"
                }
              },
              "X-RateLimit-Remaining": {
                "schema": {
                  "type": "integer"
                }
              },
              "X-RateLimit-Reset": {
                "schema": {
                  "type": "integer"
                }
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                },
                "examples": {
                  "rateLimited": {
                    "$ref": "#/components/examples/ErrorRateLimited"
                  }
                }
              }
            }
          }
        },
        "x-codeSamples": [
          {
            "lang": "cURL",
            "label": "cURL",
            "source": "curl -X GET \"https://api.kangopenbanking.com/v1/agents/{agentId}/transactions\" \\\n  -H \"Authorization: Bearer $KOB_ACCESS_TOKEN\" \\\n  -H \"Content-Type: application/json\""
          },
          {
            "lang": "JavaScript",
            "label": "Node.js",
            "source": "import { KangOpenBanking } from \"@kangopenbanking/sdk\";\n\nconst kob = new KangOpenBanking({ apiKey: process.env.KOB_API_KEY });\nconst res = await kob.request(\"GET\", \"/v1/agents/{agentId}/transactions\");\nconsole.log(res);"
          },
          {
            "lang": "Python",
            "label": "Python",
            "source": "from kangopenbanking import KangOpenBanking\n\nkob = KangOpenBanking(api_key=os.environ[\"KOB_API_KEY\"])\nres = kob.request(\"GET\", \"/v1/agents/{agentId}/transactions\")\nprint(res)"
          },
          {
            "lang": "PHP",
            "label": "PHP",
            "source": "<?php\n$kob = new KangOpenBanking\\KangOpenBanking(getenv('KOB_API_KEY'));\n$res = $kob->request('GET', '/v1/agents/{agentId}/transactions');\nprint_r($res);"
          }
        ]
      }
    },
    "/v1/admin/webhooks/test": {
      "post": {
        "tags": [
          "Admin"
        ],
        "summary": "Fire a signed test webhook to an existing endpoint",
        "description": "Admin-only. Generates a synthetic event, signs with HMAC-SHA256 (RFC 6920), POSTs to the endpoint URL, records the delivery row.",
        "operationId": "adminSendTestWebhook",
        "security": [
          {
            "bearerAuth": []
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/AdminTestWebhookRequest"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Delivery attempted",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/AdminTestWebhookResult"
                },
                "example": {
                  "delivery_id": "00000000-0000-4000-8000-000000000000",
                  "event_id": "string",
                  "status": "delivered",
                  "http_status": 0,
                  "latency_ms": 0,
                  "signature_header": "string",
                  "endpoint_url": "https://api.kangopenbanking.com"
                }
              }
            },
            "headers": {
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/XRateLimitLimit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/XRateLimitRemaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/XRateLimitReset"
              },
              "x-fapi-interaction-id": {
                "$ref": "#/components/headers/XFapiInteractionId"
              }
            }
          },
          "400": {
            "description": "Bad request",
            "headers": {
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/XRateLimitLimit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/XRateLimitRemaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/XRateLimitReset"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                },
                "examples": {
                  "error": {
                    "$ref": "#/components/examples/ErrorBadRequest"
                  }
                }
              }
            }
          },
          "403": {
            "description": "Admin role required",
            "headers": {
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/XRateLimitLimit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/XRateLimitRemaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/XRateLimitReset"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                },
                "examples": {
                  "error": {
                    "$ref": "#/components/examples/ErrorForbidden"
                  }
                }
              }
            }
          },
          "404": {
            "description": "Endpoint not found",
            "headers": {
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/XRateLimitLimit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/XRateLimitRemaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/XRateLimitReset"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                },
                "examples": {
                  "error": {
                    "$ref": "#/components/examples/ErrorNotFound"
                  }
                }
              }
            }
          },
          "429": {
            "description": "Rate limit exceeded. Retry after the interval in `Retry-After`.",
            "headers": {
              "Retry-After": {
                "schema": {
                  "type": "integer"
                },
                "description": "Seconds to wait before retrying."
              },
              "X-RateLimit-Limit": {
                "schema": {
                  "type": "integer"
                }
              },
              "X-RateLimit-Remaining": {
                "schema": {
                  "type": "integer"
                }
              },
              "X-RateLimit-Reset": {
                "schema": {
                  "type": "integer"
                }
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                },
                "examples": {
                  "rateLimited": {
                    "$ref": "#/components/examples/ErrorRateLimited"
                  }
                }
              }
            }
          }
        },
        "x-codeSamples": [
          {
            "lang": "cURL",
            "label": "cURL",
            "source": "curl -X POST \"https://api.kangopenbanking.com/v1/admin/webhooks/test\" \\\n  -H \"Authorization: Bearer $KOB_ACCESS_TOKEN\" \\\n  -H \"Content-Type: application/json\" \\\n  -d '{}'"
          },
          {
            "lang": "JavaScript",
            "label": "Node.js",
            "source": "import { KangOpenBanking } from \"@kangopenbanking/sdk\";\n\nconst kob = new KangOpenBanking({ apiKey: process.env.KOB_API_KEY });\nconst res = await kob.request(\"POST\", \"/v1/admin/webhooks/test\", { /* payload */ });\nconsole.log(res);"
          },
          {
            "lang": "Python",
            "label": "Python",
            "source": "from kangopenbanking import KangOpenBanking\n\nkob = KangOpenBanking(api_key=os.environ[\"KOB_API_KEY\"])\nres = kob.request(\"POST\", \"/v1/admin/webhooks/test\", json={})\nprint(res)"
          },
          {
            "lang": "PHP",
            "label": "PHP",
            "source": "<?php\n$kob = new KangOpenBanking\\KangOpenBanking(getenv('KOB_API_KEY'));\n$res = $kob->request('POST', '/v1/admin/webhooks/test', []);\nprint_r($res);"
          }
        ]
      }
    },
    "/v1/admin/api-keys": {
      "post": {
        "tags": [
          "Admin"
        ],
        "summary": "Mint a new institution API key",
        "description": "Returns plaintext key once. Cite OWASP API Top 10 2023 #2.",
        "operationId": "adminCreateApiKey",
        "security": [
          {
            "bearerAuth": []
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/AdminApiKeyCreateRequest"
              }
            }
          }
        },
        "responses": {
          "201": {
            "description": "Created",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/AdminApiKeyCreateResponse"
                },
                "example": {
                  "id": "00000000-0000-4000-8000-000000000000",
                  "key_prefix": "sk_live_a1b2",
                  "label": "string",
                  "environment": "sandbox",
                  "status": "active",
                  "created_at": "2026-01-01T00:00:00Z",
                  "suspended_at": "2026-01-01T00:00:00Z",
                  "suspended_reason": "string",
                  "api_key": "sk_live_…",
                  "shown_once": true,
                  "message": "string"
                }
              }
            },
            "headers": {
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/XRateLimitLimit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/XRateLimitRemaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/XRateLimitReset"
              },
              "x-fapi-interaction-id": {
                "$ref": "#/components/headers/XFapiInteractionId"
              }
            }
          },
          "400": {
            "description": "Bad request",
            "headers": {
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/XRateLimitLimit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/XRateLimitRemaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/XRateLimitReset"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                },
                "examples": {
                  "error": {
                    "$ref": "#/components/examples/ErrorBadRequest"
                  }
                }
              }
            }
          },
          "403": {
            "description": "Forbidden",
            "headers": {
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/XRateLimitLimit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/XRateLimitRemaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/XRateLimitReset"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                },
                "examples": {
                  "error": {
                    "$ref": "#/components/examples/ErrorForbidden"
                  }
                }
              }
            }
          },
          "429": {
            "description": "Rate limit exceeded. Retry after the interval in `Retry-After`.",
            "headers": {
              "Retry-After": {
                "schema": {
                  "type": "integer"
                },
                "description": "Seconds to wait before retrying."
              },
              "X-RateLimit-Limit": {
                "schema": {
                  "type": "integer"
                }
              },
              "X-RateLimit-Remaining": {
                "schema": {
                  "type": "integer"
                }
              },
              "X-RateLimit-Reset": {
                "schema": {
                  "type": "integer"
                }
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                },
                "examples": {
                  "rateLimited": {
                    "$ref": "#/components/examples/ErrorRateLimited"
                  }
                }
              }
            }
          }
        },
        "x-codeSamples": [
          {
            "lang": "cURL",
            "label": "cURL",
            "source": "curl -X POST \"https://api.kangopenbanking.com/v1/admin/api-keys\" \\\n  -H \"Authorization: Bearer $KOB_ACCESS_TOKEN\" \\\n  -H \"Content-Type: application/json\" \\\n  -d '{}'"
          },
          {
            "lang": "JavaScript",
            "label": "Node.js",
            "source": "import { KangOpenBanking } from \"@kangopenbanking/sdk\";\n\nconst kob = new KangOpenBanking({ apiKey: process.env.KOB_API_KEY });\nconst res = await kob.request(\"POST\", \"/v1/admin/api-keys\", { /* payload */ });\nconsole.log(res);"
          },
          {
            "lang": "Python",
            "label": "Python",
            "source": "from kangopenbanking import KangOpenBanking\n\nkob = KangOpenBanking(api_key=os.environ[\"KOB_API_KEY\"])\nres = kob.request(\"POST\", \"/v1/admin/api-keys\", json={})\nprint(res)"
          },
          {
            "lang": "PHP",
            "label": "PHP",
            "source": "<?php\n$kob = new KangOpenBanking\\KangOpenBanking(getenv('KOB_API_KEY'));\n$res = $kob->request('POST', '/v1/admin/api-keys', []);\nprint_r($res);"
          }
        ]
      }
    },
    "/v1/admin/api-keys/{id}/rotate": {
      "post": {
        "tags": [
          "Admin"
        ],
        "summary": "Rotate an API key with grace overlap",
        "operationId": "adminRotateApiKey",
        "security": [
          {
            "bearerAuth": []
          }
        ],
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/AdminApiKey"
                },
                "example": {
                  "id": "00000000-0000-4000-8000-000000000000",
                  "key_prefix": "sk_live_a1b2",
                  "label": "string",
                  "environment": "sandbox",
                  "status": "active",
                  "created_at": "2026-01-01T00:00:00Z",
                  "suspended_at": "2026-01-01T00:00:00Z",
                  "suspended_reason": "string"
                }
              }
            },
            "headers": {
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/XRateLimitLimit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/XRateLimitRemaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/XRateLimitReset"
              },
              "x-fapi-interaction-id": {
                "$ref": "#/components/headers/XFapiInteractionId"
              }
            }
          },
          "403": {
            "description": "Forbidden",
            "headers": {
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/XRateLimitLimit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/XRateLimitRemaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/XRateLimitReset"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                },
                "examples": {
                  "error": {
                    "$ref": "#/components/examples/ErrorForbidden"
                  }
                }
              }
            }
          },
          "404": {
            "description": "Not found",
            "headers": {
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/XRateLimitLimit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/XRateLimitRemaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/XRateLimitReset"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                },
                "examples": {
                  "error": {
                    "$ref": "#/components/examples/ErrorNotFound"
                  }
                }
              }
            }
          },
          "429": {
            "description": "Rate limit exceeded. Retry after the interval in `Retry-After`.",
            "headers": {
              "Retry-After": {
                "schema": {
                  "type": "integer"
                },
                "description": "Seconds to wait before retrying."
              },
              "X-RateLimit-Limit": {
                "schema": {
                  "type": "integer"
                }
              },
              "X-RateLimit-Remaining": {
                "schema": {
                  "type": "integer"
                }
              },
              "X-RateLimit-Reset": {
                "schema": {
                  "type": "integer"
                }
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                },
                "examples": {
                  "rateLimited": {
                    "$ref": "#/components/examples/ErrorRateLimited"
                  }
                }
              }
            }
          }
        },
        "x-codeSamples": [
          {
            "lang": "cURL",
            "label": "cURL",
            "source": "curl -X POST \"https://api.kangopenbanking.com/v1/admin/api-keys/{id}/rotate\" \\\n  -H \"Authorization: Bearer $KOB_ACCESS_TOKEN\" \\\n  -H \"Content-Type: application/json\""
          },
          {
            "lang": "JavaScript",
            "label": "Node.js",
            "source": "import { KangOpenBanking } from \"@kangopenbanking/sdk\";\n\nconst kob = new KangOpenBanking({ apiKey: process.env.KOB_API_KEY });\nconst res = await kob.request(\"POST\", \"/v1/admin/api-keys/{id}/rotate\");\nconsole.log(res);"
          },
          {
            "lang": "Python",
            "label": "Python",
            "source": "from kangopenbanking import KangOpenBanking\n\nkob = KangOpenBanking(api_key=os.environ[\"KOB_API_KEY\"])\nres = kob.request(\"POST\", \"/v1/admin/api-keys/{id}/rotate\")\nprint(res)"
          },
          {
            "lang": "PHP",
            "label": "PHP",
            "source": "<?php\n$kob = new KangOpenBanking\\KangOpenBanking(getenv('KOB_API_KEY'));\n$res = $kob->request('POST', '/v1/admin/api-keys/{id}/rotate');\nprint_r($res);"
          }
        ]
      }
    },
    "/v1/admin/api-keys/{id}/suspend": {
      "post": {
        "tags": [
          "Admin"
        ],
        "summary": "Suspend or resume an API key",
        "operationId": "adminSuspendApiKey",
        "security": [
          {
            "bearerAuth": []
          }
        ],
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/AdminApiKeySuspendRequest"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/AdminApiKey"
                },
                "example": {
                  "id": "00000000-0000-4000-8000-000000000000",
                  "key_prefix": "sk_live_a1b2",
                  "label": "string",
                  "environment": "sandbox",
                  "status": "active",
                  "created_at": "2026-01-01T00:00:00Z",
                  "suspended_at": "2026-01-01T00:00:00Z",
                  "suspended_reason": "string"
                }
              }
            },
            "headers": {
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/XRateLimitLimit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/XRateLimitRemaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/XRateLimitReset"
              },
              "x-fapi-interaction-id": {
                "$ref": "#/components/headers/XFapiInteractionId"
              }
            }
          },
          "403": {
            "description": "Forbidden",
            "headers": {
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/XRateLimitLimit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/XRateLimitRemaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/XRateLimitReset"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                },
                "examples": {
                  "error": {
                    "$ref": "#/components/examples/ErrorForbidden"
                  }
                }
              }
            }
          },
          "404": {
            "description": "Not found",
            "headers": {
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/XRateLimitLimit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/XRateLimitRemaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/XRateLimitReset"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                },
                "examples": {
                  "error": {
                    "$ref": "#/components/examples/ErrorNotFound"
                  }
                }
              }
            }
          },
          "429": {
            "description": "Rate limit exceeded. Retry after the interval in `Retry-After`.",
            "headers": {
              "Retry-After": {
                "schema": {
                  "type": "integer"
                },
                "description": "Seconds to wait before retrying."
              },
              "X-RateLimit-Limit": {
                "schema": {
                  "type": "integer"
                }
              },
              "X-RateLimit-Remaining": {
                "schema": {
                  "type": "integer"
                }
              },
              "X-RateLimit-Reset": {
                "schema": {
                  "type": "integer"
                }
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                },
                "examples": {
                  "rateLimited": {
                    "$ref": "#/components/examples/ErrorRateLimited"
                  }
                }
              }
            }
          }
        },
        "x-codeSamples": [
          {
            "lang": "cURL",
            "label": "cURL",
            "source": "curl -X POST \"https://api.kangopenbanking.com/v1/admin/api-keys/{id}/suspend\" \\\n  -H \"Authorization: Bearer $KOB_ACCESS_TOKEN\" \\\n  -H \"Content-Type: application/json\" \\\n  -d '{}'"
          },
          {
            "lang": "JavaScript",
            "label": "Node.js",
            "source": "import { KangOpenBanking } from \"@kangopenbanking/sdk\";\n\nconst kob = new KangOpenBanking({ apiKey: process.env.KOB_API_KEY });\nconst res = await kob.request(\"POST\", \"/v1/admin/api-keys/{id}/suspend\", { /* payload */ });\nconsole.log(res);"
          },
          {
            "lang": "Python",
            "label": "Python",
            "source": "from kangopenbanking import KangOpenBanking\n\nkob = KangOpenBanking(api_key=os.environ[\"KOB_API_KEY\"])\nres = kob.request(\"POST\", \"/v1/admin/api-keys/{id}/suspend\", json={})\nprint(res)"
          },
          {
            "lang": "PHP",
            "label": "PHP",
            "source": "<?php\n$kob = new KangOpenBanking\\KangOpenBanking(getenv('KOB_API_KEY'));\n$res = $kob->request('POST', '/v1/admin/api-keys/{id}/suspend', []);\nprint_r($res);"
          }
        ]
      }
    },
    "/v1/admin/api-keys/{id}/revoke": {
      "post": {
        "tags": [
          "Admin"
        ],
        "summary": "Revoke an API key permanently",
        "operationId": "adminRevokeApiKey",
        "security": [
          {
            "bearerAuth": []
          }
        ],
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/AdminApiKey"
                },
                "example": {
                  "id": "00000000-0000-4000-8000-000000000000",
                  "key_prefix": "sk_live_a1b2",
                  "label": "string",
                  "environment": "sandbox",
                  "status": "active",
                  "created_at": "2026-01-01T00:00:00Z",
                  "suspended_at": "2026-01-01T00:00:00Z",
                  "suspended_reason": "string"
                }
              }
            },
            "headers": {
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/XRateLimitLimit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/XRateLimitRemaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/XRateLimitReset"
              },
              "x-fapi-interaction-id": {
                "$ref": "#/components/headers/XFapiInteractionId"
              }
            }
          },
          "403": {
            "description": "Forbidden",
            "headers": {
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/XRateLimitLimit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/XRateLimitRemaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/XRateLimitReset"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                },
                "examples": {
                  "error": {
                    "$ref": "#/components/examples/ErrorForbidden"
                  }
                }
              }
            }
          },
          "404": {
            "description": "Not found",
            "headers": {
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/XRateLimitLimit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/XRateLimitRemaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/XRateLimitReset"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                },
                "examples": {
                  "error": {
                    "$ref": "#/components/examples/ErrorNotFound"
                  }
                }
              }
            }
          },
          "429": {
            "description": "Rate limit exceeded. Retry after the interval in `Retry-After`.",
            "headers": {
              "Retry-After": {
                "schema": {
                  "type": "integer"
                },
                "description": "Seconds to wait before retrying."
              },
              "X-RateLimit-Limit": {
                "schema": {
                  "type": "integer"
                }
              },
              "X-RateLimit-Remaining": {
                "schema": {
                  "type": "integer"
                }
              },
              "X-RateLimit-Reset": {
                "schema": {
                  "type": "integer"
                }
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                },
                "examples": {
                  "rateLimited": {
                    "$ref": "#/components/examples/ErrorRateLimited"
                  }
                }
              }
            }
          }
        },
        "x-codeSamples": [
          {
            "lang": "cURL",
            "label": "cURL",
            "source": "curl -X POST \"https://api.kangopenbanking.com/v1/admin/api-keys/{id}/revoke\" \\\n  -H \"Authorization: Bearer $KOB_ACCESS_TOKEN\" \\\n  -H \"Content-Type: application/json\""
          },
          {
            "lang": "JavaScript",
            "label": "Node.js",
            "source": "import { KangOpenBanking } from \"@kangopenbanking/sdk\";\n\nconst kob = new KangOpenBanking({ apiKey: process.env.KOB_API_KEY });\nconst res = await kob.request(\"POST\", \"/v1/admin/api-keys/{id}/revoke\");\nconsole.log(res);"
          },
          {
            "lang": "Python",
            "label": "Python",
            "source": "from kangopenbanking import KangOpenBanking\n\nkob = KangOpenBanking(api_key=os.environ[\"KOB_API_KEY\"])\nres = kob.request(\"POST\", \"/v1/admin/api-keys/{id}/revoke\")\nprint(res)"
          },
          {
            "lang": "PHP",
            "label": "PHP",
            "source": "<?php\n$kob = new KangOpenBanking\\KangOpenBanking(getenv('KOB_API_KEY'));\n$res = $kob->request('POST', '/v1/admin/api-keys/{id}/revoke');\nprint_r($res);"
          }
        ]
      }
    },
    "/v1/ussd/sessions": {
      "post": {
        "tags": [
          "USSD"
        ],
        "summary": "Open or advance a USSD session.",
        "operationId": "ussdSessionAdvance",
        "parameters": [
          {
            "name": "Accept-Language",
            "in": "header",
            "required": false,
            "schema": {
              "type": "string",
              "default": "en"
            },
            "description": "BCP 47 language tag (en, fr)."
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/UssdSessionRequest"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Session menu returned.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/UssdSession"
                },
                "example": {
                  "id": "00000000-0000-4000-8000-000000000000",
                  "session_id": "USSD-3f9d2c",
                  "msisdn": "+237671234567",
                  "service_code": "*144#",
                  "state": "active",
                  "menu": "1. Send Money\n2. Buy Airtime\n3. Balance",
                  "input": "string",
                  "language": "fr",
                  "created_at": "2026-01-01T00:00:00Z",
                  "ended_at": "2026-01-01T00:00:00Z"
                }
              }
            },
            "headers": {
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/XRateLimitLimit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/XRateLimitRemaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/XRateLimitReset"
              },
              "x-fapi-interaction-id": {
                "$ref": "#/components/headers/XFapiInteractionId"
              }
            }
          },
          "400": {
            "description": "Problem details (RFC 7807).",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                },
                "examples": {
                  "error": {
                    "$ref": "#/components/examples/ErrorBadRequest"
                  }
                }
              }
            },
            "headers": {
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/XRateLimitLimit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/XRateLimitRemaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/XRateLimitReset"
              }
            }
          },
          "429": {
            "description": "Problem details (RFC 7807).",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                },
                "examples": {
                  "error": {
                    "$ref": "#/components/examples/ErrorRateLimited"
                  }
                }
              }
            },
            "headers": {
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/XRateLimitLimit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/XRateLimitRemaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/XRateLimitReset"
              },
              "Retry-After": {
                "$ref": "#/components/headers/RetryAfter"
              }
            }
          }
        },
        "x-codeSamples": [
          {
            "lang": "cURL",
            "label": "cURL",
            "source": "curl -X POST \"https://api.kangopenbanking.com/v1/ussd/sessions\" \\\n  -H \"Authorization: Bearer $KOB_ACCESS_TOKEN\" \\\n  -H \"Content-Type: application/json\" \\\n  -d '{}'"
          },
          {
            "lang": "JavaScript",
            "label": "Node.js",
            "source": "import { KangOpenBanking } from \"@kangopenbanking/sdk\";\n\nconst kob = new KangOpenBanking({ apiKey: process.env.KOB_API_KEY });\nconst res = await kob.request(\"POST\", \"/v1/ussd/sessions\", { /* payload */ });\nconsole.log(res);"
          },
          {
            "lang": "Python",
            "label": "Python",
            "source": "from kangopenbanking import KangOpenBanking\n\nkob = KangOpenBanking(api_key=os.environ[\"KOB_API_KEY\"])\nres = kob.request(\"POST\", \"/v1/ussd/sessions\", json={})\nprint(res)"
          },
          {
            "lang": "PHP",
            "label": "PHP",
            "source": "<?php\n$kob = new KangOpenBanking\\KangOpenBanking(getenv('KOB_API_KEY'));\n$res = $kob->request('POST', '/v1/ussd/sessions', []);\nprint_r($res);"
          }
        ]
      }
    },
    "/v1/gateway/qr": {
      "post": {
        "tags": [
          "QR & Offline"
        ],
        "summary": "Create a merchant QR code.",
        "operationId": "qrCreate",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "required": [
                  "amount",
                  "currency",
                  "merchant_id"
                ],
                "properties": {
                  "amount": {
                    "type": "string",
                    "pattern": "^[0-9]{1,15}$"
                  },
                  "currency": {
                    "type": "string",
                    "enum": [
                      "XAF",
                      "XOF"
                    ]
                  },
                  "merchant_id": {
                    "type": "string",
                    "format": "uuid"
                  },
                  "ttl_seconds": {
                    "type": "integer",
                    "minimum": 60,
                    "maximum": 86400
                  }
                }
              }
            }
          }
        },
        "responses": {
          "201": {
            "description": "QR code created.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/QrCode"
                },
                "example": {
                  "id": "00000000-0000-4000-8000-000000000000",
                  "payload": "string",
                  "amount": "5000",
                  "currency": "XAF",
                  "merchant_id": "00000000-0000-4000-8000-000000000000",
                  "status": "active",
                  "expires_at": "2026-01-01T00:00:00Z",
                  "created_at": "2026-01-01T00:00:00Z"
                }
              }
            },
            "headers": {
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/XRateLimitLimit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/XRateLimitRemaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/XRateLimitReset"
              },
              "x-fapi-interaction-id": {
                "$ref": "#/components/headers/XFapiInteractionId"
              }
            }
          },
          "400": {
            "description": "Problem details (RFC 7807).",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                },
                "examples": {
                  "error": {
                    "$ref": "#/components/examples/ErrorBadRequest"
                  }
                }
              }
            },
            "headers": {
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/XRateLimitLimit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/XRateLimitRemaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/XRateLimitReset"
              }
            }
          },
          "429": {
            "description": "Rate limit exceeded. Retry after the interval in `Retry-After`.",
            "headers": {
              "Retry-After": {
                "schema": {
                  "type": "integer"
                },
                "description": "Seconds to wait before retrying."
              },
              "X-RateLimit-Limit": {
                "schema": {
                  "type": "integer"
                }
              },
              "X-RateLimit-Remaining": {
                "schema": {
                  "type": "integer"
                }
              },
              "X-RateLimit-Reset": {
                "schema": {
                  "type": "integer"
                }
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                },
                "examples": {
                  "rateLimited": {
                    "$ref": "#/components/examples/ErrorRateLimited"
                  }
                }
              }
            }
          }
        },
        "x-codeSamples": [
          {
            "lang": "cURL",
            "label": "cURL",
            "source": "curl -X POST \"https://api.kangopenbanking.com/v1/gateway/qr\" \\\n  -H \"Authorization: Bearer $KOB_ACCESS_TOKEN\" \\\n  -H \"Content-Type: application/json\" \\\n  -d '{}'"
          },
          {
            "lang": "JavaScript",
            "label": "Node.js",
            "source": "import { KangOpenBanking } from \"@kangopenbanking/sdk\";\n\nconst kob = new KangOpenBanking({ apiKey: process.env.KOB_API_KEY });\nconst res = await kob.request(\"POST\", \"/v1/gateway/qr\", { /* payload */ });\nconsole.log(res);"
          },
          {
            "lang": "Python",
            "label": "Python",
            "source": "from kangopenbanking import KangOpenBanking\n\nkob = KangOpenBanking(api_key=os.environ[\"KOB_API_KEY\"])\nres = kob.request(\"POST\", \"/v1/gateway/qr\", json={})\nprint(res)"
          },
          {
            "lang": "PHP",
            "label": "PHP",
            "source": "<?php\n$kob = new KangOpenBanking\\KangOpenBanking(getenv('KOB_API_KEY'));\n$res = $kob->request('POST', '/v1/gateway/qr', []);\nprint_r($res);"
          }
        ]
      }
    },
    "/v1/gateway/qr/offline/issue": {
      "post": {
        "tags": [
          "QR & Offline"
        ],
        "summary": "Issue a signed offline payment token.",
        "operationId": "qrOfflineIssue",
        "parameters": [
          {
            "name": "Idempotency-Key",
            "in": "header",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid"
            },
            "description": "RFC-compliant UUID v4 for safe retry."
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/OfflineTokenIssueRequest"
              }
            }
          }
        },
        "responses": {
          "201": {
            "description": "Offline token issued.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/OfflineToken"
                },
                "example": {
                  "token_id": "00000000-0000-4000-8000-000000000000",
                  "payer_id": "00000000-0000-4000-8000-000000000000",
                  "payee_id": "00000000-0000-4000-8000-000000000000",
                  "amount": "1000",
                  "currency": "XAF",
                  "issued_at": "2026-01-01T00:00:00Z",
                  "expires_at": "2026-01-01T00:00:00Z",
                  "signature": "string",
                  "redeemed_at": "2026-01-01T00:00:00Z"
                }
              }
            },
            "headers": {
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/XRateLimitLimit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/XRateLimitRemaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/XRateLimitReset"
              },
              "x-fapi-interaction-id": {
                "$ref": "#/components/headers/XFapiInteractionId"
              }
            }
          },
          "400": {
            "description": "Problem details (RFC 7807).",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                },
                "examples": {
                  "error": {
                    "$ref": "#/components/examples/ErrorBadRequest"
                  }
                }
              }
            },
            "headers": {
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/XRateLimitLimit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/XRateLimitRemaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/XRateLimitReset"
              }
            }
          },
          "409": {
            "description": "Problem details (RFC 7807).",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                },
                "examples": {
                  "error": {
                    "$ref": "#/components/examples/ErrorConflict"
                  }
                }
              }
            },
            "headers": {
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/XRateLimitLimit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/XRateLimitRemaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/XRateLimitReset"
              }
            }
          },
          "429": {
            "description": "Rate limit exceeded. Retry after the interval in `Retry-After`.",
            "headers": {
              "Retry-After": {
                "schema": {
                  "type": "integer"
                },
                "description": "Seconds to wait before retrying."
              },
              "X-RateLimit-Limit": {
                "schema": {
                  "type": "integer"
                }
              },
              "X-RateLimit-Remaining": {
                "schema": {
                  "type": "integer"
                }
              },
              "X-RateLimit-Reset": {
                "schema": {
                  "type": "integer"
                }
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                },
                "examples": {
                  "rateLimited": {
                    "$ref": "#/components/examples/ErrorRateLimited"
                  }
                }
              }
            }
          }
        },
        "x-codeSamples": [
          {
            "lang": "cURL",
            "label": "cURL",
            "source": "curl -X POST \"https://api.kangopenbanking.com/v1/gateway/qr/offline/issue\" \\\n  -H \"Authorization: Bearer $KOB_ACCESS_TOKEN\" \\\n  -H \"Content-Type: application/json\" \\\n  -d '{}'"
          },
          {
            "lang": "JavaScript",
            "label": "Node.js",
            "source": "import { KangOpenBanking } from \"@kangopenbanking/sdk\";\n\nconst kob = new KangOpenBanking({ apiKey: process.env.KOB_API_KEY });\nconst res = await kob.request(\"POST\", \"/v1/gateway/qr/offline/issue\", { /* payload */ });\nconsole.log(res);"
          },
          {
            "lang": "Python",
            "label": "Python",
            "source": "from kangopenbanking import KangOpenBanking\n\nkob = KangOpenBanking(api_key=os.environ[\"KOB_API_KEY\"])\nres = kob.request(\"POST\", \"/v1/gateway/qr/offline/issue\", json={})\nprint(res)"
          },
          {
            "lang": "PHP",
            "label": "PHP",
            "source": "<?php\n$kob = new KangOpenBanking\\KangOpenBanking(getenv('KOB_API_KEY'));\n$res = $kob->request('POST', '/v1/gateway/qr/offline/issue', []);\nprint_r($res);"
          }
        ]
      }
    },
    "/v1/gateway/qr/offline/redeem": {
      "post": {
        "tags": [
          "QR & Offline"
        ],
        "summary": "Redeem a signed offline payment token.",
        "operationId": "qrOfflineRedeem",
        "parameters": [
          {
            "name": "Idempotency-Key",
            "in": "header",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid"
            },
            "description": "RFC-compliant UUID v4 for safe retry."
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/OfflineTokenRedeemRequest"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Token redeemed.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/OfflineToken"
                },
                "example": {
                  "token_id": "00000000-0000-4000-8000-000000000000",
                  "payer_id": "00000000-0000-4000-8000-000000000000",
                  "payee_id": "00000000-0000-4000-8000-000000000000",
                  "amount": "1000",
                  "currency": "XAF",
                  "issued_at": "2026-01-01T00:00:00Z",
                  "expires_at": "2026-01-01T00:00:00Z",
                  "signature": "string",
                  "redeemed_at": "2026-01-01T00:00:00Z"
                }
              }
            },
            "headers": {
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/XRateLimitLimit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/XRateLimitRemaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/XRateLimitReset"
              },
              "x-fapi-interaction-id": {
                "$ref": "#/components/headers/XFapiInteractionId"
              }
            }
          },
          "400": {
            "description": "Problem details (RFC 7807).",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                },
                "examples": {
                  "error": {
                    "$ref": "#/components/examples/ErrorBadRequest"
                  }
                }
              }
            },
            "headers": {
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/XRateLimitLimit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/XRateLimitRemaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/XRateLimitReset"
              }
            }
          },
          "409": {
            "description": "Problem details (RFC 7807).",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                },
                "examples": {
                  "error": {
                    "$ref": "#/components/examples/ErrorConflict"
                  }
                }
              }
            },
            "headers": {
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/XRateLimitLimit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/XRateLimitRemaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/XRateLimitReset"
              }
            }
          },
          "410": {
            "description": "Problem details (RFC 7807).",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                },
                "examples": {
                  "error": {
                    "$ref": "#/components/examples/ErrorNotFound"
                  }
                }
              }
            },
            "headers": {
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/XRateLimitLimit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/XRateLimitRemaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/XRateLimitReset"
              }
            }
          },
          "429": {
            "description": "Rate limit exceeded. Retry after the interval in `Retry-After`.",
            "headers": {
              "Retry-After": {
                "schema": {
                  "type": "integer"
                },
                "description": "Seconds to wait before retrying."
              },
              "X-RateLimit-Limit": {
                "schema": {
                  "type": "integer"
                }
              },
              "X-RateLimit-Remaining": {
                "schema": {
                  "type": "integer"
                }
              },
              "X-RateLimit-Reset": {
                "schema": {
                  "type": "integer"
                }
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                },
                "examples": {
                  "rateLimited": {
                    "$ref": "#/components/examples/ErrorRateLimited"
                  }
                }
              }
            }
          }
        },
        "x-codeSamples": [
          {
            "lang": "cURL",
            "label": "cURL",
            "source": "curl -X POST \"https://api.kangopenbanking.com/v1/gateway/qr/offline/redeem\" \\\n  -H \"Authorization: Bearer $KOB_ACCESS_TOKEN\" \\\n  -H \"Content-Type: application/json\" \\\n  -d '{}'"
          },
          {
            "lang": "JavaScript",
            "label": "Node.js",
            "source": "import { KangOpenBanking } from \"@kangopenbanking/sdk\";\n\nconst kob = new KangOpenBanking({ apiKey: process.env.KOB_API_KEY });\nconst res = await kob.request(\"POST\", \"/v1/gateway/qr/offline/redeem\", { /* payload */ });\nconsole.log(res);"
          },
          {
            "lang": "Python",
            "label": "Python",
            "source": "from kangopenbanking import KangOpenBanking\n\nkob = KangOpenBanking(api_key=os.environ[\"KOB_API_KEY\"])\nres = kob.request(\"POST\", \"/v1/gateway/qr/offline/redeem\", json={})\nprint(res)"
          },
          {
            "lang": "PHP",
            "label": "PHP",
            "source": "<?php\n$kob = new KangOpenBanking\\KangOpenBanking(getenv('KOB_API_KEY'));\n$res = $kob->request('POST', '/v1/gateway/qr/offline/redeem', []);\nprint_r($res);"
          }
        ]
      }
    },
    "/v1/remittance/cemac/corridors": {
      "get": {
        "tags": [
          "CEMAC Remittance"
        ],
        "summary": "List active CEMAC remittance corridors.",
        "operationId": "cemacCorridorsList",
        "responses": {
          "200": {
            "description": "Corridor list.",
            "content": {
              "application/json": {
                "schema": {
                  "allOf": [
                    {
                      "$ref": "#/components/schemas/PaginatedResponse"
                    },
                    {
                      "type": "object",
                      "properties": {
                        "data": {
                          "type": "array",
                          "items": {
                            "$ref": "#/components/schemas/CemacCorridor"
                          }
                        }
                      }
                    }
                  ]
                },
                "example": {
                  "data": [
                    {
                      "origin_country": "CM",
                      "destination_country": "CM",
                      "fee_bps": 100,
                      "fx_rate": 1,
                      "status": "active"
                    }
                  ],
                  "pagination": {
                    "page": 1,
                    "limit": 20,
                    "total": 150,
                    "has_next": true,
                    "next_cursor": "eyJpZCI6IjEyMyJ9"
                  },
                  "meta": {
                    "request_id": "550e8400-e29b-41d4-a716-446655440000",
                    "timestamp": "2025-03-27T12:00:00Z",
                    "api_version": "4.3.0"
                  }
                }
              }
            },
            "headers": {
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/XRateLimitLimit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/XRateLimitRemaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/XRateLimitReset"
              },
              "x-fapi-interaction-id": {
                "$ref": "#/components/headers/XFapiInteractionId"
              }
            }
          },
          "429": {
            "description": "Rate limit exceeded. Retry after the interval in `Retry-After`.",
            "headers": {
              "Retry-After": {
                "schema": {
                  "type": "integer"
                },
                "description": "Seconds to wait before retrying."
              },
              "X-RateLimit-Limit": {
                "schema": {
                  "type": "integer"
                }
              },
              "X-RateLimit-Remaining": {
                "schema": {
                  "type": "integer"
                }
              },
              "X-RateLimit-Reset": {
                "schema": {
                  "type": "integer"
                }
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                },
                "examples": {
                  "rateLimited": {
                    "$ref": "#/components/examples/ErrorRateLimited"
                  }
                }
              }
            }
          }
        },
        "parameters": [
          {
            "name": "cursor",
            "in": "query",
            "required": false,
            "description": "Opaque, signed forward cursor returned as `pagination.next_cursor`. Cursors expire after 1800 seconds.",
            "schema": {
              "type": "string",
              "maxLength": 512
            }
          },
          {
            "name": "limit",
            "in": "query",
            "required": false,
            "description": "Maximum number of items to return (default 25, maximum 100).",
            "schema": {
              "type": "integer",
              "minimum": 1,
              "maximum": 100,
              "default": 25
            }
          }
        ],
        "x-codeSamples": [
          {
            "lang": "cURL",
            "label": "cURL",
            "source": "curl -X GET \"https://api.kangopenbanking.com/v1/remittance/cemac/corridors\" \\\n  -H \"Authorization: Bearer $KOB_ACCESS_TOKEN\" \\\n  -H \"Content-Type: application/json\""
          },
          {
            "lang": "JavaScript",
            "label": "Node.js",
            "source": "import { KangOpenBanking } from \"@kangopenbanking/sdk\";\n\nconst kob = new KangOpenBanking({ apiKey: process.env.KOB_API_KEY });\nconst res = await kob.request(\"GET\", \"/v1/remittance/cemac/corridors\");\nconsole.log(res);"
          },
          {
            "lang": "Python",
            "label": "Python",
            "source": "from kangopenbanking import KangOpenBanking\n\nkob = KangOpenBanking(api_key=os.environ[\"KOB_API_KEY\"])\nres = kob.request(\"GET\", \"/v1/remittance/cemac/corridors\")\nprint(res)"
          },
          {
            "lang": "PHP",
            "label": "PHP",
            "source": "<?php\n$kob = new KangOpenBanking\\KangOpenBanking(getenv('KOB_API_KEY'));\n$res = $kob->request('GET', '/v1/remittance/cemac/corridors');\nprint_r($res);"
          }
        ]
      }
    },
    "/v1/remittance/cemac/quote": {
      "post": {
        "tags": [
          "CEMAC Remittance"
        ],
        "summary": "Get a CEMAC remittance quote.",
        "operationId": "cemacRemittanceQuote",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/CemacRemittanceQuoteRequest"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Quote computed.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/CemacRemittanceQuote"
                },
                "example": {
                  "amount": "1000",
                  "fee": "1000",
                  "net": "1000",
                  "receive_amount": "1000",
                  "fx_rate": 0,
                  "currency": "XAF",
                  "quote_id": "00000000-0000-4000-8000-000000000000",
                  "expires_at": "2026-01-01T00:00:00Z"
                }
              }
            },
            "headers": {
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/XRateLimitLimit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/XRateLimitRemaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/XRateLimitReset"
              },
              "x-fapi-interaction-id": {
                "$ref": "#/components/headers/XFapiInteractionId"
              }
            }
          },
          "400": {
            "description": "Problem details (RFC 7807).",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                },
                "examples": {
                  "error": {
                    "$ref": "#/components/examples/ErrorBadRequest"
                  }
                }
              }
            },
            "headers": {
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/XRateLimitLimit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/XRateLimitRemaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/XRateLimitReset"
              }
            }
          },
          "429": {
            "description": "Rate limit exceeded. Retry after the interval in `Retry-After`.",
            "headers": {
              "Retry-After": {
                "schema": {
                  "type": "integer"
                },
                "description": "Seconds to wait before retrying."
              },
              "X-RateLimit-Limit": {
                "schema": {
                  "type": "integer"
                }
              },
              "X-RateLimit-Remaining": {
                "schema": {
                  "type": "integer"
                }
              },
              "X-RateLimit-Reset": {
                "schema": {
                  "type": "integer"
                }
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                },
                "examples": {
                  "rateLimited": {
                    "$ref": "#/components/examples/ErrorRateLimited"
                  }
                }
              }
            }
          }
        },
        "x-codeSamples": [
          {
            "lang": "cURL",
            "label": "cURL",
            "source": "curl -X POST \"https://api.kangopenbanking.com/v1/remittance/cemac/quote\" \\\n  -H \"Authorization: Bearer $KOB_ACCESS_TOKEN\" \\\n  -H \"Content-Type: application/json\" \\\n  -d '{}'"
          },
          {
            "lang": "JavaScript",
            "label": "Node.js",
            "source": "import { KangOpenBanking } from \"@kangopenbanking/sdk\";\n\nconst kob = new KangOpenBanking({ apiKey: process.env.KOB_API_KEY });\nconst res = await kob.request(\"POST\", \"/v1/remittance/cemac/quote\", { /* payload */ });\nconsole.log(res);"
          },
          {
            "lang": "Python",
            "label": "Python",
            "source": "from kangopenbanking import KangOpenBanking\n\nkob = KangOpenBanking(api_key=os.environ[\"KOB_API_KEY\"])\nres = kob.request(\"POST\", \"/v1/remittance/cemac/quote\", json={})\nprint(res)"
          },
          {
            "lang": "PHP",
            "label": "PHP",
            "source": "<?php\n$kob = new KangOpenBanking\\KangOpenBanking(getenv('KOB_API_KEY'));\n$res = $kob->request('POST', '/v1/remittance/cemac/quote', []);\nprint_r($res);"
          }
        ]
      }
    },
    "/v1/remittance/cemac/transfers": {
      "post": {
        "tags": [
          "CEMAC Remittance"
        ],
        "summary": "Create a CEMAC remittance transfer.",
        "operationId": "cemacRemittanceCreate",
        "parameters": [
          {
            "name": "Idempotency-Key",
            "in": "header",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid"
            },
            "description": "RFC-compliant UUID v4 for safe retry."
          },
          {
            "name": "Accept-Language",
            "in": "header",
            "required": false,
            "schema": {
              "type": "string",
              "default": "en"
            },
            "description": "BCP 47 language tag (en, fr)."
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/CemacRemittanceTransferRequest"
              }
            }
          }
        },
        "responses": {
          "201": {
            "description": "Transfer accepted.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/CemacRemittanceTransfer"
                },
                "example": {
                  "id": "00000000-0000-4000-8000-000000000000",
                  "status": "pending",
                  "amount": "1000",
                  "fee": "1000",
                  "net": "1000",
                  "origin_country": "CM",
                  "destination_country": "CM",
                  "reference": "string",
                  "created_at": "2026-01-01T00:00:00Z",
                  "settled_at": "2026-01-01T00:00:00Z"
                }
              }
            },
            "headers": {
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/XRateLimitLimit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/XRateLimitRemaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/XRateLimitReset"
              },
              "x-fapi-interaction-id": {
                "$ref": "#/components/headers/XFapiInteractionId"
              }
            }
          },
          "400": {
            "description": "Problem details (RFC 7807).",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                },
                "examples": {
                  "error": {
                    "$ref": "#/components/examples/ErrorBadRequest"
                  }
                }
              }
            },
            "headers": {
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/XRateLimitLimit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/XRateLimitRemaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/XRateLimitReset"
              }
            }
          },
          "409": {
            "description": "Problem details (RFC 7807).",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                },
                "examples": {
                  "error": {
                    "$ref": "#/components/examples/ErrorConflict"
                  }
                }
              }
            },
            "headers": {
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/XRateLimitLimit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/XRateLimitRemaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/XRateLimitReset"
              }
            }
          },
          "429": {
            "description": "Rate limit exceeded. Retry after the interval in `Retry-After`.",
            "headers": {
              "Retry-After": {
                "schema": {
                  "type": "integer"
                },
                "description": "Seconds to wait before retrying."
              },
              "X-RateLimit-Limit": {
                "schema": {
                  "type": "integer"
                }
              },
              "X-RateLimit-Remaining": {
                "schema": {
                  "type": "integer"
                }
              },
              "X-RateLimit-Reset": {
                "schema": {
                  "type": "integer"
                }
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                },
                "examples": {
                  "rateLimited": {
                    "$ref": "#/components/examples/ErrorRateLimited"
                  }
                }
              }
            }
          }
        },
        "x-codeSamples": [
          {
            "lang": "cURL",
            "label": "cURL",
            "source": "curl -X POST \"https://api.kangopenbanking.com/v1/remittance/cemac/transfers\" \\\n  -H \"Authorization: Bearer $KOB_ACCESS_TOKEN\" \\\n  -H \"Content-Type: application/json\" \\\n  -d '{}'"
          },
          {
            "lang": "JavaScript",
            "label": "Node.js",
            "source": "import { KangOpenBanking } from \"@kangopenbanking/sdk\";\n\nconst kob = new KangOpenBanking({ apiKey: process.env.KOB_API_KEY });\nconst res = await kob.request(\"POST\", \"/v1/remittance/cemac/transfers\", { /* payload */ });\nconsole.log(res);"
          },
          {
            "lang": "Python",
            "label": "Python",
            "source": "from kangopenbanking import KangOpenBanking\n\nkob = KangOpenBanking(api_key=os.environ[\"KOB_API_KEY\"])\nres = kob.request(\"POST\", \"/v1/remittance/cemac/transfers\", json={})\nprint(res)"
          },
          {
            "lang": "PHP",
            "label": "PHP",
            "source": "<?php\n$kob = new KangOpenBanking\\KangOpenBanking(getenv('KOB_API_KEY'));\n$res = $kob->request('POST', '/v1/remittance/cemac/transfers', []);\nprint_r($res);"
          }
        ]
      }
    },
    "/v1/remittance/cemac/transfers/{id}": {
      "get": {
        "tags": [
          "CEMAC Remittance"
        ],
        "summary": "Retrieve a CEMAC remittance transfer.",
        "operationId": "cemacRemittanceGet",
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Transfer detail.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/CemacRemittanceTransfer"
                },
                "example": {
                  "id": "00000000-0000-4000-8000-000000000000",
                  "status": "pending",
                  "amount": "1000",
                  "fee": "1000",
                  "net": "1000",
                  "origin_country": "CM",
                  "destination_country": "CM",
                  "reference": "string",
                  "created_at": "2026-01-01T00:00:00Z",
                  "settled_at": "2026-01-01T00:00:00Z"
                }
              }
            },
            "headers": {
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/XRateLimitLimit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/XRateLimitRemaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/XRateLimitReset"
              },
              "x-fapi-interaction-id": {
                "$ref": "#/components/headers/XFapiInteractionId"
              }
            }
          },
          "404": {
            "description": "Problem details (RFC 7807).",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                },
                "examples": {
                  "error": {
                    "$ref": "#/components/examples/ErrorNotFound"
                  }
                }
              }
            },
            "headers": {
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/XRateLimitLimit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/XRateLimitRemaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/XRateLimitReset"
              }
            }
          },
          "429": {
            "description": "Rate limit exceeded. Retry after the interval in `Retry-After`.",
            "headers": {
              "Retry-After": {
                "schema": {
                  "type": "integer"
                },
                "description": "Seconds to wait before retrying."
              },
              "X-RateLimit-Limit": {
                "schema": {
                  "type": "integer"
                }
              },
              "X-RateLimit-Remaining": {
                "schema": {
                  "type": "integer"
                }
              },
              "X-RateLimit-Reset": {
                "schema": {
                  "type": "integer"
                }
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                },
                "examples": {
                  "rateLimited": {
                    "$ref": "#/components/examples/ErrorRateLimited"
                  }
                }
              }
            }
          }
        },
        "x-codeSamples": [
          {
            "lang": "cURL",
            "label": "cURL",
            "source": "curl -X GET \"https://api.kangopenbanking.com/v1/remittance/cemac/transfers/{id}\" \\\n  -H \"Authorization: Bearer $KOB_ACCESS_TOKEN\" \\\n  -H \"Content-Type: application/json\""
          },
          {
            "lang": "JavaScript",
            "label": "Node.js",
            "source": "import { KangOpenBanking } from \"@kangopenbanking/sdk\";\n\nconst kob = new KangOpenBanking({ apiKey: process.env.KOB_API_KEY });\nconst res = await kob.request(\"GET\", \"/v1/remittance/cemac/transfers/{id}\");\nconsole.log(res);"
          },
          {
            "lang": "Python",
            "label": "Python",
            "source": "from kangopenbanking import KangOpenBanking\n\nkob = KangOpenBanking(api_key=os.environ[\"KOB_API_KEY\"])\nres = kob.request(\"GET\", \"/v1/remittance/cemac/transfers/{id}\")\nprint(res)"
          },
          {
            "lang": "PHP",
            "label": "PHP",
            "source": "<?php\n$kob = new KangOpenBanking\\KangOpenBanking(getenv('KOB_API_KEY'));\n$res = $kob->request('GET', '/v1/remittance/cemac/transfers/{id}');\nprint_r($res);"
          }
        ]
      }
    },
    "/v1/remittance/cemac/transfers/{id}/cancel": {
      "post": {
        "tags": [
          "CEMAC Remittance"
        ],
        "summary": "Cancel a pending or funded CEMAC remittance transfer.",
        "operationId": "cemacRemittanceCancel",
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          },
          {
            "name": "Idempotency-Key",
            "in": "header",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid"
            },
            "description": "RFC-compliant UUID v4 for safe retry."
          }
        ],
        "responses": {
          "200": {
            "description": "Transfer cancelled.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/CemacRemittanceTransfer"
                },
                "example": {
                  "id": "00000000-0000-4000-8000-000000000000",
                  "status": "pending",
                  "amount": "1000",
                  "fee": "1000",
                  "net": "1000",
                  "origin_country": "CM",
                  "destination_country": "CM",
                  "reference": "string",
                  "created_at": "2026-01-01T00:00:00Z",
                  "settled_at": "2026-01-01T00:00:00Z"
                }
              }
            },
            "headers": {
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/XRateLimitLimit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/XRateLimitRemaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/XRateLimitReset"
              },
              "x-fapi-interaction-id": {
                "$ref": "#/components/headers/XFapiInteractionId"
              }
            }
          },
          "404": {
            "description": "Problem details (RFC 7807).",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                },
                "examples": {
                  "error": {
                    "$ref": "#/components/examples/ErrorNotFound"
                  }
                }
              }
            },
            "headers": {
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/XRateLimitLimit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/XRateLimitRemaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/XRateLimitReset"
              }
            }
          },
          "409": {
            "description": "Problem details (RFC 7807).",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                },
                "examples": {
                  "error": {
                    "$ref": "#/components/examples/ErrorConflict"
                  }
                }
              }
            },
            "headers": {
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/XRateLimitLimit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/XRateLimitRemaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/XRateLimitReset"
              }
            }
          },
          "429": {
            "description": "Rate limit exceeded. Retry after the interval in `Retry-After`.",
            "headers": {
              "Retry-After": {
                "schema": {
                  "type": "integer"
                },
                "description": "Seconds to wait before retrying."
              },
              "X-RateLimit-Limit": {
                "schema": {
                  "type": "integer"
                }
              },
              "X-RateLimit-Remaining": {
                "schema": {
                  "type": "integer"
                }
              },
              "X-RateLimit-Reset": {
                "schema": {
                  "type": "integer"
                }
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                },
                "examples": {
                  "rateLimited": {
                    "$ref": "#/components/examples/ErrorRateLimited"
                  }
                }
              }
            }
          }
        },
        "x-codeSamples": [
          {
            "lang": "cURL",
            "label": "cURL",
            "source": "curl -X POST \"https://api.kangopenbanking.com/v1/remittance/cemac/transfers/{id}/cancel\" \\\n  -H \"Authorization: Bearer $KOB_ACCESS_TOKEN\" \\\n  -H \"Content-Type: application/json\""
          },
          {
            "lang": "JavaScript",
            "label": "Node.js",
            "source": "import { KangOpenBanking } from \"@kangopenbanking/sdk\";\n\nconst kob = new KangOpenBanking({ apiKey: process.env.KOB_API_KEY });\nconst res = await kob.request(\"POST\", \"/v1/remittance/cemac/transfers/{id}/cancel\");\nconsole.log(res);"
          },
          {
            "lang": "Python",
            "label": "Python",
            "source": "from kangopenbanking import KangOpenBanking\n\nkob = KangOpenBanking(api_key=os.environ[\"KOB_API_KEY\"])\nres = kob.request(\"POST\", \"/v1/remittance/cemac/transfers/{id}/cancel\")\nprint(res)"
          },
          {
            "lang": "PHP",
            "label": "PHP",
            "source": "<?php\n$kob = new KangOpenBanking\\KangOpenBanking(getenv('KOB_API_KEY'));\n$res = $kob->request('POST', '/v1/remittance/cemac/transfers/{id}/cancel');\nprint_r($res);"
          }
        ]
      }
    },
    "/v1/gateway/global-accounts": {
      "post": {
        "tags": [
          "Gateway"
        ],
        "summary": "Create a Nium-powered global virtual account",
        "description": "Provisions a real USD/EUR/GBP bank account for the caller via Nium. Incoming credits are converted to XAF (Nium FX + configurable spread) and routed to the user's Kang Wallet or Mobile Money. Reference: FAPI 1.0 Advanced, RFC 8259.",
        "operationId": "createGlobalAccount",
        "security": [
          {
            "bearerAuth": []
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "required": [
                  "currency"
                ],
                "properties": {
                  "currency": {
                    "type": "string",
                    "enum": [
                      "USD",
                      "EUR",
                      "GBP"
                    ]
                  },
                  "beneficiary_name": {
                    "type": "string",
                    "minLength": 1,
                    "maxLength": 140
                  }
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Existing active account returned (idempotent)",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/NiumGlobalAccount"
                },
                "example": {
                  "id": "f1d6f4a0-1d4e-4a3a-9e0a-1a2b3c4d5e6f",
                  "currency": "USD",
                  "iban": null,
                  "account_number": "912345678",
                  "routing_code": "021000021",
                  "bic": "CHASUS33",
                  "bank_name": "JPMorgan Chase (via Nium)",
                  "bank_address": "383 Madison Ave, New York, NY 10179",
                  "beneficiary_name": "Jane Influencer",
                  "status": "active",
                  "payout_preference_override": null,
                  "payout_channel_override": null,
                  "mode": "stub"
                }
              }
            },
            "headers": {
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/XRateLimitLimit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/XRateLimitRemaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/XRateLimitReset"
              },
              "x-fapi-interaction-id": {
                "$ref": "#/components/headers/XFapiInteractionId"
              }
            }
          },
          "201": {
            "description": "Account created",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/NiumGlobalAccount"
                },
                "example": {
                  "id": "f1d6f4a0-1d4e-4a3a-9e0a-1a2b3c4d5e6f",
                  "currency": "USD",
                  "iban": null,
                  "account_number": "912345678",
                  "routing_code": "021000021",
                  "bic": "CHASUS33",
                  "bank_name": "JPMorgan Chase (via Nium)",
                  "bank_address": "383 Madison Ave, New York, NY 10179",
                  "beneficiary_name": "Jane Influencer",
                  "status": "active",
                  "payout_preference_override": null,
                  "payout_channel_override": null,
                  "mode": "stub"
                }
              }
            },
            "headers": {
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/XRateLimitLimit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/XRateLimitRemaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/XRateLimitReset"
              },
              "x-fapi-interaction-id": {
                "$ref": "#/components/headers/XFapiInteractionId"
              }
            }
          },
          "400": {
            "description": "Invalid request",
            "headers": {
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/XRateLimitLimit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/XRateLimitRemaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/XRateLimitReset"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                },
                "examples": {
                  "error": {
                    "$ref": "#/components/examples/ErrorBadRequest"
                  }
                }
              }
            }
          },
          "401": {
            "description": "Unauthorized",
            "headers": {
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/XRateLimitLimit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/XRateLimitRemaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/XRateLimitReset"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                },
                "examples": {
                  "error": {
                    "$ref": "#/components/examples/ErrorUnauthorized"
                  }
                }
              }
            }
          },
          "429": {
            "description": "Rate limit exceeded. Retry after the interval in `Retry-After`.",
            "headers": {
              "Retry-After": {
                "schema": {
                  "type": "integer"
                },
                "description": "Seconds to wait before retrying."
              },
              "X-RateLimit-Limit": {
                "schema": {
                  "type": "integer"
                }
              },
              "X-RateLimit-Remaining": {
                "schema": {
                  "type": "integer"
                }
              },
              "X-RateLimit-Reset": {
                "schema": {
                  "type": "integer"
                }
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                },
                "examples": {
                  "rateLimited": {
                    "$ref": "#/components/examples/ErrorRateLimited"
                  }
                }
              }
            }
          },
          "502": {
            "description": "Nium provider error",
            "headers": {
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/XRateLimitLimit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/XRateLimitRemaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/XRateLimitReset"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                },
                "examples": {
                  "error": {
                    "$ref": "#/components/examples/ErrorServer"
                  }
                }
              }
            }
          }
        },
        "x-codeSamples": [
          {
            "lang": "cURL",
            "label": "cURL",
            "source": "curl -X POST \"https://api.kangopenbanking.com/v1/gateway/global-accounts\" \\\n  -H \"Authorization: Bearer $KOB_ACCESS_TOKEN\" \\\n  -H \"Content-Type: application/json\" \\\n  -d '{}'"
          },
          {
            "lang": "JavaScript",
            "label": "Node.js",
            "source": "import { KangOpenBanking } from \"@kangopenbanking/sdk\";\n\nconst kob = new KangOpenBanking({ apiKey: process.env.KOB_API_KEY });\nconst res = await kob.request(\"POST\", \"/v1/gateway/global-accounts\", { /* payload */ });\nconsole.log(res);"
          },
          {
            "lang": "Python",
            "label": "Python",
            "source": "from kangopenbanking import KangOpenBanking\n\nkob = KangOpenBanking(api_key=os.environ[\"KOB_API_KEY\"])\nres = kob.request(\"POST\", \"/v1/gateway/global-accounts\", json={})\nprint(res)"
          },
          {
            "lang": "PHP",
            "label": "PHP",
            "source": "<?php\n$kob = new KangOpenBanking\\KangOpenBanking(getenv('KOB_API_KEY'));\n$res = $kob->request('POST', '/v1/gateway/global-accounts', []);\nprint_r($res);"
          }
        ]
      },
      "get": {
        "tags": [
          "Gateway"
        ],
        "summary": "List global virtual accounts and recent incoming payments",
        "operationId": "listGlobalAccounts",
        "security": [
          {
            "bearerAuth": []
          }
        ],
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "accounts": {
                      "type": "array",
                      "items": {
                        "$ref": "#/components/schemas/NiumGlobalAccount"
                      }
                    },
                    "incoming_payments": {
                      "type": "array",
                      "items": {
                        "$ref": "#/components/schemas/NiumIncomingPayment"
                      }
                    },
                    "user_defaults": {
                      "$ref": "#/components/schemas/NiumPayoutPreference"
                    }
                  }
                },
                "example": {
                  "accounts": [
                    {
                      "id": "f1d6f4a0-1d4e-4a3a-9e0a-1a2b3c4d5e6f",
                      "currency": "USD",
                      "iban": null,
                      "account_number": "912345678",
                      "routing_code": "021000021",
                      "bic": "CHASUS33",
                      "bank_name": "JPMorgan Chase (via Nium)",
                      "bank_address": "383 Madison Ave, New York, NY 10179",
                      "beneficiary_name": "Jane Influencer",
                      "status": "active",
                      "payout_preference_override": null,
                      "payout_channel_override": null,
                      "mode": "stub"
                    }
                  ],
                  "incoming_payments": [
                    {
                      "id": "p_2026_03_001",
                      "source_amount": 250,
                      "source_currency": "USD",
                      "fx_rate_nium": 612.45,
                      "fx_spread_bps": 75,
                      "xaf_gross": 153112.5,
                      "xaf_spread_revenue": 1148.34,
                      "xaf_withdrawal_fee": 0,
                      "xaf_net_credited": 151964.16,
                      "routing": "KANG_WALLET",
                      "status": "credited",
                      "created_at": "2026-03-12T14:02:11Z"
                    }
                  ],
                  "user_defaults": {
                    "payout_preference": "MOBILE_MONEY",
                    "payout_channel": "237677123456"
                  }
                }
              }
            },
            "headers": {
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/XRateLimitLimit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/XRateLimitRemaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/XRateLimitReset"
              },
              "x-fapi-interaction-id": {
                "$ref": "#/components/headers/XFapiInteractionId"
              }
            }
          },
          "429": {
            "description": "Rate limit exceeded. Retry after the interval in `Retry-After`.",
            "headers": {
              "Retry-After": {
                "schema": {
                  "type": "integer"
                },
                "description": "Seconds to wait before retrying."
              },
              "X-RateLimit-Limit": {
                "schema": {
                  "type": "integer"
                }
              },
              "X-RateLimit-Remaining": {
                "schema": {
                  "type": "integer"
                }
              },
              "X-RateLimit-Reset": {
                "schema": {
                  "type": "integer"
                }
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                },
                "examples": {
                  "rateLimited": {
                    "$ref": "#/components/examples/ErrorRateLimited"
                  }
                }
              }
            }
          }
        },
        "x-codeSamples": [
          {
            "lang": "cURL",
            "label": "cURL",
            "source": "curl -X GET \"https://api.kangopenbanking.com/v1/gateway/global-accounts\" \\\n  -H \"Authorization: Bearer $KOB_ACCESS_TOKEN\" \\\n  -H \"Content-Type: application/json\""
          },
          {
            "lang": "JavaScript",
            "label": "Node.js",
            "source": "import { KangOpenBanking } from \"@kangopenbanking/sdk\";\n\nconst kob = new KangOpenBanking({ apiKey: process.env.KOB_API_KEY });\nconst res = await kob.request(\"GET\", \"/v1/gateway/global-accounts\");\nconsole.log(res);"
          },
          {
            "lang": "Python",
            "label": "Python",
            "source": "from kangopenbanking import KangOpenBanking\n\nkob = KangOpenBanking(api_key=os.environ[\"KOB_API_KEY\"])\nres = kob.request(\"GET\", \"/v1/gateway/global-accounts\")\nprint(res)"
          },
          {
            "lang": "PHP",
            "label": "PHP",
            "source": "<?php\n$kob = new KangOpenBanking\\KangOpenBanking(getenv('KOB_API_KEY'));\n$res = $kob->request('GET', '/v1/gateway/global-accounts');\nprint_r($res);"
          }
        ]
      }
    },
    "/v1/gateway/global-accounts/payout-preference": {
      "patch": {
        "tags": [
          "Gateway"
        ],
        "summary": "Update cash-out routing preference (user default or per-account override)",
        "operationId": "updateGlobalAccountPayoutPreference",
        "security": [
          {
            "bearerAuth": []
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "oneOf": [
                  {
                    "type": "object",
                    "required": [
                      "scope",
                      "payout_preference"
                    ],
                    "properties": {
                      "scope": {
                        "type": "string",
                        "enum": [
                          "user"
                        ]
                      },
                      "payout_preference": {
                        "type": "string",
                        "enum": [
                          "KANG_WALLET",
                          "MOBILE_MONEY"
                        ]
                      },
                      "payout_channel": {
                        "type": "string",
                        "description": "Phone number, required for MOBILE_MONEY"
                      }
                    }
                  },
                  {
                    "type": "object",
                    "required": [
                      "scope",
                      "account_id"
                    ],
                    "properties": {
                      "scope": {
                        "type": "string",
                        "enum": [
                          "account"
                        ]
                      },
                      "account_id": {
                        "type": "string",
                        "format": "uuid"
                      },
                      "payout_preference_override": {
                        "type": "string",
                        "nullable": true,
                        "enum": [
                          "KANG_WALLET",
                          "MOBILE_MONEY",
                          null
                        ]
                      },
                      "payout_channel_override": {
                        "type": "string",
                        "nullable": true
                      }
                    }
                  }
                ]
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Updated",
            "headers": {
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/XRateLimitLimit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/XRateLimitRemaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/XRateLimitReset"
              },
              "x-fapi-interaction-id": {
                "$ref": "#/components/headers/XFapiInteractionId"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/GenericSuccessResponse"
                },
                "example": {
                  "success": true,
                  "data": {},
                  "request_id": "string"
                }
              }
            }
          },
          "400": {
            "description": "Invalid request",
            "headers": {
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/XRateLimitLimit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/XRateLimitRemaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/XRateLimitReset"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                },
                "examples": {
                  "error": {
                    "$ref": "#/components/examples/ErrorBadRequest"
                  }
                }
              }
            }
          },
          "404": {
            "description": "Account not found",
            "headers": {
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/XRateLimitLimit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/XRateLimitRemaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/XRateLimitReset"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                },
                "examples": {
                  "error": {
                    "$ref": "#/components/examples/ErrorNotFound"
                  }
                }
              }
            }
          },
          "429": {
            "description": "Rate limit exceeded. Retry after the interval in `Retry-After`.",
            "headers": {
              "Retry-After": {
                "schema": {
                  "type": "integer"
                },
                "description": "Seconds to wait before retrying."
              },
              "X-RateLimit-Limit": {
                "schema": {
                  "type": "integer"
                }
              },
              "X-RateLimit-Remaining": {
                "schema": {
                  "type": "integer"
                }
              },
              "X-RateLimit-Reset": {
                "schema": {
                  "type": "integer"
                }
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                },
                "examples": {
                  "rateLimited": {
                    "$ref": "#/components/examples/ErrorRateLimited"
                  }
                }
              }
            }
          }
        },
        "x-codeSamples": [
          {
            "lang": "cURL",
            "label": "cURL",
            "source": "curl -X PATCH \"https://api.kangopenbanking.com/v1/gateway/global-accounts/payout-preference\" \\\n  -H \"Authorization: Bearer $KOB_ACCESS_TOKEN\" \\\n  -H \"Content-Type: application/json\" \\\n  -d '{}'"
          },
          {
            "lang": "JavaScript",
            "label": "Node.js",
            "source": "import { KangOpenBanking } from \"@kangopenbanking/sdk\";\n\nconst kob = new KangOpenBanking({ apiKey: process.env.KOB_API_KEY });\nconst res = await kob.request(\"PATCH\", \"/v1/gateway/global-accounts/payout-preference\", { /* payload */ });\nconsole.log(res);"
          },
          {
            "lang": "Python",
            "label": "Python",
            "source": "from kangopenbanking import KangOpenBanking\n\nkob = KangOpenBanking(api_key=os.environ[\"KOB_API_KEY\"])\nres = kob.request(\"PATCH\", \"/v1/gateway/global-accounts/payout-preference\", json={})\nprint(res)"
          },
          {
            "lang": "PHP",
            "label": "PHP",
            "source": "<?php\n$kob = new KangOpenBanking\\KangOpenBanking(getenv('KOB_API_KEY'));\n$res = $kob->request('PATCH', '/v1/gateway/global-accounts/payout-preference', []);\nprint_r($res);"
          }
        ]
      }
    },
    "/v1/gateway/global-accounts/webhook": {
      "post": {
        "tags": [
          "Gateway"
        ],
        "summary": "Nium incoming-payment webhook (provider → KOB)",
        "description": "Called by Nium when funds land in a global virtual account. HMAC-SHA256 signed via header `x-nium-signature`. Idempotent on `transactionId`. KOB applies FX + spread, deducts withdrawal fee (only for MOBILE_MONEY routing), credits the user's Kang Wallet, and asynchronously dispatches Mobile Money payouts through Flutterwave when applicable.",
        "operationId": "niumIncomingWebhook",
        "security": [
          {
            "NiumSignature": []
          }
        ],
        "parameters": [
          {
            "in": "header",
            "name": "x-nium-signature",
            "schema": {
              "type": "string"
            },
            "required": true
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/NiumWebhookEvent"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Acknowledged",
            "headers": {
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/XRateLimitLimit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/XRateLimitRemaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/XRateLimitReset"
              },
              "x-fapi-interaction-id": {
                "$ref": "#/components/headers/XFapiInteractionId"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/GenericSuccessResponse"
                },
                "example": {
                  "success": true,
                  "data": {},
                  "request_id": "string"
                }
              }
            }
          },
          "401": {
            "description": "Invalid signature",
            "headers": {
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/XRateLimitLimit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/XRateLimitRemaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/XRateLimitReset"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                },
                "examples": {
                  "error": {
                    "$ref": "#/components/examples/ErrorUnauthorized"
                  }
                }
              }
            }
          },
          "404": {
            "description": "Unknown account",
            "headers": {
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/XRateLimitLimit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/XRateLimitRemaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/XRateLimitReset"
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                },
                "examples": {
                  "error": {
                    "$ref": "#/components/examples/ErrorNotFound"
                  }
                }
              }
            }
          },
          "429": {
            "description": "Rate limit exceeded. Retry after the interval in `Retry-After`.",
            "headers": {
              "Retry-After": {
                "schema": {
                  "type": "integer"
                },
                "description": "Seconds to wait before retrying."
              },
              "X-RateLimit-Limit": {
                "schema": {
                  "type": "integer"
                }
              },
              "X-RateLimit-Remaining": {
                "schema": {
                  "type": "integer"
                }
              },
              "X-RateLimit-Reset": {
                "schema": {
                  "type": "integer"
                }
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                },
                "examples": {
                  "rateLimited": {
                    "$ref": "#/components/examples/ErrorRateLimited"
                  }
                }
              }
            }
          }
        },
        "x-codeSamples": [
          {
            "lang": "cURL",
            "label": "cURL",
            "source": "curl -X POST \"https://api.kangopenbanking.com/v1/gateway/global-accounts/webhook\" \\\n  -H \"Authorization: Bearer $KOB_ACCESS_TOKEN\" \\\n  -H \"Content-Type: application/json\" \\\n  -d '{}'"
          },
          {
            "lang": "JavaScript",
            "label": "Node.js",
            "source": "import { KangOpenBanking } from \"@kangopenbanking/sdk\";\n\nconst kob = new KangOpenBanking({ apiKey: process.env.KOB_API_KEY });\nconst res = await kob.request(\"POST\", \"/v1/gateway/global-accounts/webhook\", { /* payload */ });\nconsole.log(res);"
          },
          {
            "lang": "Python",
            "label": "Python",
            "source": "from kangopenbanking import KangOpenBanking\n\nkob = KangOpenBanking(api_key=os.environ[\"KOB_API_KEY\"])\nres = kob.request(\"POST\", \"/v1/gateway/global-accounts/webhook\", json={})\nprint(res)"
          },
          {
            "lang": "PHP",
            "label": "PHP",
            "source": "<?php\n$kob = new KangOpenBanking\\KangOpenBanking(getenv('KOB_API_KEY'));\n$res = $kob->request('POST', '/v1/gateway/global-accounts/webhook', []);\nprint_r($res);"
          }
        ]
      }
    },
    "/v1/webhooks/v2/endpoints/{endpointId}/deliveries/{deliveryId}/replay": {
      "post": {
        "tags": [
          "Webhooks"
        ],
        "summary": "Replay a single webhook delivery",
        "description": "Re-send the original payload of a previously attempted delivery to the same endpoint. A new delivery record is created (one-shot, no automatic retry) so the original audit trail is preserved. Useful when a downstream service was temporarily unavailable. Justification: Stripe webhook reliability parity; FAPI-1.0-Adv §6.2 (delivery accountability).",
        "operationId": "webhookV2ReplayDelivery",
        "security": [
          {
            "bearerAuth": []
          }
        ],
        "parameters": [
          {
            "name": "endpointId",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          },
          {
            "name": "deliveryId",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          },
          {
            "$ref": "#/components/parameters/IdempotencyKey"
          },
          {
            "$ref": "#/components/parameters/RequestId"
          },
          {
            "$ref": "#/components/parameters/Traceparent"
          },
          {
            "$ref": "#/components/parameters/Tracestate"
          },
          {
            "$ref": "#/components/parameters/AcceptLanguage"
          }
        ],
        "requestBody": {
          "required": false,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/WebhookReplayRequest"
              }
            }
          }
        },
        "responses": {
          "201": {
            "description": "Replay attempted; new delivery record returned",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/WebhookReplayResult"
                },
                "examples": {
                  "default": {
                    "summary": "Successful response envelope",
                    "value": {
                      "replay_delivery_id": "3f1a6b52-9c84-4d2e-8f77-1b0c5a9e4d31",
                      "original_delivery_id": "3f1a6b52-9c84-4d2e-8f77-1b0c5a9e4d31",
                      "endpoint_id": "3f1a6b52-9c84-4d2e-8f77-1b0c5a9e4d31",
                      "status": "delivered",
                      "created_at": "2026-05-02T10:15:30Z",
                      "success": true,
                      "data": {
                        "id": "obj_01HZX9TRJ4M7YQK6P3W2VBDN5K",
                        "object": "resource",
                        "created_at": "2026-05-02T10:15:30Z"
                      },
                      "meta": {
                        "request_id": "7d1f0a1c-2b4e-4f6a-9c3d-5e8f0a1b2c3d",
                        "timestamp": "2026-05-02T10:15:30Z"
                      }
                    }
                  }
                }
              }
            },
            "headers": {
              "x-fapi-interaction-id": {
                "$ref": "#/components/headers/XFapiInteractionIdResponse"
              },
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/XRateLimitLimit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/XRateLimitRemaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/XRateLimitReset"
              },
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              },
              "traceparent": {
                "$ref": "#/components/headers/Traceparent"
              },
              "Content-Language": {
                "$ref": "#/components/headers/Content-Language"
              }
            }
          },
          "400": {
            "description": "Bad request",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              },
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                },
                "examples": {
                  "default": {
                    "$ref": "#/components/examples/ErrorBadRequest"
                  }
                }
              }
            },
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/XRateLimitLimit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/XRateLimitRemaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/XRateLimitReset"
              }
            }
          },
          "401": {
            "description": "Unauthorized",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              },
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                },
                "examples": {
                  "default": {
                    "$ref": "#/components/examples/ErrorUnauthorized"
                  }
                }
              }
            },
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/XRateLimitLimit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/XRateLimitRemaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/XRateLimitReset"
              }
            }
          },
          "403": {
            "description": "Forbidden",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              },
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                },
                "examples": {
                  "default": {
                    "$ref": "#/components/examples/ErrorForbidden"
                  }
                }
              }
            },
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/XRateLimitLimit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/XRateLimitRemaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/XRateLimitReset"
              }
            }
          },
          "404": {
            "description": "Endpoint or delivery not found",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              },
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                },
                "examples": {
                  "default": {
                    "$ref": "#/components/examples/ErrorNotFound"
                  }
                }
              }
            },
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/XRateLimitLimit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/XRateLimitRemaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/XRateLimitReset"
              }
            }
          },
          "409": {
            "description": "Endpoint inactive",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              },
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                },
                "examples": {
                  "default": {
                    "$ref": "#/components/examples/ErrorConflict"
                  }
                }
              }
            },
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/XRateLimitLimit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/XRateLimitRemaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/XRateLimitReset"
              }
            }
          },
          "429": {
            "description": "Rate limit exceeded",
            "headers": {
              "Retry-After": {
                "schema": {
                  "type": "integer"
                },
                "description": "Number of seconds to wait before retrying"
              },
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/XRateLimitLimit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/XRateLimitRemaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/XRateLimitReset"
              },
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              },
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                },
                "examples": {
                  "default": {
                    "$ref": "#/components/examples/ErrorRateLimited"
                  }
                }
              }
            }
          },
          "500": {
            "description": "Internal server error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              },
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                },
                "examples": {
                  "default": {
                    "$ref": "#/components/examples/ErrorServer"
                  }
                }
              }
            },
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/XRateLimitLimit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/XRateLimitRemaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/XRateLimitReset"
              }
            }
          }
        },
        "x-codeSamples": [
          {
            "lang": "cURL",
            "label": "cURL",
            "source": "curl -X POST \"https://api.kangopenbanking.com/v1/webhooks/v2/endpoints/{endpointId}/deliveries/{deliveryId}/replay\" \\\n  -H \"Authorization: Bearer $KOB_API_KEY\" \\\n  -H \"X-Request-Id: $(uuidgen)\" \\\n  -H \"Idempotency-Key: $(uuidgen)\" \\\n  -H \"Content-Type: application/json\" \\\n  -d '{\"amount\":\"5000\",\"currency\":\"XAF\"}'"
          },
          {
            "lang": "JavaScript",
            "label": "Node.js",
            "source": "import { KangClient } from '@kangopenbanking/sdk';\n\nconst kang = new KangClient({ apiKey: process.env.KOB_API_KEY });\n\nconst response = await kang.request({\n  method: 'POST',\n  path: '/v1/webhooks/v2/endpoints/{endpointId}/deliveries/{deliveryId}/replay',\n  body: { amount: '5000', currency: 'XAF' },\n  idempotencyKey: crypto.randomUUID(),\n});\n\nconsole.log(response.data);"
          },
          {
            "lang": "Python",
            "label": "Python",
            "source": "from kangopenbanking import Kang\nimport os, uuid\n\nkang = Kang(api_key=os.environ[\"KOB_API_KEY\"])\n\nresponse = kang.request(\n    method=\"POST\",\n    path=\"/v1/webhooks/v2/endpoints/{endpointId}/deliveries/{deliveryId}/replay\",\n    body={\"amount\": \"5000\", \"currency\": \"XAF\"},\n    idempotency_key=str(uuid.uuid4()),\n)\n\nprint(response.data)"
          },
          {
            "lang": "PHP",
            "label": "PHP",
            "source": "<?php\nrequire 'vendor/autoload.php';\n\n$kang = new \\KangOpenBanking\\Client(getenv('KOB_API_KEY'));\n\n$response = $kang->request([\n    'method' => 'POST',\n    'path'   => '/v1/webhooks/v2/endpoints/{endpointId}/deliveries/{deliveryId}/replay',\n    'body'   => ['amount' => '5000', 'currency' => 'XAF'],\n    'idempotency_key' => \\Ramsey\\Uuid\\Uuid::uuid4()->toString(),\n]);\n\nprint_r($response->data);"
          }
        ]
      }
    },
    "/v1/webhooks/v2/endpoints/{endpointId}/health": {
      "get": {
        "tags": [
          "Webhooks"
        ],
        "summary": "Get webhook endpoint health snapshot",
        "description": "Return a 24-hour health snapshot for an endpoint: success rate, latency percentiles (p50/p95/p99), totals by status, and last delivery / failure timestamps. Justification: PSD2 RTS Article 32 (operational monitoring); Stripe/PayPal endpoint health parity.",
        "operationId": "webhookV2EndpointHealth",
        "security": [
          {
            "bearerAuth": []
          }
        ],
        "parameters": [
          {
            "name": "endpointId",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          },
          {
            "$ref": "#/components/parameters/RequestId"
          },
          {
            "$ref": "#/components/parameters/Traceparent"
          },
          {
            "$ref": "#/components/parameters/Tracestate"
          },
          {
            "$ref": "#/components/parameters/AcceptLanguage"
          }
        ],
        "responses": {
          "200": {
            "description": "Health snapshot",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/WebhookEndpointHealth"
                },
                "examples": {
                  "default": {
                    "summary": "Successful response envelope",
                    "value": {
                      "endpoint_id": "3f1a6b52-9c84-4d2e-8f77-1b0c5a9e4d31",
                      "url": "https://api.kangopenbanking.com/v1/resource/3f1a6b52-9c84-4d2e-8f77-1b0c5a9e4d31",
                      "is_active": true,
                      "window": "24h",
                      "health": "healthy",
                      "totals": {
                        "total": 0,
                        "delivered": 0,
                        "failed": 0,
                        "pending": 0,
                        "exhausted": 0
                      },
                      "generated_at": "2026-05-02T10:15:30Z",
                      "success": true,
                      "data": {
                        "id": "obj_01HZX9TRJ4M7YQK6P3W2VBDN5K",
                        "object": "resource",
                        "created_at": "2026-05-02T10:15:30Z"
                      },
                      "meta": {
                        "request_id": "7d1f0a1c-2b4e-4f6a-9c3d-5e8f0a1b2c3d",
                        "timestamp": "2026-05-02T10:15:30Z"
                      }
                    }
                  }
                }
              }
            },
            "headers": {
              "x-fapi-interaction-id": {
                "$ref": "#/components/headers/XFapiInteractionIdResponse"
              },
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/XRateLimitLimit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/XRateLimitRemaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/XRateLimitReset"
              },
              "Cache-Control": {
                "$ref": "#/components/headers/CacheControl"
              },
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              },
              "traceparent": {
                "$ref": "#/components/headers/Traceparent"
              },
              "Content-Language": {
                "$ref": "#/components/headers/Content-Language"
              }
            }
          },
          "400": {
            "description": "Bad request",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              },
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                },
                "examples": {
                  "default": {
                    "$ref": "#/components/examples/ErrorBadRequest"
                  }
                }
              }
            },
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/XRateLimitLimit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/XRateLimitRemaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/XRateLimitReset"
              }
            }
          },
          "401": {
            "description": "Unauthorized",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              },
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                },
                "examples": {
                  "default": {
                    "$ref": "#/components/examples/ErrorUnauthorized"
                  }
                }
              }
            },
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/XRateLimitLimit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/XRateLimitRemaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/XRateLimitReset"
              }
            }
          },
          "403": {
            "description": "Forbidden",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              },
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                },
                "examples": {
                  "default": {
                    "$ref": "#/components/examples/ErrorForbidden"
                  }
                }
              }
            },
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/XRateLimitLimit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/XRateLimitRemaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/XRateLimitReset"
              }
            }
          },
          "404": {
            "description": "Endpoint not found",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              },
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                },
                "examples": {
                  "default": {
                    "$ref": "#/components/examples/ErrorNotFound"
                  }
                }
              }
            },
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/XRateLimitLimit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/XRateLimitRemaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/XRateLimitReset"
              }
            }
          },
          "429": {
            "description": "Rate limit exceeded",
            "headers": {
              "Retry-After": {
                "schema": {
                  "type": "integer"
                }
              },
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/XRateLimitLimit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/XRateLimitRemaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/XRateLimitReset"
              },
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              },
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                },
                "examples": {
                  "default": {
                    "$ref": "#/components/examples/ErrorRateLimited"
                  }
                }
              }
            }
          },
          "500": {
            "description": "Internal server error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              },
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                },
                "examples": {
                  "default": {
                    "$ref": "#/components/examples/ErrorServer"
                  }
                }
              }
            },
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/XRateLimitLimit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/XRateLimitRemaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/XRateLimitReset"
              }
            }
          }
        },
        "x-codeSamples": [
          {
            "lang": "cURL",
            "label": "cURL",
            "source": "curl -X GET \"https://api.kangopenbanking.com/v1/webhooks/v2/endpoints/{endpointId}/health\" \\\n  -H \"Authorization: Bearer $KOB_API_KEY\" \\\n  -H \"X-Request-Id: $(uuidgen)\""
          },
          {
            "lang": "JavaScript",
            "label": "Node.js",
            "source": "import { KangClient } from '@kangopenbanking/sdk';\n\nconst kang = new KangClient({ apiKey: process.env.KOB_API_KEY });\n\nconst response = await kang.request({\n  method: 'GET',\n  path: '/v1/webhooks/v2/endpoints/{endpointId}/health',\n});\n\nconsole.log(response.data);"
          },
          {
            "lang": "Python",
            "label": "Python",
            "source": "from kangopenbanking import Kang\nimport os, uuid\n\nkang = Kang(api_key=os.environ[\"KOB_API_KEY\"])\n\nresponse = kang.request(\n    method=\"GET\",\n    path=\"/v1/webhooks/v2/endpoints/{endpointId}/health\",\n)\n\nprint(response.data)"
          },
          {
            "lang": "PHP",
            "label": "PHP",
            "source": "<?php\nrequire 'vendor/autoload.php';\n\n$kang = new \\KangOpenBanking\\Client(getenv('KOB_API_KEY'));\n\n$response = $kang->request([\n    'method' => 'GET',\n    'path'   => '/v1/webhooks/v2/endpoints/{endpointId}/health',\n]);\n\nprint_r($response->data);"
          }
        ]
      }
    },
    "/v1/consents/{consentId}/status": {
      "get": {
        "tags": [
          "Consent Management"
        ],
        "summary": "Get consent status",
        "description": "Returns current status, scopes and recent audit events for a consent. Status values: AwaitingAuthorisation, Authorised, Rejected, Revoked, Expired, Consumed. Justification: PSD2 RTS Article 5(1)(a).",
        "operationId": "getConsentStatus",
        "security": [
          {
            "bearerAuth": []
          }
        ],
        "parameters": [
          {
            "name": "consentId",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          },
          {
            "$ref": "#/components/parameters/RequestId"
          },
          {
            "$ref": "#/components/parameters/Traceparent"
          },
          {
            "$ref": "#/components/parameters/Tracestate"
          },
          {
            "$ref": "#/components/parameters/AcceptLanguage"
          }
        ],
        "responses": {
          "200": {
            "description": "Consent status",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "consentId": {
                      "type": "string",
                      "format": "uuid"
                    },
                    "status": {
                      "type": "string",
                      "enum": [
                        "AwaitingAuthorisation",
                        "Authorised",
                        "Rejected",
                        "Revoked",
                        "Expired",
                        "Consumed"
                      ]
                    },
                    "statusUpdateDateTime": {
                      "type": "string",
                      "format": "date-time"
                    },
                    "scopes": {
                      "type": "array",
                      "items": {
                        "type": "string"
                      }
                    },
                    "events": {
                      "type": "array",
                      "items": {
                        "type": "object",
                        "properties": {
                          "event": {
                            "type": "string"
                          },
                          "at": {
                            "type": "string",
                            "format": "date-time"
                          }
                        }
                      }
                    }
                  }
                },
                "examples": {
                  "default": {
                    "$ref": "#/components/examples/PaginatedList"
                  }
                }
              }
            },
            "headers": {
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/XRateLimitLimit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/XRateLimitRemaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/XRateLimitReset"
              },
              "x-fapi-interaction-id": {
                "$ref": "#/components/headers/XFapiInteractionId"
              },
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              },
              "traceparent": {
                "$ref": "#/components/headers/Traceparent"
              },
              "Content-Language": {
                "$ref": "#/components/headers/Content-Language"
              }
            }
          },
          "400": {
            "description": "400 Bad Request — the request failed validation.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                },
                "example": {
                  "type": "https://api.kangopenbanking.com/v1/errors/validation-error",
                  "title": "Validation Error",
                  "status": 400
                }
              },
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                },
                "example": {
                  "type": "https://api.kangopenbanking.com/v1/errors/validation-error",
                  "title": "Validation Error",
                  "status": 400
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "404": {
            "$ref": "#/components/responses/NotFound",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "429": {
            "$ref": "#/components/responses/TooManyRequests",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "500": {
            "description": "500 Internal Server Error — an unexpected condition prevented completion.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                },
                "example": {
                  "type": "https://api.kangopenbanking.com/v1/errors/internal-error",
                  "title": "Internal Server Error",
                  "status": 500
                }
              },
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                },
                "example": {
                  "type": "https://api.kangopenbanking.com/v1/errors/internal-error",
                  "title": "Internal Server Error",
                  "status": 500
                }
              }
            }
          },
          "default": {
            "description": "Server error — see ProblemDetails for trace ID.",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            },
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/XRateLimitLimit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/XRateLimitRemaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/XRateLimitReset"
              }
            }
          }
        },
        "x-codeSamples": [
          {
            "lang": "cURL",
            "label": "cURL",
            "source": "curl -X GET \"https://api.kangopenbanking.com/v1/consents/{consentId}/status\" \\\n  -H \"Authorization: Bearer $KOB_API_KEY\" \\\n  -H \"X-Request-Id: $(uuidgen)\""
          },
          {
            "lang": "JavaScript",
            "label": "Node.js",
            "source": "import { KangClient } from '@kangopenbanking/sdk';\n\nconst kang = new KangClient({ apiKey: process.env.KOB_API_KEY });\n\nconst response = await kang.request({\n  method: 'GET',\n  path: '/v1/consents/{consentId}/status',\n});\n\nconsole.log(response.data);"
          },
          {
            "lang": "Python",
            "label": "Python",
            "source": "from kangopenbanking import Kang\nimport os, uuid\n\nkang = Kang(api_key=os.environ[\"KOB_API_KEY\"])\n\nresponse = kang.request(\n    method=\"GET\",\n    path=\"/v1/consents/{consentId}/status\",\n)\n\nprint(response.data)"
          },
          {
            "lang": "PHP",
            "label": "PHP",
            "source": "<?php\nrequire 'vendor/autoload.php';\n\n$kang = new \\KangOpenBanking\\Client(getenv('KOB_API_KEY'));\n\n$response = $kang->request([\n    'method' => 'GET',\n    'path'   => '/v1/consents/{consentId}/status',\n]);\n\nprint_r($response->data);"
          }
        ]
      }
    },
    "/v1/certificates/{certificateId}": {
      "get": {
        "tags": [
          "Certificates"
        ],
        "summary": "Get a certificate by ID",
        "description": "Returns metadata for a registered TPP certificate (subject DN, fingerprint, expiry, status). Justification: eIDAS / FAPI 1.0 Advanced §5.2.2.",
        "operationId": "getCertificate",
        "security": [
          {
            "bearerAuth": []
          }
        ],
        "parameters": [
          {
            "name": "certificateId",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          },
          {
            "$ref": "#/components/parameters/RequestId"
          },
          {
            "$ref": "#/components/parameters/Traceparent"
          },
          {
            "$ref": "#/components/parameters/Tracestate"
          },
          {
            "$ref": "#/components/parameters/AcceptLanguage"
          }
        ],
        "responses": {
          "200": {
            "description": "Certificate metadata",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "id": {
                      "type": "string",
                      "format": "uuid"
                    },
                    "subject": {
                      "type": "string"
                    },
                    "issuer": {
                      "type": "string"
                    },
                    "thumbprint_sha256": {
                      "type": "string"
                    },
                    "not_before": {
                      "type": "string",
                      "format": "date-time"
                    },
                    "not_after": {
                      "type": "string",
                      "format": "date-time"
                    },
                    "status": {
                      "type": "string",
                      "enum": [
                        "active",
                        "revoked",
                        "expired"
                      ]
                    }
                  }
                },
                "examples": {
                  "default": {
                    "$ref": "#/components/examples/GenericSuccess"
                  }
                }
              }
            },
            "headers": {
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/XRateLimitLimit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/XRateLimitRemaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/XRateLimitReset"
              },
              "x-fapi-interaction-id": {
                "$ref": "#/components/headers/XFapiInteractionId"
              },
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              },
              "traceparent": {
                "$ref": "#/components/headers/Traceparent"
              },
              "Content-Language": {
                "$ref": "#/components/headers/Content-Language"
              }
            }
          },
          "400": {
            "description": "400 Bad Request — the request failed validation.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                },
                "example": {
                  "type": "https://api.kangopenbanking.com/v1/errors/validation-error",
                  "title": "Validation Error",
                  "status": 400
                }
              },
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                },
                "example": {
                  "type": "https://api.kangopenbanking.com/v1/errors/validation-error",
                  "title": "Validation Error",
                  "status": 400
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "404": {
            "$ref": "#/components/responses/NotFound",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "429": {
            "$ref": "#/components/responses/TooManyRequests",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "500": {
            "description": "500 Internal Server Error — an unexpected condition prevented completion.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                },
                "example": {
                  "type": "https://api.kangopenbanking.com/v1/errors/internal-error",
                  "title": "Internal Server Error",
                  "status": 500
                }
              },
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                },
                "example": {
                  "type": "https://api.kangopenbanking.com/v1/errors/internal-error",
                  "title": "Internal Server Error",
                  "status": 500
                }
              }
            }
          },
          "default": {
            "description": "Server error — see ProblemDetails for trace ID.",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            },
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/XRateLimitLimit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/XRateLimitRemaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/XRateLimitReset"
              }
            }
          }
        },
        "x-codeSamples": [
          {
            "lang": "cURL",
            "label": "cURL",
            "source": "curl -X GET \"https://api.kangopenbanking.com/v1/certificates/{certificateId}\" \\\n  -H \"Authorization: Bearer $KOB_API_KEY\" \\\n  -H \"X-Request-Id: $(uuidgen)\""
          },
          {
            "lang": "JavaScript",
            "label": "Node.js",
            "source": "import { KangClient } from '@kangopenbanking/sdk';\n\nconst kang = new KangClient({ apiKey: process.env.KOB_API_KEY });\n\nconst response = await kang.request({\n  method: 'GET',\n  path: '/v1/certificates/{certificateId}',\n});\n\nconsole.log(response.data);"
          },
          {
            "lang": "Python",
            "label": "Python",
            "source": "from kangopenbanking import Kang\nimport os, uuid\n\nkang = Kang(api_key=os.environ[\"KOB_API_KEY\"])\n\nresponse = kang.request(\n    method=\"GET\",\n    path=\"/v1/certificates/{certificateId}\",\n)\n\nprint(response.data)"
          },
          {
            "lang": "PHP",
            "label": "PHP",
            "source": "<?php\nrequire 'vendor/autoload.php';\n\n$kang = new \\KangOpenBanking\\Client(getenv('KOB_API_KEY'));\n\n$response = $kang->request([\n    'method' => 'GET',\n    'path'   => '/v1/certificates/{certificateId}',\n]);\n\nprint_r($response->data);"
          }
        ]
      }
    },
    "/v1/oauth/register": {
      "post": {
        "tags": [
          "OAuth"
        ],
        "summary": "Dynamic Client Registration (RFC 7591)",
        "description": "Registers a new OAuth2/OIDC client using a signed Software Statement Assertion (SSA) JWT. Justification: RFC 7591, FAPI-CIBA §5.",
        "operationId": "oauthDynamicClientRegister",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "required": [
                  "software_statement",
                  "redirect_uris"
                ],
                "properties": {
                  "software_statement": {
                    "type": "string",
                    "description": "Signed SSA JWT issued by the regulator/operator."
                  },
                  "redirect_uris": {
                    "type": "array",
                    "items": {
                      "type": "string",
                      "format": "uri"
                    }
                  },
                  "token_endpoint_auth_method": {
                    "type": "string",
                    "enum": [
                      "tls_client_auth",
                      "private_key_jwt"
                    ]
                  },
                  "grant_types": {
                    "type": "array",
                    "items": {
                      "type": "string"
                    }
                  },
                  "response_types": {
                    "type": "array",
                    "items": {
                      "type": "string"
                    }
                  },
                  "scope": {
                    "type": "string"
                  }
                }
              }
            }
          }
        },
        "responses": {
          "201": {
            "description": "Client registered",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "client_id": {
                      "type": "string"
                    },
                    "client_id_issued_at": {
                      "type": "integer"
                    },
                    "client_secret_expires_at": {
                      "type": "integer",
                      "example": 0
                    },
                    "registration_access_token": {
                      "type": "string"
                    },
                    "registration_client_uri": {
                      "type": "string",
                      "format": "uri"
                    }
                  }
                },
                "examples": {
                  "default": {
                    "$ref": "#/components/examples/GenericSuccess"
                  }
                }
              }
            },
            "headers": {
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/XRateLimitLimit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/XRateLimitRemaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/XRateLimitReset"
              },
              "x-fapi-interaction-id": {
                "$ref": "#/components/headers/XFapiInteractionId"
              },
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              },
              "traceparent": {
                "$ref": "#/components/headers/Traceparent"
              },
              "Content-Language": {
                "$ref": "#/components/headers/Content-Language"
              }
            }
          },
          "400": {
            "description": "Invalid software statement",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                },
                "example": {
                  "type": "https://api.kangopenbanking.com/v1/errors/validation-error",
                  "title": "Validation Error",
                  "status": 400
                }
              },
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                },
                "example": {
                  "type": "https://api.kangopenbanking.com/v1/errors/validation-error",
                  "title": "Validation Error",
                  "status": 400
                }
              }
            },
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/XRateLimitLimit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/XRateLimitRemaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/XRateLimitReset"
              }
            }
          },
          "401": {
            "description": "Software statement signature invalid",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                },
                "example": {
                  "type": "https://api.kangopenbanking.com/v1/errors/unauthorized",
                  "title": "Unauthorized",
                  "status": 401
                }
              },
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                },
                "example": {
                  "type": "https://api.kangopenbanking.com/v1/errors/unauthorized",
                  "title": "Unauthorized",
                  "status": 401
                }
              }
            },
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/XRateLimitLimit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/XRateLimitRemaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/XRateLimitReset"
              }
            }
          },
          "409": {
            "$ref": "#/components/responses/Conflict",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "429": {
            "$ref": "#/components/responses/TooManyRequests",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "500": {
            "description": "500 Internal Server Error — an unexpected condition prevented completion.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                },
                "example": {
                  "type": "https://api.kangopenbanking.com/v1/errors/internal-error",
                  "title": "Internal Server Error",
                  "status": 500
                }
              },
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                },
                "example": {
                  "type": "https://api.kangopenbanking.com/v1/errors/internal-error",
                  "title": "Internal Server Error",
                  "status": 500
                }
              }
            }
          },
          "default": {
            "description": "Server error — see ProblemDetails for trace ID.",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            },
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/XRateLimitLimit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/XRateLimitRemaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/XRateLimitReset"
              }
            }
          }
        },
        "x-codeSamples": [
          {
            "lang": "cURL",
            "label": "cURL",
            "source": "curl -X POST \"https://api.kangopenbanking.com/v1/oauth/register\" \\\n  -H \"Authorization: Bearer $KOB_API_KEY\" \\\n  -H \"X-Request-Id: $(uuidgen)\" \\\n  -H \"Idempotency-Key: $(uuidgen)\" \\\n  -H \"Content-Type: application/json\" \\\n  -d '{\"amount\":\"5000\",\"currency\":\"XAF\"}'"
          },
          {
            "lang": "JavaScript",
            "label": "Node.js",
            "source": "import { KangClient } from '@kangopenbanking/sdk';\n\nconst kang = new KangClient({ apiKey: process.env.KOB_API_KEY });\n\nconst response = await kang.request({\n  method: 'POST',\n  path: '/v1/oauth/register',\n  body: { amount: '5000', currency: 'XAF' },\n  idempotencyKey: crypto.randomUUID(),\n});\n\nconsole.log(response.data);"
          },
          {
            "lang": "Python",
            "label": "Python",
            "source": "from kangopenbanking import Kang\nimport os, uuid\n\nkang = Kang(api_key=os.environ[\"KOB_API_KEY\"])\n\nresponse = kang.request(\n    method=\"POST\",\n    path=\"/v1/oauth/register\",\n    body={\"amount\": \"5000\", \"currency\": \"XAF\"},\n    idempotency_key=str(uuid.uuid4()),\n)\n\nprint(response.data)"
          },
          {
            "lang": "PHP",
            "label": "PHP",
            "source": "<?php\nrequire 'vendor/autoload.php';\n\n$kang = new \\KangOpenBanking\\Client(getenv('KOB_API_KEY'));\n\n$response = $kang->request([\n    'method' => 'POST',\n    'path'   => '/v1/oauth/register',\n    'body'   => ['amount' => '5000', 'currency' => 'XAF'],\n    'idempotency_key' => \\Ramsey\\Uuid\\Uuid::uuid4()->toString(),\n]);\n\nprint_r($response->data);"
          }
        ],
        "parameters": [
          {
            "$ref": "#/components/parameters/RequestId"
          },
          {
            "$ref": "#/components/parameters/Traceparent"
          },
          {
            "$ref": "#/components/parameters/Tracestate"
          },
          {
            "$ref": "#/components/parameters/AcceptLanguage"
          }
        ]
      }
    },
    "/v1/.well-known/jwks.json": {
      "get": {
        "tags": [
          "OAuth"
        ],
        "summary": "JWKS (well-known alias)",
        "description": "Alias for `/v1/jwks` advertised by OIDC discovery. Returns the JSON Web Key Set used to verify ID tokens and signed request objects. Justification: RFC 8414 §3.\n\n**Key selection:** select the verification key whose `kid` matches the JWT header `kid`; treat `kid` as an opaque string and refresh this document when an unknown `kid` is seen. The signing-key lifecycle derives `kid` as an RFC 7638 JWK thumbprint; key rotation is pending certification, so do not pin a single key.",
        "operationId": "getJwksWellKnown",
        "responses": {
          "200": {
            "description": "JWKS",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "keys": {
                      "type": "array",
                      "items": {
                        "type": "object"
                      }
                    }
                  }
                },
                "examples": {
                  "default": {
                    "$ref": "#/components/examples/GenericSuccess"
                  }
                }
              }
            },
            "headers": {
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/XRateLimitLimit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/XRateLimitRemaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/XRateLimitReset"
              },
              "x-fapi-interaction-id": {
                "$ref": "#/components/headers/XFapiInteractionId"
              },
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              },
              "traceparent": {
                "$ref": "#/components/headers/Traceparent"
              },
              "Content-Language": {
                "$ref": "#/components/headers/Content-Language"
              }
            }
          },
          "400": {
            "description": "400 Bad Request — the request failed validation.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                },
                "example": {
                  "type": "https://api.kangopenbanking.com/v1/errors/validation-error",
                  "title": "Validation Error",
                  "status": 400
                }
              },
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                },
                "example": {
                  "type": "https://api.kangopenbanking.com/v1/errors/validation-error",
                  "title": "Validation Error",
                  "status": 400
                }
              }
            }
          },
          "401": {
            "description": "401 Unauthorized — credentials are missing, expired or invalid.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                },
                "example": {
                  "type": "https://api.kangopenbanking.com/v1/errors/unauthorized",
                  "title": "Unauthorized",
                  "status": 401
                }
              },
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                },
                "example": {
                  "type": "https://api.kangopenbanking.com/v1/errors/unauthorized",
                  "title": "Unauthorized",
                  "status": 401
                }
              }
            }
          },
          "429": {
            "$ref": "#/components/responses/TooManyRequests",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "500": {
            "description": "500 Internal Server Error — an unexpected condition prevented completion.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                },
                "example": {
                  "type": "https://api.kangopenbanking.com/v1/errors/internal-error",
                  "title": "Internal Server Error",
                  "status": 500
                }
              },
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                },
                "example": {
                  "type": "https://api.kangopenbanking.com/v1/errors/internal-error",
                  "title": "Internal Server Error",
                  "status": 500
                }
              }
            }
          },
          "default": {
            "description": "Server error — see ProblemDetails for trace ID.",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            },
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/XRateLimitLimit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/XRateLimitRemaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/XRateLimitReset"
              }
            }
          }
        },
        "x-codeSamples": [
          {
            "lang": "cURL",
            "label": "cURL",
            "source": "curl -X GET \"https://api.kangopenbanking.com/v1/.well-known/jwks.json\" \\\n  -H \"Authorization: Bearer $KOB_API_KEY\" \\\n  -H \"X-Request-Id: $(uuidgen)\""
          },
          {
            "lang": "JavaScript",
            "label": "Node.js",
            "source": "import { KangClient } from '@kangopenbanking/sdk';\n\nconst kang = new KangClient({ apiKey: process.env.KOB_API_KEY });\n\nconst response = await kang.request({\n  method: 'GET',\n  path: '/v1/.well-known/jwks.json',\n});\n\nconsole.log(response.data);"
          },
          {
            "lang": "Python",
            "label": "Python",
            "source": "from kangopenbanking import Kang\nimport os, uuid\n\nkang = Kang(api_key=os.environ[\"KOB_API_KEY\"])\n\nresponse = kang.request(\n    method=\"GET\",\n    path=\"/v1/.well-known/jwks.json\",\n)\n\nprint(response.data)"
          },
          {
            "lang": "PHP",
            "label": "PHP",
            "source": "<?php\nrequire 'vendor/autoload.php';\n\n$kang = new \\KangOpenBanking\\Client(getenv('KOB_API_KEY'));\n\n$response = $kang->request([\n    'method' => 'GET',\n    'path'   => '/v1/.well-known/jwks.json',\n]);\n\nprint_r($response->data);"
          }
        ],
        "x-public-endpoint": true,
        "parameters": [
          {
            "$ref": "#/components/parameters/RequestId"
          },
          {
            "$ref": "#/components/parameters/Traceparent"
          },
          {
            "$ref": "#/components/parameters/Tracestate"
          },
          {
            "$ref": "#/components/parameters/AcceptLanguage"
          }
        ]
      }
    },
    "/v1/userinfo": {
      "get": {
        "tags": [
          "OAuth"
        ],
        "summary": "UserInfo (OIDC alias)",
        "description": "Alias for `/v1/oauth/userinfo` advertised by OIDC discovery. Returns claims about the authenticated end-user. Justification: OpenID Connect Core §5.3.",
        "operationId": "getUserInfoAlias",
        "security": [
          {
            "bearerAuth": []
          }
        ],
        "responses": {
          "200": {
            "description": "UserInfo claims",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "additionalProperties": true
                },
                "examples": {
                  "default": {
                    "$ref": "#/components/examples/GenericSuccess"
                  }
                }
              }
            },
            "headers": {
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/XRateLimitLimit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/XRateLimitRemaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/XRateLimitReset"
              },
              "x-fapi-interaction-id": {
                "$ref": "#/components/headers/XFapiInteractionId"
              },
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              },
              "traceparent": {
                "$ref": "#/components/headers/Traceparent"
              },
              "Content-Language": {
                "$ref": "#/components/headers/Content-Language"
              }
            }
          },
          "400": {
            "description": "400 Bad Request — the request failed validation.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                },
                "example": {
                  "type": "https://api.kangopenbanking.com/v1/errors/validation-error",
                  "title": "Validation Error",
                  "status": 400
                }
              },
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                },
                "example": {
                  "type": "https://api.kangopenbanking.com/v1/errors/validation-error",
                  "title": "Validation Error",
                  "status": 400
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "429": {
            "$ref": "#/components/responses/TooManyRequests",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "500": {
            "description": "500 Internal Server Error — an unexpected condition prevented completion.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                },
                "example": {
                  "type": "https://api.kangopenbanking.com/v1/errors/internal-error",
                  "title": "Internal Server Error",
                  "status": 500
                }
              },
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                },
                "example": {
                  "type": "https://api.kangopenbanking.com/v1/errors/internal-error",
                  "title": "Internal Server Error",
                  "status": 500
                }
              }
            }
          },
          "default": {
            "description": "Server error — see ProblemDetails for trace ID.",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            },
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/XRateLimitLimit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/XRateLimitRemaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/XRateLimitReset"
              }
            }
          }
        },
        "x-codeSamples": [
          {
            "lang": "cURL",
            "label": "cURL",
            "source": "curl -X GET \"https://api.kangopenbanking.com/v1/userinfo\" \\\n  -H \"Authorization: Bearer $KOB_API_KEY\" \\\n  -H \"X-Request-Id: $(uuidgen)\""
          },
          {
            "lang": "JavaScript",
            "label": "Node.js",
            "source": "import { KangClient } from '@kangopenbanking/sdk';\n\nconst kang = new KangClient({ apiKey: process.env.KOB_API_KEY });\n\nconst response = await kang.request({\n  method: 'GET',\n  path: '/v1/userinfo',\n});\n\nconsole.log(response.data);"
          },
          {
            "lang": "Python",
            "label": "Python",
            "source": "from kangopenbanking import Kang\nimport os, uuid\n\nkang = Kang(api_key=os.environ[\"KOB_API_KEY\"])\n\nresponse = kang.request(\n    method=\"GET\",\n    path=\"/v1/userinfo\",\n)\n\nprint(response.data)"
          },
          {
            "lang": "PHP",
            "label": "PHP",
            "source": "<?php\nrequire 'vendor/autoload.php';\n\n$kang = new \\KangOpenBanking\\Client(getenv('KOB_API_KEY'));\n\n$response = $kang->request([\n    'method' => 'GET',\n    'path'   => '/v1/userinfo',\n]);\n\nprint_r($response->data);"
          }
        ],
        "parameters": [
          {
            "$ref": "#/components/parameters/RequestId"
          },
          {
            "$ref": "#/components/parameters/Traceparent"
          },
          {
            "$ref": "#/components/parameters/Tracestate"
          },
          {
            "$ref": "#/components/parameters/AcceptLanguage"
          }
        ]
      }
    },
    "/v1/banks/{bankId}/connector/files/upload": {
      "post": {
        "tags": [
          "BankConnectors"
        ],
        "summary": "Upload bank data file",
        "operationId": "connectorFileUpload",
        "description": "Manually upload a CSV/XML file containing accounts, balances, transactions, beneficiaries, payment_instructions, payment_status, or statement data. Justification: PSD2 RTS Article 36 (alternative interface), ISO 20022 camt/pain semantics. File-based connector replaces missing bank API.",
        "security": [
          {
            "bearerAuth": []
          },
          {
            "oauth2": [
              "banking:write"
            ]
          }
        ],
        "parameters": [
          {
            "name": "bankId",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          },
          {
            "$ref": "#/components/parameters/RequestId"
          },
          {
            "$ref": "#/components/parameters/Traceparent"
          },
          {
            "$ref": "#/components/parameters/Tracestate"
          },
          {
            "$ref": "#/components/parameters/AcceptLanguage"
          }
        ],
        "responses": {
          "200": {
            "description": "Success",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                },
                "examples": {
                  "default": {
                    "$ref": "#/components/examples/GenericSuccess"
                  }
                }
              }
            },
            "headers": {
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/XRateLimitLimit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/XRateLimitRemaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/XRateLimitReset"
              },
              "x-fapi-interaction-id": {
                "$ref": "#/components/headers/XFapiInteractionId"
              },
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              },
              "traceparent": {
                "$ref": "#/components/headers/Traceparent"
              },
              "Content-Language": {
                "$ref": "#/components/headers/Content-Language"
              }
            }
          },
          "400": {
            "description": "Bad Request",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                },
                "example": {
                  "type": "https://api.kangopenbanking.com/v1/errors/validation-error",
                  "title": "Validation Error",
                  "status": 400
                }
              },
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                },
                "example": {
                  "type": "https://api.kangopenbanking.com/v1/errors/validation-error",
                  "title": "Validation Error",
                  "status": 400
                }
              }
            },
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/XRateLimitLimit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/XRateLimitRemaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/XRateLimitReset"
              }
            }
          },
          "401": {
            "description": "Unauthorized",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                },
                "example": {
                  "type": "https://api.kangopenbanking.com/v1/errors/unauthorized",
                  "title": "Unauthorized",
                  "status": 401
                }
              },
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                },
                "example": {
                  "type": "https://api.kangopenbanking.com/v1/errors/unauthorized",
                  "title": "Unauthorized",
                  "status": 401
                }
              }
            },
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/XRateLimitLimit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/XRateLimitRemaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/XRateLimitReset"
              }
            }
          },
          "403": {
            "description": "Forbidden",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                },
                "examples": {
                  "error": {
                    "$ref": "#/components/examples/ErrorForbidden"
                  }
                }
              },
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            },
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/XRateLimitLimit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/XRateLimitRemaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/XRateLimitReset"
              }
            }
          },
          "404": {
            "description": "Not Found",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                },
                "examples": {
                  "error": {
                    "$ref": "#/components/examples/ErrorNotFound"
                  }
                }
              },
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            },
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/XRateLimitLimit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/XRateLimitRemaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/XRateLimitReset"
              }
            }
          },
          "409": {
            "$ref": "#/components/responses/Conflict",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "429": {
            "$ref": "#/components/responses/TooManyRequests",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "500": {
            "description": "500 Internal Server Error — an unexpected condition prevented completion.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                },
                "example": {
                  "type": "https://api.kangopenbanking.com/v1/errors/internal-error",
                  "title": "Internal Server Error",
                  "status": 500
                }
              },
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                },
                "example": {
                  "type": "https://api.kangopenbanking.com/v1/errors/internal-error",
                  "title": "Internal Server Error",
                  "status": 500
                }
              }
            }
          },
          "default": {
            "description": "Server error — see ProblemDetails for trace ID.",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            },
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/XRateLimitLimit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/XRateLimitRemaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/XRateLimitReset"
              }
            }
          }
        },
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "required": [
                  "file_type",
                  "file_base64",
                  "filename"
                ],
                "properties": {
                  "file_type": {
                    "type": "string",
                    "enum": [
                      "accounts",
                      "balances",
                      "transactions",
                      "beneficiaries",
                      "payment_instructions",
                      "payment_status",
                      "statement"
                    ]
                  },
                  "filename": {
                    "type": "string",
                    "maxLength": 255
                  },
                  "file_base64": {
                    "type": "string",
                    "description": "Base64-encoded file content"
                  },
                  "environment": {
                    "type": "string",
                    "enum": [
                      "sandbox",
                      "prod"
                    ],
                    "default": "sandbox"
                  }
                }
              }
            }
          }
        },
        "x-codeSamples": [
          {
            "lang": "cURL",
            "label": "cURL",
            "source": "curl -X POST \"https://api.kangopenbanking.com/v1/banks/{bankId}/connector/files/upload\" \\\n  -H \"Authorization: Bearer $KOB_API_KEY\" \\\n  -H \"X-Request-Id: $(uuidgen)\" \\\n  -H \"Idempotency-Key: $(uuidgen)\" \\\n  -H \"Content-Type: application/json\" \\\n  -d '{\"amount\":\"5000\",\"currency\":\"XAF\"}'"
          },
          {
            "lang": "JavaScript",
            "label": "Node.js",
            "source": "import { KangClient } from '@kangopenbanking/sdk';\n\nconst kang = new KangClient({ apiKey: process.env.KOB_API_KEY });\n\nconst response = await kang.request({\n  method: 'POST',\n  path: '/v1/banks/{bankId}/connector/files/upload',\n  body: { amount: '5000', currency: 'XAF' },\n  idempotencyKey: crypto.randomUUID(),\n});\n\nconsole.log(response.data);"
          },
          {
            "lang": "Python",
            "label": "Python",
            "source": "from kangopenbanking import Kang\nimport os, uuid\n\nkang = Kang(api_key=os.environ[\"KOB_API_KEY\"])\n\nresponse = kang.request(\n    method=\"POST\",\n    path=\"/v1/banks/{bankId}/connector/files/upload\",\n    body={\"amount\": \"5000\", \"currency\": \"XAF\"},\n    idempotency_key=str(uuid.uuid4()),\n)\n\nprint(response.data)"
          },
          {
            "lang": "PHP",
            "label": "PHP",
            "source": "<?php\nrequire 'vendor/autoload.php';\n\n$kang = new \\KangOpenBanking\\Client(getenv('KOB_API_KEY'));\n\n$response = $kang->request([\n    'method' => 'POST',\n    'path'   => '/v1/banks/{bankId}/connector/files/upload',\n    'body'   => ['amount' => '5000', 'currency' => 'XAF'],\n    'idempotency_key' => \\Ramsey\\Uuid\\Uuid::uuid4()->toString(),\n]);\n\nprint_r($response->data);"
          }
        ]
      }
    },
    "/v1/banks/{bankId}/connector/sftp/config": {
      "post": {
        "tags": [
          "BankConnectors"
        ],
        "summary": "Configure SFTP connector",
        "operationId": "connectorSftpConfig",
        "description": "Register or update SFTP credentials and remote folders for scheduled file pulls. Credentials are encrypted at rest. Justification: PSD2 RTS contingency interface.",
        "security": [
          {
            "bearerAuth": []
          },
          {
            "oauth2": [
              "banking:write"
            ]
          }
        ],
        "parameters": [
          {
            "name": "bankId",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          },
          {
            "$ref": "#/components/parameters/RequestId"
          },
          {
            "$ref": "#/components/parameters/Traceparent"
          },
          {
            "$ref": "#/components/parameters/Tracestate"
          },
          {
            "$ref": "#/components/parameters/AcceptLanguage"
          }
        ],
        "responses": {
          "200": {
            "description": "Success",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                },
                "examples": {
                  "default": {
                    "$ref": "#/components/examples/GenericSuccess"
                  }
                }
              }
            },
            "headers": {
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/XRateLimitLimit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/XRateLimitRemaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/XRateLimitReset"
              },
              "x-fapi-interaction-id": {
                "$ref": "#/components/headers/XFapiInteractionId"
              },
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              },
              "traceparent": {
                "$ref": "#/components/headers/Traceparent"
              },
              "Content-Language": {
                "$ref": "#/components/headers/Content-Language"
              }
            }
          },
          "400": {
            "description": "Bad Request",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                },
                "example": {
                  "type": "https://api.kangopenbanking.com/v1/errors/validation-error",
                  "title": "Validation Error",
                  "status": 400
                }
              },
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                },
                "example": {
                  "type": "https://api.kangopenbanking.com/v1/errors/validation-error",
                  "title": "Validation Error",
                  "status": 400
                }
              }
            },
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/XRateLimitLimit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/XRateLimitRemaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/XRateLimitReset"
              }
            }
          },
          "401": {
            "description": "Unauthorized",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                },
                "example": {
                  "type": "https://api.kangopenbanking.com/v1/errors/unauthorized",
                  "title": "Unauthorized",
                  "status": 401
                }
              },
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                },
                "example": {
                  "type": "https://api.kangopenbanking.com/v1/errors/unauthorized",
                  "title": "Unauthorized",
                  "status": 401
                }
              }
            },
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/XRateLimitLimit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/XRateLimitRemaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/XRateLimitReset"
              }
            }
          },
          "403": {
            "description": "Forbidden",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                },
                "examples": {
                  "error": {
                    "$ref": "#/components/examples/ErrorForbidden"
                  }
                }
              },
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            },
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/XRateLimitLimit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/XRateLimitRemaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/XRateLimitReset"
              }
            }
          },
          "404": {
            "description": "Not Found",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                },
                "examples": {
                  "error": {
                    "$ref": "#/components/examples/ErrorNotFound"
                  }
                }
              },
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            },
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/XRateLimitLimit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/XRateLimitRemaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/XRateLimitReset"
              }
            }
          },
          "409": {
            "$ref": "#/components/responses/Conflict",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "429": {
            "$ref": "#/components/responses/TooManyRequests",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "500": {
            "description": "500 Internal Server Error — an unexpected condition prevented completion.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                },
                "example": {
                  "type": "https://api.kangopenbanking.com/v1/errors/internal-error",
                  "title": "Internal Server Error",
                  "status": 500
                }
              },
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                },
                "example": {
                  "type": "https://api.kangopenbanking.com/v1/errors/internal-error",
                  "title": "Internal Server Error",
                  "status": 500
                }
              }
            }
          },
          "default": {
            "description": "Server error — see ProblemDetails for trace ID.",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            },
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/XRateLimitLimit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/XRateLimitRemaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/XRateLimitReset"
              }
            }
          }
        },
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "required": [
                  "host",
                  "port",
                  "username",
                  "remote_folder"
                ],
                "properties": {
                  "host": {
                    "type": "string"
                  },
                  "port": {
                    "type": "integer",
                    "minimum": 1,
                    "maximum": 65535,
                    "default": 22
                  },
                  "username": {
                    "type": "string"
                  },
                  "private_key_pem": {
                    "type": "string",
                    "description": "PEM-encoded SSH private key (write-only)"
                  },
                  "password": {
                    "type": "string",
                    "description": "Optional password (write-only)"
                  },
                  "remote_folder": {
                    "type": "string"
                  },
                  "polling_interval_seconds": {
                    "type": "integer",
                    "minimum": 60,
                    "default": 300
                  },
                  "enabled": {
                    "type": "boolean",
                    "default": false
                  },
                  "environment": {
                    "type": "string",
                    "enum": [
                      "sandbox",
                      "prod"
                    ],
                    "default": "sandbox"
                  }
                }
              }
            }
          }
        },
        "x-codeSamples": [
          {
            "lang": "cURL",
            "label": "cURL",
            "source": "curl -X POST \"https://api.kangopenbanking.com/v1/banks/{bankId}/connector/sftp/config\" \\\n  -H \"Authorization: Bearer $KOB_API_KEY\" \\\n  -H \"X-Request-Id: $(uuidgen)\" \\\n  -H \"Idempotency-Key: $(uuidgen)\" \\\n  -H \"Content-Type: application/json\" \\\n  -d '{\"amount\":\"5000\",\"currency\":\"XAF\"}'"
          },
          {
            "lang": "JavaScript",
            "label": "Node.js",
            "source": "import { KangClient } from '@kangopenbanking/sdk';\n\nconst kang = new KangClient({ apiKey: process.env.KOB_API_KEY });\n\nconst response = await kang.request({\n  method: 'POST',\n  path: '/v1/banks/{bankId}/connector/sftp/config',\n  body: { amount: '5000', currency: 'XAF' },\n  idempotencyKey: crypto.randomUUID(),\n});\n\nconsole.log(response.data);"
          },
          {
            "lang": "Python",
            "label": "Python",
            "source": "from kangopenbanking import Kang\nimport os, uuid\n\nkang = Kang(api_key=os.environ[\"KOB_API_KEY\"])\n\nresponse = kang.request(\n    method=\"POST\",\n    path=\"/v1/banks/{bankId}/connector/sftp/config\",\n    body={\"amount\": \"5000\", \"currency\": \"XAF\"},\n    idempotency_key=str(uuid.uuid4()),\n)\n\nprint(response.data)"
          },
          {
            "lang": "PHP",
            "label": "PHP",
            "source": "<?php\nrequire 'vendor/autoload.php';\n\n$kang = new \\KangOpenBanking\\Client(getenv('KOB_API_KEY'));\n\n$response = $kang->request([\n    'method' => 'POST',\n    'path'   => '/v1/banks/{bankId}/connector/sftp/config',\n    'body'   => ['amount' => '5000', 'currency' => 'XAF'],\n    'idempotency_key' => \\Ramsey\\Uuid\\Uuid::uuid4()->toString(),\n]);\n\nprint_r($response->data);"
          }
        ]
      }
    },
    "/v1/banks/{bankId}/connector/sftp/pull": {
      "post": {
        "tags": [
          "BankConnectors"
        ],
        "summary": "Trigger SFTP pull now",
        "operationId": "connectorSftpPullNow",
        "description": "Trigger an immediate SFTP pull cycle for the bank. Returns run identifier; ingestion runs asynchronously.",
        "security": [
          {
            "bearerAuth": []
          },
          {
            "oauth2": [
              "banking:write"
            ]
          }
        ],
        "parameters": [
          {
            "name": "bankId",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          },
          {
            "$ref": "#/components/parameters/RequestId"
          },
          {
            "$ref": "#/components/parameters/Traceparent"
          },
          {
            "$ref": "#/components/parameters/Tracestate"
          },
          {
            "$ref": "#/components/parameters/AcceptLanguage"
          }
        ],
        "responses": {
          "200": {
            "description": "Success",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                },
                "examples": {
                  "default": {
                    "$ref": "#/components/examples/GenericSuccess"
                  }
                }
              }
            },
            "headers": {
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/XRateLimitLimit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/XRateLimitRemaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/XRateLimitReset"
              },
              "x-fapi-interaction-id": {
                "$ref": "#/components/headers/XFapiInteractionId"
              },
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              },
              "traceparent": {
                "$ref": "#/components/headers/Traceparent"
              },
              "Content-Language": {
                "$ref": "#/components/headers/Content-Language"
              }
            }
          },
          "400": {
            "description": "Bad Request",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                },
                "example": {
                  "type": "https://api.kangopenbanking.com/v1/errors/validation-error",
                  "title": "Validation Error",
                  "status": 400
                }
              },
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                },
                "example": {
                  "type": "https://api.kangopenbanking.com/v1/errors/validation-error",
                  "title": "Validation Error",
                  "status": 400
                }
              }
            },
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/XRateLimitLimit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/XRateLimitRemaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/XRateLimitReset"
              }
            }
          },
          "401": {
            "description": "Unauthorized",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                },
                "example": {
                  "type": "https://api.kangopenbanking.com/v1/errors/unauthorized",
                  "title": "Unauthorized",
                  "status": 401
                }
              },
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                },
                "example": {
                  "type": "https://api.kangopenbanking.com/v1/errors/unauthorized",
                  "title": "Unauthorized",
                  "status": 401
                }
              }
            },
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/XRateLimitLimit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/XRateLimitRemaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/XRateLimitReset"
              }
            }
          },
          "403": {
            "description": "Forbidden",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                },
                "examples": {
                  "error": {
                    "$ref": "#/components/examples/ErrorForbidden"
                  }
                }
              },
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            },
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/XRateLimitLimit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/XRateLimitRemaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/XRateLimitReset"
              }
            }
          },
          "404": {
            "description": "Not Found",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                },
                "examples": {
                  "error": {
                    "$ref": "#/components/examples/ErrorNotFound"
                  }
                }
              },
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            },
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/XRateLimitLimit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/XRateLimitRemaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/XRateLimitReset"
              }
            }
          },
          "409": {
            "$ref": "#/components/responses/Conflict",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "429": {
            "$ref": "#/components/responses/TooManyRequests",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "500": {
            "description": "500 Internal Server Error — an unexpected condition prevented completion.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                },
                "example": {
                  "type": "https://api.kangopenbanking.com/v1/errors/internal-error",
                  "title": "Internal Server Error",
                  "status": 500
                }
              },
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                },
                "example": {
                  "type": "https://api.kangopenbanking.com/v1/errors/internal-error",
                  "title": "Internal Server Error",
                  "status": 500
                }
              }
            }
          },
          "default": {
            "description": "Server error — see ProblemDetails for trace ID.",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            },
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/XRateLimitLimit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/XRateLimitRemaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/XRateLimitReset"
              }
            }
          }
        },
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "environment": {
                    "type": "string",
                    "enum": [
                      "sandbox",
                      "prod"
                    ],
                    "default": "sandbox"
                  }
                }
              }
            }
          }
        },
        "x-codeSamples": [
          {
            "lang": "cURL",
            "label": "cURL",
            "source": "curl -X POST \"https://api.kangopenbanking.com/v1/banks/{bankId}/connector/sftp/pull\" \\\n  -H \"Authorization: Bearer $KOB_API_KEY\" \\\n  -H \"X-Request-Id: $(uuidgen)\" \\\n  -H \"Idempotency-Key: $(uuidgen)\" \\\n  -H \"Content-Type: application/json\" \\\n  -d '{\"amount\":\"5000\",\"currency\":\"XAF\"}'"
          },
          {
            "lang": "JavaScript",
            "label": "Node.js",
            "source": "import { KangClient } from '@kangopenbanking/sdk';\n\nconst kang = new KangClient({ apiKey: process.env.KOB_API_KEY });\n\nconst response = await kang.request({\n  method: 'POST',\n  path: '/v1/banks/{bankId}/connector/sftp/pull',\n  body: { amount: '5000', currency: 'XAF' },\n  idempotencyKey: crypto.randomUUID(),\n});\n\nconsole.log(response.data);"
          },
          {
            "lang": "Python",
            "label": "Python",
            "source": "from kangopenbanking import Kang\nimport os, uuid\n\nkang = Kang(api_key=os.environ[\"KOB_API_KEY\"])\n\nresponse = kang.request(\n    method=\"POST\",\n    path=\"/v1/banks/{bankId}/connector/sftp/pull\",\n    body={\"amount\": \"5000\", \"currency\": \"XAF\"},\n    idempotency_key=str(uuid.uuid4()),\n)\n\nprint(response.data)"
          },
          {
            "lang": "PHP",
            "label": "PHP",
            "source": "<?php\nrequire 'vendor/autoload.php';\n\n$kang = new \\KangOpenBanking\\Client(getenv('KOB_API_KEY'));\n\n$response = $kang->request([\n    'method' => 'POST',\n    'path'   => '/v1/banks/{bankId}/connector/sftp/pull',\n    'body'   => ['amount' => '5000', 'currency' => 'XAF'],\n    'idempotency_key' => \\Ramsey\\Uuid\\Uuid::uuid4()->toString(),\n]);\n\nprint_r($response->data);"
          }
        ]
      }
    },
    "/v1/banks/{bankId}/connector/imports": {
      "get": {
        "tags": [
          "BankConnectors"
        ],
        "summary": "List file imports",
        "operationId": "connectorImportsList",
        "description": "List historical file uploads / SFTP pulls with status, dedupe hash, and error summaries.",
        "security": [
          {
            "bearerAuth": []
          },
          {
            "oauth2": [
              "banking:write"
            ]
          }
        ],
        "parameters": [
          {
            "name": "bankId",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          },
          {
            "name": "limit",
            "in": "query",
            "schema": {
              "type": "integer",
              "minimum": 1,
              "maximum": 200,
              "default": 50
            }
          },
          {
            "name": "offset",
            "in": "query",
            "schema": {
              "type": "integer",
              "minimum": 0,
              "default": 0
            }
          },
          {
            "name": "file_type",
            "in": "query",
            "schema": {
              "type": "string",
              "enum": [
                "accounts",
                "balances",
                "transactions",
                "beneficiaries",
                "payment_instructions",
                "payment_status",
                "statement"
              ]
            }
          },
          {
            "name": "status",
            "in": "query",
            "schema": {
              "type": "string",
              "enum": [
                "received",
                "validating",
                "processed",
                "failed"
              ]
            }
          },
          {
            "$ref": "#/components/parameters/StartingAfter"
          },
          {
            "$ref": "#/components/parameters/EndingBefore"
          },
          {
            "$ref": "#/components/parameters/RequestId"
          },
          {
            "$ref": "#/components/parameters/Traceparent"
          },
          {
            "$ref": "#/components/parameters/Tracestate"
          },
          {
            "$ref": "#/components/parameters/AcceptLanguage"
          }
        ],
        "responses": {
          "200": {
            "description": "Success",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                },
                "examples": {
                  "default": {
                    "$ref": "#/components/examples/PaginatedList"
                  }
                }
              }
            },
            "headers": {
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/XRateLimitLimit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/XRateLimitRemaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/XRateLimitReset"
              },
              "x-fapi-interaction-id": {
                "$ref": "#/components/headers/XFapiInteractionId"
              },
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              },
              "traceparent": {
                "$ref": "#/components/headers/Traceparent"
              },
              "Content-Language": {
                "$ref": "#/components/headers/Content-Language"
              }
            }
          },
          "400": {
            "description": "Bad Request",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                },
                "example": {
                  "type": "https://api.kangopenbanking.com/v1/errors/validation-error",
                  "title": "Validation Error",
                  "status": 400
                }
              },
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                },
                "example": {
                  "type": "https://api.kangopenbanking.com/v1/errors/validation-error",
                  "title": "Validation Error",
                  "status": 400
                }
              }
            },
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/XRateLimitLimit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/XRateLimitRemaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/XRateLimitReset"
              }
            }
          },
          "401": {
            "description": "Unauthorized",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                },
                "example": {
                  "type": "https://api.kangopenbanking.com/v1/errors/unauthorized",
                  "title": "Unauthorized",
                  "status": 401
                }
              },
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                },
                "example": {
                  "type": "https://api.kangopenbanking.com/v1/errors/unauthorized",
                  "title": "Unauthorized",
                  "status": 401
                }
              }
            },
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/XRateLimitLimit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/XRateLimitRemaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/XRateLimitReset"
              }
            }
          },
          "403": {
            "description": "Forbidden",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                },
                "examples": {
                  "error": {
                    "$ref": "#/components/examples/ErrorForbidden"
                  }
                }
              },
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            },
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/XRateLimitLimit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/XRateLimitRemaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/XRateLimitReset"
              }
            }
          },
          "404": {
            "description": "Not Found",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                },
                "examples": {
                  "error": {
                    "$ref": "#/components/examples/ErrorNotFound"
                  }
                }
              },
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            },
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/XRateLimitLimit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/XRateLimitRemaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/XRateLimitReset"
              }
            }
          },
          "429": {
            "$ref": "#/components/responses/TooManyRequests",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "500": {
            "description": "500 Internal Server Error — an unexpected condition prevented completion.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                },
                "example": {
                  "type": "https://api.kangopenbanking.com/v1/errors/internal-error",
                  "title": "Internal Server Error",
                  "status": 500
                }
              },
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                },
                "example": {
                  "type": "https://api.kangopenbanking.com/v1/errors/internal-error",
                  "title": "Internal Server Error",
                  "status": 500
                }
              }
            }
          },
          "default": {
            "description": "Server error — see ProblemDetails for trace ID.",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            },
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/XRateLimitLimit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/XRateLimitRemaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/XRateLimitReset"
              }
            }
          }
        },
        "x-codeSamples": [
          {
            "lang": "cURL",
            "label": "cURL",
            "source": "curl -X GET \"https://api.kangopenbanking.com/v1/banks/{bankId}/connector/imports\" \\\n  -H \"Authorization: Bearer $KOB_API_KEY\" \\\n  -H \"X-Request-Id: $(uuidgen)\""
          },
          {
            "lang": "JavaScript",
            "label": "Node.js",
            "source": "import { KangClient } from '@kangopenbanking/sdk';\n\nconst kang = new KangClient({ apiKey: process.env.KOB_API_KEY });\n\nconst response = await kang.request({\n  method: 'GET',\n  path: '/v1/banks/{bankId}/connector/imports',\n});\n\nconsole.log(response.data);"
          },
          {
            "lang": "Python",
            "label": "Python",
            "source": "from kangopenbanking import Kang\nimport os, uuid\n\nkang = Kang(api_key=os.environ[\"KOB_API_KEY\"])\n\nresponse = kang.request(\n    method=\"GET\",\n    path=\"/v1/banks/{bankId}/connector/imports\",\n)\n\nprint(response.data)"
          },
          {
            "lang": "PHP",
            "label": "PHP",
            "source": "<?php\nrequire 'vendor/autoload.php';\n\n$kang = new \\KangOpenBanking\\Client(getenv('KOB_API_KEY'));\n\n$response = $kang->request([\n    'method' => 'GET',\n    'path'   => '/v1/banks/{bankId}/connector/imports',\n]);\n\nprint_r($response->data);"
          }
        ]
      }
    },
    "/v1/banks/{bankId}/connector/imports/{importId}": {
      "get": {
        "tags": [
          "BankConnectors"
        ],
        "summary": "Get file import detail",
        "operationId": "connectorImportGet",
        "description": "Retrieve a single import including line-level errors, dedupe hash, and ingestion outcome.",
        "security": [
          {
            "bearerAuth": []
          },
          {
            "oauth2": [
              "banking:read"
            ]
          }
        ],
        "parameters": [
          {
            "name": "bankId",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          },
          {
            "name": "importId",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          },
          {
            "$ref": "#/components/parameters/RequestId"
          },
          {
            "$ref": "#/components/parameters/Traceparent"
          },
          {
            "$ref": "#/components/parameters/Tracestate"
          },
          {
            "$ref": "#/components/parameters/AcceptLanguage"
          }
        ],
        "responses": {
          "200": {
            "description": "Import detail",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                },
                "examples": {
                  "default": {
                    "$ref": "#/components/examples/GenericSuccess"
                  }
                }
              }
            },
            "headers": {
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/XRateLimitLimit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/XRateLimitRemaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/XRateLimitReset"
              },
              "x-fapi-interaction-id": {
                "$ref": "#/components/headers/XFapiInteractionId"
              },
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              },
              "traceparent": {
                "$ref": "#/components/headers/Traceparent"
              },
              "Content-Language": {
                "$ref": "#/components/headers/Content-Language"
              }
            }
          },
          "400": {
            "description": "400 Bad Request — the request failed validation.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                },
                "example": {
                  "type": "https://api.kangopenbanking.com/v1/errors/validation-error",
                  "title": "Validation Error",
                  "status": 400
                }
              },
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                },
                "example": {
                  "type": "https://api.kangopenbanking.com/v1/errors/validation-error",
                  "title": "Validation Error",
                  "status": 400
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "404": {
            "description": "Not Found",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                },
                "examples": {
                  "error": {
                    "$ref": "#/components/examples/ErrorNotFound"
                  }
                }
              },
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            },
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/XRateLimitLimit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/XRateLimitRemaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/XRateLimitReset"
              }
            }
          },
          "429": {
            "$ref": "#/components/responses/TooManyRequests",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "500": {
            "description": "500 Internal Server Error — an unexpected condition prevented completion.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                },
                "example": {
                  "type": "https://api.kangopenbanking.com/v1/errors/internal-error",
                  "title": "Internal Server Error",
                  "status": 500
                }
              },
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                },
                "example": {
                  "type": "https://api.kangopenbanking.com/v1/errors/internal-error",
                  "title": "Internal Server Error",
                  "status": 500
                }
              }
            }
          },
          "default": {
            "description": "Server error — see ProblemDetails for trace ID.",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            },
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/XRateLimitLimit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/XRateLimitRemaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/XRateLimitReset"
              }
            }
          }
        },
        "x-codeSamples": [
          {
            "lang": "cURL",
            "label": "cURL",
            "source": "curl -X GET \"https://api.kangopenbanking.com/v1/banks/{bankId}/connector/imports/{importId}\" \\\n  -H \"Authorization: Bearer $KOB_API_KEY\" \\\n  -H \"X-Request-Id: $(uuidgen)\""
          },
          {
            "lang": "JavaScript",
            "label": "Node.js",
            "source": "import { KangClient } from '@kangopenbanking/sdk';\n\nconst kang = new KangClient({ apiKey: process.env.KOB_API_KEY });\n\nconst response = await kang.request({\n  method: 'GET',\n  path: '/v1/banks/{bankId}/connector/imports/{importId}',\n});\n\nconsole.log(response.data);"
          },
          {
            "lang": "Python",
            "label": "Python",
            "source": "from kangopenbanking import Kang\nimport os, uuid\n\nkang = Kang(api_key=os.environ[\"KOB_API_KEY\"])\n\nresponse = kang.request(\n    method=\"GET\",\n    path=\"/v1/banks/{bankId}/connector/imports/{importId}\",\n)\n\nprint(response.data)"
          },
          {
            "lang": "PHP",
            "label": "PHP",
            "source": "<?php\nrequire 'vendor/autoload.php';\n\n$kang = new \\KangOpenBanking\\Client(getenv('KOB_API_KEY'));\n\n$response = $kang->request([\n    'method' => 'GET',\n    'path'   => '/v1/banks/{bankId}/connector/imports/{importId}',\n]);\n\nprint_r($response->data);"
          }
        ]
      }
    },
    "/v1/banks/{bankId}/connector/mappings": {
      "get": {
        "tags": [
          "BankConnectors"
        ],
        "summary": "List CSV/file mapping templates",
        "operationId": "connectorMappingsList",
        "description": "List CSV/file mapping templates.\n\n**Tag:** BankConnectors\n\nAuthenticate with a bearer token issued by `/v1/oauth/token`. All state-changing requests\n(POST, PUT, PATCH, DELETE) MUST include an `Idempotency-Key` header (UUID v4) to make\nretries safe — Kang will return the original response for any duplicate key within 24 hours.\n\nErrors follow [RFC 7807](https://datatracker.ietf.org/doc/html/rfc7807) and are returned with\n`Content-Type: application/problem+json`. The `code` field is stable and machine-readable.\nRate-limit headers (`X-RateLimit-Limit`, `X-RateLimit-Remaining`, `X-RateLimit-Reset`)\nare present on every response.",
        "security": [
          {
            "bearerAuth": []
          },
          {
            "oauth2": [
              "banking:write"
            ]
          }
        ],
        "parameters": [
          {
            "name": "bankId",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          },
          {
            "name": "file_type",
            "in": "query",
            "schema": {
              "type": "string"
            }
          },
          {
            "$ref": "#/components/parameters/RequestId"
          },
          {
            "$ref": "#/components/parameters/Traceparent"
          },
          {
            "$ref": "#/components/parameters/Tracestate"
          },
          {
            "$ref": "#/components/parameters/AcceptLanguage"
          },
          {
            "$ref": "#/components/parameters/LimitParam"
          },
          {
            "$ref": "#/components/parameters/CursorParam"
          }
        ],
        "responses": {
          "200": {
            "description": "Success",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                },
                "examples": {
                  "default": {
                    "$ref": "#/components/examples/PaginatedList"
                  }
                }
              }
            },
            "headers": {
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/XRateLimitLimit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/XRateLimitRemaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/XRateLimitReset"
              },
              "x-fapi-interaction-id": {
                "$ref": "#/components/headers/XFapiInteractionId"
              },
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              },
              "traceparent": {
                "$ref": "#/components/headers/Traceparent"
              },
              "Content-Language": {
                "$ref": "#/components/headers/Content-Language"
              }
            }
          },
          "400": {
            "description": "Bad Request",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                },
                "example": {
                  "type": "https://api.kangopenbanking.com/v1/errors/validation-error",
                  "title": "Validation Error",
                  "status": 400
                }
              },
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                },
                "example": {
                  "type": "https://api.kangopenbanking.com/v1/errors/validation-error",
                  "title": "Validation Error",
                  "status": 400
                }
              }
            },
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/XRateLimitLimit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/XRateLimitRemaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/XRateLimitReset"
              }
            }
          },
          "401": {
            "description": "Unauthorized",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                },
                "example": {
                  "type": "https://api.kangopenbanking.com/v1/errors/unauthorized",
                  "title": "Unauthorized",
                  "status": 401
                }
              },
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                },
                "example": {
                  "type": "https://api.kangopenbanking.com/v1/errors/unauthorized",
                  "title": "Unauthorized",
                  "status": 401
                }
              }
            },
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/XRateLimitLimit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/XRateLimitRemaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/XRateLimitReset"
              }
            }
          },
          "403": {
            "description": "Forbidden",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                },
                "examples": {
                  "error": {
                    "$ref": "#/components/examples/ErrorForbidden"
                  }
                }
              },
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            },
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/XRateLimitLimit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/XRateLimitRemaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/XRateLimitReset"
              }
            }
          },
          "404": {
            "description": "Not Found",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                },
                "examples": {
                  "error": {
                    "$ref": "#/components/examples/ErrorNotFound"
                  }
                }
              },
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            },
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/XRateLimitLimit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/XRateLimitRemaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/XRateLimitReset"
              }
            }
          },
          "429": {
            "$ref": "#/components/responses/TooManyRequests",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "500": {
            "description": "500 Internal Server Error — an unexpected condition prevented completion.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                },
                "example": {
                  "type": "https://api.kangopenbanking.com/v1/errors/internal-error",
                  "title": "Internal Server Error",
                  "status": 500
                }
              },
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                },
                "example": {
                  "type": "https://api.kangopenbanking.com/v1/errors/internal-error",
                  "title": "Internal Server Error",
                  "status": 500
                }
              }
            }
          },
          "default": {
            "description": "Server error — see ProblemDetails for trace ID.",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            },
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/XRateLimitLimit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/XRateLimitRemaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/XRateLimitReset"
              }
            }
          }
        },
        "x-codeSamples": [
          {
            "lang": "cURL",
            "label": "cURL",
            "source": "curl -X GET \"https://api.kangopenbanking.com/v1/banks/{bankId}/connector/mappings\" \\\n  -H \"Authorization: Bearer $KOB_API_KEY\" \\\n  -H \"X-Request-Id: $(uuidgen)\""
          },
          {
            "lang": "JavaScript",
            "label": "Node.js",
            "source": "import { KangClient } from '@kangopenbanking/sdk';\n\nconst kang = new KangClient({ apiKey: process.env.KOB_API_KEY });\n\nconst response = await kang.request({\n  method: 'GET',\n  path: '/v1/banks/{bankId}/connector/mappings',\n});\n\nconsole.log(response.data);"
          },
          {
            "lang": "Python",
            "label": "Python",
            "source": "from kangopenbanking import Kang\nimport os, uuid\n\nkang = Kang(api_key=os.environ[\"KOB_API_KEY\"])\n\nresponse = kang.request(\n    method=\"GET\",\n    path=\"/v1/banks/{bankId}/connector/mappings\",\n)\n\nprint(response.data)"
          },
          {
            "lang": "PHP",
            "label": "PHP",
            "source": "<?php\nrequire 'vendor/autoload.php';\n\n$kang = new \\KangOpenBanking\\Client(getenv('KOB_API_KEY'));\n\n$response = $kang->request([\n    'method' => 'GET',\n    'path'   => '/v1/banks/{bankId}/connector/mappings',\n]);\n\nprint_r($response->data);"
          }
        ]
      },
      "post": {
        "tags": [
          "BankConnectors"
        ],
        "summary": "Create or update mapping template",
        "operationId": "connectorMappingsUpsert",
        "description": "Upsert a per-bank, per-file_type column mapping. Versioned; only one active mapping per (bank, file_type).",
        "security": [
          {
            "bearerAuth": []
          },
          {
            "oauth2": [
              "banking:write"
            ]
          }
        ],
        "parameters": [
          {
            "name": "bankId",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          },
          {
            "$ref": "#/components/parameters/RequestId"
          },
          {
            "$ref": "#/components/parameters/Traceparent"
          },
          {
            "$ref": "#/components/parameters/Tracestate"
          },
          {
            "$ref": "#/components/parameters/AcceptLanguage"
          }
        ],
        "responses": {
          "200": {
            "description": "Success",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                },
                "examples": {
                  "default": {
                    "$ref": "#/components/examples/GenericSuccess"
                  }
                }
              }
            },
            "headers": {
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/XRateLimitLimit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/XRateLimitRemaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/XRateLimitReset"
              },
              "x-fapi-interaction-id": {
                "$ref": "#/components/headers/XFapiInteractionId"
              },
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              },
              "traceparent": {
                "$ref": "#/components/headers/Traceparent"
              },
              "Content-Language": {
                "$ref": "#/components/headers/Content-Language"
              }
            }
          },
          "400": {
            "description": "Bad Request",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                },
                "example": {
                  "type": "https://api.kangopenbanking.com/v1/errors/validation-error",
                  "title": "Validation Error",
                  "status": 400
                }
              },
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                },
                "example": {
                  "type": "https://api.kangopenbanking.com/v1/errors/validation-error",
                  "title": "Validation Error",
                  "status": 400
                }
              }
            },
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/XRateLimitLimit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/XRateLimitRemaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/XRateLimitReset"
              }
            }
          },
          "401": {
            "description": "Unauthorized",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                },
                "example": {
                  "type": "https://api.kangopenbanking.com/v1/errors/unauthorized",
                  "title": "Unauthorized",
                  "status": 401
                }
              },
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                },
                "example": {
                  "type": "https://api.kangopenbanking.com/v1/errors/unauthorized",
                  "title": "Unauthorized",
                  "status": 401
                }
              }
            },
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/XRateLimitLimit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/XRateLimitRemaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/XRateLimitReset"
              }
            }
          },
          "403": {
            "description": "Forbidden",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                },
                "examples": {
                  "error": {
                    "$ref": "#/components/examples/ErrorForbidden"
                  }
                }
              },
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            },
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/XRateLimitLimit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/XRateLimitRemaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/XRateLimitReset"
              }
            }
          },
          "404": {
            "description": "Not Found",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                },
                "examples": {
                  "error": {
                    "$ref": "#/components/examples/ErrorNotFound"
                  }
                }
              },
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            },
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/XRateLimitLimit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/XRateLimitRemaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/XRateLimitReset"
              }
            }
          },
          "409": {
            "$ref": "#/components/responses/Conflict",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "429": {
            "$ref": "#/components/responses/TooManyRequests",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "500": {
            "description": "500 Internal Server Error — an unexpected condition prevented completion.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                },
                "example": {
                  "type": "https://api.kangopenbanking.com/v1/errors/internal-error",
                  "title": "Internal Server Error",
                  "status": 500
                }
              },
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                },
                "example": {
                  "type": "https://api.kangopenbanking.com/v1/errors/internal-error",
                  "title": "Internal Server Error",
                  "status": 500
                }
              }
            }
          },
          "default": {
            "description": "Server error — see ProblemDetails for trace ID.",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            },
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/XRateLimitLimit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/XRateLimitRemaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/XRateLimitReset"
              }
            }
          }
        },
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "required": [
                  "file_type",
                  "mapping_json"
                ],
                "properties": {
                  "file_type": {
                    "type": "string",
                    "enum": [
                      "accounts",
                      "balances",
                      "transactions",
                      "beneficiaries",
                      "payment_instructions",
                      "payment_status"
                    ]
                  },
                  "mapping_json": {
                    "type": "object",
                    "description": "Column→canonical-field mapping with optional transforms (trim, uppercase, parseDecimal, parsePhone, maskAccount)"
                  },
                  "is_active": {
                    "type": "boolean",
                    "default": true
                  }
                }
              }
            }
          }
        },
        "x-codeSamples": [
          {
            "lang": "cURL",
            "label": "cURL",
            "source": "curl -X POST \"https://api.kangopenbanking.com/v1/banks/{bankId}/connector/mappings\" \\\n  -H \"Authorization: Bearer $KOB_API_KEY\" \\\n  -H \"X-Request-Id: $(uuidgen)\" \\\n  -H \"Idempotency-Key: $(uuidgen)\" \\\n  -H \"Content-Type: application/json\" \\\n  -d '{\"amount\":\"5000\",\"currency\":\"XAF\"}'"
          },
          {
            "lang": "JavaScript",
            "label": "Node.js",
            "source": "import { KangClient } from '@kangopenbanking/sdk';\n\nconst kang = new KangClient({ apiKey: process.env.KOB_API_KEY });\n\nconst response = await kang.request({\n  method: 'POST',\n  path: '/v1/banks/{bankId}/connector/mappings',\n  body: { amount: '5000', currency: 'XAF' },\n  idempotencyKey: crypto.randomUUID(),\n});\n\nconsole.log(response.data);"
          },
          {
            "lang": "Python",
            "label": "Python",
            "source": "from kangopenbanking import Kang\nimport os, uuid\n\nkang = Kang(api_key=os.environ[\"KOB_API_KEY\"])\n\nresponse = kang.request(\n    method=\"POST\",\n    path=\"/v1/banks/{bankId}/connector/mappings\",\n    body={\"amount\": \"5000\", \"currency\": \"XAF\"},\n    idempotency_key=str(uuid.uuid4()),\n)\n\nprint(response.data)"
          },
          {
            "lang": "PHP",
            "label": "PHP",
            "source": "<?php\nrequire 'vendor/autoload.php';\n\n$kang = new \\KangOpenBanking\\Client(getenv('KOB_API_KEY'));\n\n$response = $kang->request([\n    'method' => 'POST',\n    'path'   => '/v1/banks/{bankId}/connector/mappings',\n    'body'   => ['amount' => '5000', 'currency' => 'XAF'],\n    'idempotency_key' => \\Ramsey\\Uuid\\Uuid::uuid4()->toString(),\n]);\n\nprint_r($response->data);"
          }
        ]
      }
    },
    "/v1/banks/{bankId}/connector/validate-template": {
      "post": {
        "tags": [
          "BankConnectors"
        ],
        "summary": "Validate a mapping against a sample file",
        "operationId": "connectorValidateTemplate",
        "description": "Dry-run a mapping template against a sample file. Returns row count, validation errors per row, and dedupe collisions.",
        "security": [
          {
            "bearerAuth": []
          },
          {
            "oauth2": [
              "banking:write"
            ]
          }
        ],
        "parameters": [
          {
            "name": "bankId",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          },
          {
            "$ref": "#/components/parameters/RequestId"
          },
          {
            "$ref": "#/components/parameters/Traceparent"
          },
          {
            "$ref": "#/components/parameters/Tracestate"
          },
          {
            "$ref": "#/components/parameters/AcceptLanguage"
          }
        ],
        "responses": {
          "200": {
            "description": "Success",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                },
                "examples": {
                  "default": {
                    "$ref": "#/components/examples/GenericSuccess"
                  }
                }
              }
            },
            "headers": {
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/XRateLimitLimit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/XRateLimitRemaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/XRateLimitReset"
              },
              "x-fapi-interaction-id": {
                "$ref": "#/components/headers/XFapiInteractionId"
              },
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              },
              "traceparent": {
                "$ref": "#/components/headers/Traceparent"
              },
              "Content-Language": {
                "$ref": "#/components/headers/Content-Language"
              }
            }
          },
          "400": {
            "description": "Bad Request",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                },
                "example": {
                  "type": "https://api.kangopenbanking.com/v1/errors/validation-error",
                  "title": "Validation Error",
                  "status": 400
                }
              },
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                },
                "example": {
                  "type": "https://api.kangopenbanking.com/v1/errors/validation-error",
                  "title": "Validation Error",
                  "status": 400
                }
              }
            },
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/XRateLimitLimit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/XRateLimitRemaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/XRateLimitReset"
              }
            }
          },
          "401": {
            "description": "Unauthorized",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                },
                "example": {
                  "type": "https://api.kangopenbanking.com/v1/errors/unauthorized",
                  "title": "Unauthorized",
                  "status": 401
                }
              },
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                },
                "example": {
                  "type": "https://api.kangopenbanking.com/v1/errors/unauthorized",
                  "title": "Unauthorized",
                  "status": 401
                }
              }
            },
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/XRateLimitLimit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/XRateLimitRemaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/XRateLimitReset"
              }
            }
          },
          "403": {
            "description": "Forbidden",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                },
                "examples": {
                  "error": {
                    "$ref": "#/components/examples/ErrorForbidden"
                  }
                }
              },
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            },
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/XRateLimitLimit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/XRateLimitRemaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/XRateLimitReset"
              }
            }
          },
          "404": {
            "description": "Not Found",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                },
                "examples": {
                  "error": {
                    "$ref": "#/components/examples/ErrorNotFound"
                  }
                }
              },
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            },
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/XRateLimitLimit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/XRateLimitRemaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/XRateLimitReset"
              }
            }
          },
          "409": {
            "$ref": "#/components/responses/Conflict",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "429": {
            "$ref": "#/components/responses/TooManyRequests",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "500": {
            "description": "500 Internal Server Error — an unexpected condition prevented completion.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                },
                "example": {
                  "type": "https://api.kangopenbanking.com/v1/errors/internal-error",
                  "title": "Internal Server Error",
                  "status": 500
                }
              },
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                },
                "example": {
                  "type": "https://api.kangopenbanking.com/v1/errors/internal-error",
                  "title": "Internal Server Error",
                  "status": 500
                }
              }
            }
          },
          "default": {
            "description": "Server error — see ProblemDetails for trace ID.",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            },
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/XRateLimitLimit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/XRateLimitRemaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/XRateLimitReset"
              }
            }
          }
        },
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "required": [
                  "file_type",
                  "file_base64",
                  "mapping_json"
                ],
                "properties": {
                  "file_type": {
                    "type": "string"
                  },
                  "file_base64": {
                    "type": "string"
                  },
                  "mapping_json": {
                    "type": "object"
                  }
                }
              }
            }
          }
        },
        "x-codeSamples": [
          {
            "lang": "cURL",
            "label": "cURL",
            "source": "curl -X POST \"https://api.kangopenbanking.com/v1/banks/{bankId}/connector/validate-template\" \\\n  -H \"Authorization: Bearer $KOB_API_KEY\" \\\n  -H \"X-Request-Id: $(uuidgen)\" \\\n  -H \"Idempotency-Key: $(uuidgen)\" \\\n  -H \"Content-Type: application/json\" \\\n  -d '{\"amount\":\"5000\",\"currency\":\"XAF\"}'"
          },
          {
            "lang": "JavaScript",
            "label": "Node.js",
            "source": "import { KangClient } from '@kangopenbanking/sdk';\n\nconst kang = new KangClient({ apiKey: process.env.KOB_API_KEY });\n\nconst response = await kang.request({\n  method: 'POST',\n  path: '/v1/banks/{bankId}/connector/validate-template',\n  body: { amount: '5000', currency: 'XAF' },\n  idempotencyKey: crypto.randomUUID(),\n});\n\nconsole.log(response.data);"
          },
          {
            "lang": "Python",
            "label": "Python",
            "source": "from kangopenbanking import Kang\nimport os, uuid\n\nkang = Kang(api_key=os.environ[\"KOB_API_KEY\"])\n\nresponse = kang.request(\n    method=\"POST\",\n    path=\"/v1/banks/{bankId}/connector/validate-template\",\n    body={\"amount\": \"5000\", \"currency\": \"XAF\"},\n    idempotency_key=str(uuid.uuid4()),\n)\n\nprint(response.data)"
          },
          {
            "lang": "PHP",
            "label": "PHP",
            "source": "<?php\nrequire 'vendor/autoload.php';\n\n$kang = new \\KangOpenBanking\\Client(getenv('KOB_API_KEY'));\n\n$response = $kang->request([\n    'method' => 'POST',\n    'path'   => '/v1/banks/{bankId}/connector/validate-template',\n    'body'   => ['amount' => '5000', 'currency' => 'XAF'],\n    'idempotency_key' => \\Ramsey\\Uuid\\Uuid::uuid4()->toString(),\n]);\n\nprint_r($response->data);"
          }
        ]
      }
    },
    "/v1/banks/{bankId}/batch-payments": {
      "post": {
        "tags": [
          "BankConnectors"
        ],
        "summary": "Create outbound payment batch",
        "operationId": "connectorBatchCreate",
        "description": "Create a payment batch for execution by the bank. Default output is CSV; pain.001 (ISO 20022) supported when format=pain001.",
        "security": [
          {
            "bearerAuth": []
          },
          {
            "oauth2": [
              "banking:write"
            ]
          }
        ],
        "parameters": [
          {
            "$ref": "#/components/parameters/IdempotencyKey"
          },
          {
            "name": "bankId",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          },
          {
            "$ref": "#/components/parameters/RequestId"
          },
          {
            "$ref": "#/components/parameters/Traceparent"
          },
          {
            "$ref": "#/components/parameters/Tracestate"
          },
          {
            "$ref": "#/components/parameters/AcceptLanguage"
          }
        ],
        "responses": {
          "200": {
            "description": "Success",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                },
                "examples": {
                  "default": {
                    "$ref": "#/components/examples/PaymentIntentCreated"
                  }
                }
              }
            },
            "headers": {
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/XRateLimitLimit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/XRateLimitRemaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/XRateLimitReset"
              },
              "x-fapi-interaction-id": {
                "$ref": "#/components/headers/XFapiInteractionId"
              },
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              },
              "traceparent": {
                "$ref": "#/components/headers/Traceparent"
              },
              "Content-Language": {
                "$ref": "#/components/headers/Content-Language"
              },
              "X-Idempotent-Replay": {
                "$ref": "#/components/headers/X-Idempotent-Replay"
              },
              "X-Idempotency-Status": {
                "$ref": "#/components/headers/X-Idempotency-Status"
              }
            }
          },
          "400": {
            "description": "Bad Request",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                },
                "example": {
                  "type": "https://api.kangopenbanking.com/v1/errors/validation-error",
                  "title": "Validation Error",
                  "status": 400
                }
              },
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                },
                "example": {
                  "type": "https://api.kangopenbanking.com/v1/errors/validation-error",
                  "title": "Validation Error",
                  "status": 400
                }
              }
            },
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/XRateLimitLimit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/XRateLimitRemaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/XRateLimitReset"
              }
            }
          },
          "401": {
            "description": "Unauthorized",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                },
                "example": {
                  "type": "https://api.kangopenbanking.com/v1/errors/unauthorized",
                  "title": "Unauthorized",
                  "status": 401
                }
              },
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                },
                "example": {
                  "type": "https://api.kangopenbanking.com/v1/errors/unauthorized",
                  "title": "Unauthorized",
                  "status": 401
                }
              }
            },
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/XRateLimitLimit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/XRateLimitRemaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/XRateLimitReset"
              }
            }
          },
          "403": {
            "description": "Forbidden",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                },
                "examples": {
                  "error": {
                    "$ref": "#/components/examples/ErrorForbidden"
                  }
                }
              },
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            },
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/XRateLimitLimit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/XRateLimitRemaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/XRateLimitReset"
              }
            }
          },
          "404": {
            "description": "Not Found",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                },
                "examples": {
                  "error": {
                    "$ref": "#/components/examples/ErrorNotFound"
                  }
                }
              },
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            },
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/XRateLimitLimit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/XRateLimitRemaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/XRateLimitReset"
              }
            }
          },
          "409": {
            "$ref": "#/components/responses/Conflict",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "429": {
            "$ref": "#/components/responses/TooManyRequests",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "500": {
            "description": "500 Internal Server Error — an unexpected condition prevented completion.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                },
                "example": {
                  "type": "https://api.kangopenbanking.com/v1/errors/internal-error",
                  "title": "Internal Server Error",
                  "status": 500
                }
              },
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                },
                "example": {
                  "type": "https://api.kangopenbanking.com/v1/errors/internal-error",
                  "title": "Internal Server Error",
                  "status": 500
                }
              }
            }
          },
          "default": {
            "description": "Server error — see ProblemDetails for trace ID.",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            },
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/XRateLimitLimit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/XRateLimitRemaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/XRateLimitReset"
              }
            }
          }
        },
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "required": [
                  "batch_type",
                  "items"
                ],
                "properties": {
                  "batch_type": {
                    "type": "string",
                    "enum": [
                      "outgoing_transfers",
                      "salary",
                      "merchant_payouts"
                    ]
                  },
                  "format": {
                    "type": "string",
                    "enum": [
                      "csv",
                      "pain001"
                    ],
                    "default": "csv"
                  },
                  "environment": {
                    "type": "string",
                    "enum": [
                      "sandbox",
                      "prod"
                    ],
                    "default": "sandbox"
                  },
                  "items": {
                    "type": "array",
                    "minItems": 1,
                    "maxItems": 10000,
                    "items": {
                      "type": "object",
                      "required": [
                        "beneficiary_account",
                        "amount",
                        "currency"
                      ],
                      "properties": {
                        "beneficiary_name": {
                          "type": "string"
                        },
                        "beneficiary_account": {
                          "type": "string"
                        },
                        "amount": {
                          "type": "string",
                          "pattern": "^[0-9]{1,15}$"
                        },
                        "currency": {
                          "type": "string",
                          "minLength": 3,
                          "maxLength": 3,
                          "default": "XAF"
                        },
                        "reference": {
                          "type": "string"
                        },
                        "narrative": {
                          "type": "string"
                        }
                      }
                    }
                  }
                }
              }
            }
          }
        },
        "x-codeSamples": [
          {
            "lang": "cURL",
            "label": "cURL",
            "source": "curl -X POST \"https://api.kangopenbanking.com/v1/banks/{bankId}/batch-payments\" \\\n  -H \"Authorization: Bearer $KOB_API_KEY\" \\\n  -H \"X-Request-Id: $(uuidgen)\" \\\n  -H \"Idempotency-Key: $(uuidgen)\" \\\n  -H \"Content-Type: application/json\" \\\n  -d '{\"amount\":\"5000\",\"currency\":\"XAF\"}'"
          },
          {
            "lang": "JavaScript",
            "label": "Node.js",
            "source": "import { KangClient } from '@kangopenbanking/sdk';\n\nconst kang = new KangClient({ apiKey: process.env.KOB_API_KEY });\n\nconst response = await kang.request({\n  method: 'POST',\n  path: '/v1/banks/{bankId}/batch-payments',\n  body: { amount: '5000', currency: 'XAF' },\n  idempotencyKey: crypto.randomUUID(),\n});\n\nconsole.log(response.data);"
          },
          {
            "lang": "Python",
            "label": "Python",
            "source": "from kangopenbanking import Kang\nimport os, uuid\n\nkang = Kang(api_key=os.environ[\"KOB_API_KEY\"])\n\nresponse = kang.request(\n    method=\"POST\",\n    path=\"/v1/banks/{bankId}/batch-payments\",\n    body={\"amount\": \"5000\", \"currency\": \"XAF\"},\n    idempotency_key=str(uuid.uuid4()),\n)\n\nprint(response.data)"
          },
          {
            "lang": "PHP",
            "label": "PHP",
            "source": "<?php\nrequire 'vendor/autoload.php';\n\n$kang = new \\KangOpenBanking\\Client(getenv('KOB_API_KEY'));\n\n$response = $kang->request([\n    'method' => 'POST',\n    'path'   => '/v1/banks/{bankId}/batch-payments',\n    'body'   => ['amount' => '5000', 'currency' => 'XAF'],\n    'idempotency_key' => \\Ramsey\\Uuid\\Uuid::uuid4()->toString(),\n]);\n\nprint_r($response->data);"
          }
        ]
      },
      "get": {
        "tags": [
          "BankConnectors"
        ],
        "summary": "List outbound payment batches",
        "operationId": "connectorBatchList",
        "description": "List outbound payment batches.\n\n**Tag:** BankConnectors\n\nAuthenticate with a bearer token issued by `/v1/oauth/token`. All state-changing requests\n(POST, PUT, PATCH, DELETE) MUST include an `Idempotency-Key` header (UUID v4) to make\nretries safe — Kang will return the original response for any duplicate key within 24 hours.\n\nErrors follow [RFC 7807](https://datatracker.ietf.org/doc/html/rfc7807) and are returned with\n`Content-Type: application/problem+json`. The `code` field is stable and machine-readable.\nRate-limit headers (`X-RateLimit-Limit`, `X-RateLimit-Remaining`, `X-RateLimit-Reset`)\nare present on every response.",
        "security": [
          {
            "bearerAuth": []
          },
          {
            "oauth2": [
              "banking:write"
            ]
          }
        ],
        "parameters": [
          {
            "name": "bankId",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          },
          {
            "name": "status",
            "in": "query",
            "schema": {
              "type": "string",
              "enum": [
                "draft",
                "generated",
                "delivered",
                "executed",
                "partially_failed",
                "failed",
                "reconciled"
              ]
            }
          },
          {
            "name": "limit",
            "in": "query",
            "schema": {
              "type": "integer",
              "minimum": 1,
              "maximum": 200,
              "default": 50
            }
          },
          {
            "name": "offset",
            "in": "query",
            "schema": {
              "type": "integer",
              "minimum": 0,
              "default": 0
            }
          },
          {
            "$ref": "#/components/parameters/StartingAfter"
          },
          {
            "$ref": "#/components/parameters/EndingBefore"
          },
          {
            "$ref": "#/components/parameters/RequestId"
          },
          {
            "$ref": "#/components/parameters/Traceparent"
          },
          {
            "$ref": "#/components/parameters/Tracestate"
          },
          {
            "$ref": "#/components/parameters/AcceptLanguage"
          }
        ],
        "responses": {
          "200": {
            "description": "Success",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                },
                "examples": {
                  "default": {
                    "$ref": "#/components/examples/PaymentIntentCreated"
                  }
                }
              }
            },
            "headers": {
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/XRateLimitLimit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/XRateLimitRemaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/XRateLimitReset"
              },
              "x-fapi-interaction-id": {
                "$ref": "#/components/headers/XFapiInteractionId"
              },
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              },
              "traceparent": {
                "$ref": "#/components/headers/Traceparent"
              },
              "Content-Language": {
                "$ref": "#/components/headers/Content-Language"
              }
            }
          },
          "400": {
            "description": "Bad Request",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                },
                "example": {
                  "type": "https://api.kangopenbanking.com/v1/errors/validation-error",
                  "title": "Validation Error",
                  "status": 400
                }
              },
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                },
                "example": {
                  "type": "https://api.kangopenbanking.com/v1/errors/validation-error",
                  "title": "Validation Error",
                  "status": 400
                }
              }
            },
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/XRateLimitLimit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/XRateLimitRemaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/XRateLimitReset"
              }
            }
          },
          "401": {
            "description": "Unauthorized",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                },
                "example": {
                  "type": "https://api.kangopenbanking.com/v1/errors/unauthorized",
                  "title": "Unauthorized",
                  "status": 401
                }
              },
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                },
                "example": {
                  "type": "https://api.kangopenbanking.com/v1/errors/unauthorized",
                  "title": "Unauthorized",
                  "status": 401
                }
              }
            },
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/XRateLimitLimit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/XRateLimitRemaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/XRateLimitReset"
              }
            }
          },
          "403": {
            "description": "Forbidden",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                },
                "examples": {
                  "error": {
                    "$ref": "#/components/examples/ErrorForbidden"
                  }
                }
              },
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            },
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/XRateLimitLimit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/XRateLimitRemaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/XRateLimitReset"
              }
            }
          },
          "404": {
            "description": "Not Found",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                },
                "examples": {
                  "error": {
                    "$ref": "#/components/examples/ErrorNotFound"
                  }
                }
              },
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            },
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/XRateLimitLimit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/XRateLimitRemaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/XRateLimitReset"
              }
            }
          },
          "429": {
            "$ref": "#/components/responses/TooManyRequests",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "500": {
            "description": "500 Internal Server Error — an unexpected condition prevented completion.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                },
                "example": {
                  "type": "https://api.kangopenbanking.com/v1/errors/internal-error",
                  "title": "Internal Server Error",
                  "status": 500
                }
              },
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                },
                "example": {
                  "type": "https://api.kangopenbanking.com/v1/errors/internal-error",
                  "title": "Internal Server Error",
                  "status": 500
                }
              }
            }
          },
          "default": {
            "description": "Server error — see ProblemDetails for trace ID.",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            },
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/XRateLimitLimit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/XRateLimitRemaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/XRateLimitReset"
              }
            }
          }
        },
        "x-codeSamples": [
          {
            "lang": "cURL",
            "label": "cURL",
            "source": "curl -X GET \"https://api.kangopenbanking.com/v1/banks/{bankId}/batch-payments\" \\\n  -H \"Authorization: Bearer $KOB_API_KEY\" \\\n  -H \"X-Request-Id: $(uuidgen)\""
          },
          {
            "lang": "JavaScript",
            "label": "Node.js",
            "source": "import { KangClient } from '@kangopenbanking/sdk';\n\nconst kang = new KangClient({ apiKey: process.env.KOB_API_KEY });\n\nconst response = await kang.request({\n  method: 'GET',\n  path: '/v1/banks/{bankId}/batch-payments',\n});\n\nconsole.log(response.data);"
          },
          {
            "lang": "Python",
            "label": "Python",
            "source": "from kangopenbanking import Kang\nimport os, uuid\n\nkang = Kang(api_key=os.environ[\"KOB_API_KEY\"])\n\nresponse = kang.request(\n    method=\"GET\",\n    path=\"/v1/banks/{bankId}/batch-payments\",\n)\n\nprint(response.data)"
          },
          {
            "lang": "PHP",
            "label": "PHP",
            "source": "<?php\nrequire 'vendor/autoload.php';\n\n$kang = new \\KangOpenBanking\\Client(getenv('KOB_API_KEY'));\n\n$response = $kang->request([\n    'method' => 'GET',\n    'path'   => '/v1/banks/{bankId}/batch-payments',\n]);\n\nprint_r($response->data);"
          }
        ]
      }
    },
    "/v1/banks/{bankId}/batch-payments/{batchId}": {
      "get": {
        "tags": [
          "BankConnectors"
        ],
        "summary": "Get batch detail",
        "operationId": "connectorBatchGet",
        "description": "Get batch detail.\n\n**Tag:** BankConnectors\n\nAuthenticate with a bearer token issued by `/v1/oauth/token`. All state-changing requests\n(POST, PUT, PATCH, DELETE) MUST include an `Idempotency-Key` header (UUID v4) to make\nretries safe — Kang will return the original response for any duplicate key within 24 hours.\n\nErrors follow [RFC 7807](https://datatracker.ietf.org/doc/html/rfc7807) and are returned with\n`Content-Type: application/problem+json`. The `code` field is stable and machine-readable.\nRate-limit headers (`X-RateLimit-Limit`, `X-RateLimit-Remaining`, `X-RateLimit-Reset`)\nare present on every response.",
        "security": [
          {
            "bearerAuth": []
          },
          {
            "oauth2": [
              "banking:read"
            ]
          }
        ],
        "parameters": [
          {
            "name": "bankId",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          },
          {
            "name": "batchId",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          },
          {
            "$ref": "#/components/parameters/RequestId"
          },
          {
            "$ref": "#/components/parameters/Traceparent"
          },
          {
            "$ref": "#/components/parameters/Tracestate"
          },
          {
            "$ref": "#/components/parameters/AcceptLanguage"
          }
        ],
        "responses": {
          "200": {
            "description": "Batch detail",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                },
                "examples": {
                  "default": {
                    "$ref": "#/components/examples/PaymentIntentCreated"
                  }
                }
              }
            },
            "headers": {
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/XRateLimitLimit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/XRateLimitRemaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/XRateLimitReset"
              },
              "x-fapi-interaction-id": {
                "$ref": "#/components/headers/XFapiInteractionId"
              },
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              },
              "traceparent": {
                "$ref": "#/components/headers/Traceparent"
              },
              "Content-Language": {
                "$ref": "#/components/headers/Content-Language"
              }
            }
          },
          "400": {
            "description": "400 Bad Request — the request failed validation.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                },
                "example": {
                  "type": "https://api.kangopenbanking.com/v1/errors/validation-error",
                  "title": "Validation Error",
                  "status": 400
                }
              },
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                },
                "example": {
                  "type": "https://api.kangopenbanking.com/v1/errors/validation-error",
                  "title": "Validation Error",
                  "status": 400
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "404": {
            "description": "Not Found",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                },
                "examples": {
                  "error": {
                    "$ref": "#/components/examples/ErrorNotFound"
                  }
                }
              },
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            },
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/XRateLimitLimit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/XRateLimitRemaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/XRateLimitReset"
              }
            }
          },
          "429": {
            "$ref": "#/components/responses/TooManyRequests",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "500": {
            "description": "500 Internal Server Error — an unexpected condition prevented completion.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                },
                "example": {
                  "type": "https://api.kangopenbanking.com/v1/errors/internal-error",
                  "title": "Internal Server Error",
                  "status": 500
                }
              },
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                },
                "example": {
                  "type": "https://api.kangopenbanking.com/v1/errors/internal-error",
                  "title": "Internal Server Error",
                  "status": 500
                }
              }
            }
          },
          "default": {
            "description": "Server error — see ProblemDetails for trace ID.",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            },
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/XRateLimitLimit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/XRateLimitRemaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/XRateLimitReset"
              }
            }
          }
        },
        "x-codeSamples": [
          {
            "lang": "cURL",
            "label": "cURL",
            "source": "curl -X GET \"https://api.kangopenbanking.com/v1/banks/{bankId}/batch-payments/{batchId}\" \\\n  -H \"Authorization: Bearer $KOB_API_KEY\" \\\n  -H \"X-Request-Id: $(uuidgen)\""
          },
          {
            "lang": "JavaScript",
            "label": "Node.js",
            "source": "import { KangClient } from '@kangopenbanking/sdk';\n\nconst kang = new KangClient({ apiKey: process.env.KOB_API_KEY });\n\nconst response = await kang.request({\n  method: 'GET',\n  path: '/v1/banks/{bankId}/batch-payments/{batchId}',\n});\n\nconsole.log(response.data);"
          },
          {
            "lang": "Python",
            "label": "Python",
            "source": "from kangopenbanking import Kang\nimport os, uuid\n\nkang = Kang(api_key=os.environ[\"KOB_API_KEY\"])\n\nresponse = kang.request(\n    method=\"GET\",\n    path=\"/v1/banks/{bankId}/batch-payments/{batchId}\",\n)\n\nprint(response.data)"
          },
          {
            "lang": "PHP",
            "label": "PHP",
            "source": "<?php\nrequire 'vendor/autoload.php';\n\n$kang = new \\KangOpenBanking\\Client(getenv('KOB_API_KEY'));\n\n$response = $kang->request([\n    'method' => 'GET',\n    'path'   => '/v1/banks/{bankId}/batch-payments/{batchId}',\n]);\n\nprint_r($response->data);"
          }
        ]
      }
    },
    "/v1/banks/{bankId}/batch-payments/{batchId}/download": {
      "get": {
        "tags": [
          "BankConnectors"
        ],
        "summary": "Download batch file",
        "operationId": "connectorBatchDownload",
        "description": "Download the generated batch file. Returns CSV (text/csv) by default or ISO 20022 pain.001 XML when format=pain001.",
        "security": [
          {
            "bearerAuth": []
          },
          {
            "oauth2": [
              "banking:read"
            ]
          }
        ],
        "parameters": [
          {
            "name": "bankId",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          },
          {
            "name": "batchId",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          },
          {
            "name": "format",
            "in": "query",
            "schema": {
              "type": "string",
              "enum": [
                "csv",
                "pain001"
              ],
              "default": "csv"
            }
          },
          {
            "$ref": "#/components/parameters/RequestId"
          },
          {
            "$ref": "#/components/parameters/Traceparent"
          },
          {
            "$ref": "#/components/parameters/Tracestate"
          },
          {
            "$ref": "#/components/parameters/AcceptLanguage"
          }
        ],
        "responses": {
          "200": {
            "description": "Batch file",
            "content": {
              "text/csv": {
                "schema": {
                  "type": "string"
                }
              },
              "application/xml": {
                "schema": {
                  "type": "string",
                  "description": "ISO 20022 pain.001.001.09"
                }
              },
              "application/json": {
                "examples": {
                  "default": {
                    "$ref": "#/components/examples/PaymentIntentCreated"
                  }
                },
                "schema": {
                  "$ref": "#/components/schemas/GenericSuccessResponse"
                }
              }
            },
            "headers": {
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/XRateLimitLimit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/XRateLimitRemaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/XRateLimitReset"
              },
              "x-fapi-interaction-id": {
                "$ref": "#/components/headers/XFapiInteractionId"
              },
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              },
              "traceparent": {
                "$ref": "#/components/headers/Traceparent"
              },
              "Content-Language": {
                "$ref": "#/components/headers/Content-Language"
              }
            }
          },
          "400": {
            "description": "400 Bad Request — the request failed validation.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                },
                "example": {
                  "type": "https://api.kangopenbanking.com/v1/errors/validation-error",
                  "title": "Validation Error",
                  "status": 400
                }
              },
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                },
                "example": {
                  "type": "https://api.kangopenbanking.com/v1/errors/validation-error",
                  "title": "Validation Error",
                  "status": 400
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "404": {
            "description": "Not Found",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                },
                "examples": {
                  "error": {
                    "$ref": "#/components/examples/ErrorNotFound"
                  }
                }
              },
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            },
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/XRateLimitLimit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/XRateLimitRemaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/XRateLimitReset"
              }
            }
          },
          "429": {
            "$ref": "#/components/responses/TooManyRequests",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "500": {
            "description": "500 Internal Server Error — an unexpected condition prevented completion.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                },
                "example": {
                  "type": "https://api.kangopenbanking.com/v1/errors/internal-error",
                  "title": "Internal Server Error",
                  "status": 500
                }
              },
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                },
                "example": {
                  "type": "https://api.kangopenbanking.com/v1/errors/internal-error",
                  "title": "Internal Server Error",
                  "status": 500
                }
              }
            }
          },
          "default": {
            "description": "Server error — see ProblemDetails for trace ID.",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            },
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/XRateLimitLimit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/XRateLimitRemaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/XRateLimitReset"
              }
            }
          }
        },
        "x-codeSamples": [
          {
            "lang": "cURL",
            "label": "cURL",
            "source": "curl -X GET \"https://api.kangopenbanking.com/v1/banks/{bankId}/batch-payments/{batchId}/download\" \\\n  -H \"Authorization: Bearer $KOB_API_KEY\" \\\n  -H \"X-Request-Id: $(uuidgen)\""
          },
          {
            "lang": "JavaScript",
            "label": "Node.js",
            "source": "import { KangClient } from '@kangopenbanking/sdk';\n\nconst kang = new KangClient({ apiKey: process.env.KOB_API_KEY });\n\nconst response = await kang.request({\n  method: 'GET',\n  path: '/v1/banks/{bankId}/batch-payments/{batchId}/download',\n});\n\nconsole.log(response.data);"
          },
          {
            "lang": "Python",
            "label": "Python",
            "source": "from kangopenbanking import Kang\nimport os, uuid\n\nkang = Kang(api_key=os.environ[\"KOB_API_KEY\"])\n\nresponse = kang.request(\n    method=\"GET\",\n    path=\"/v1/banks/{bankId}/batch-payments/{batchId}/download\",\n)\n\nprint(response.data)"
          },
          {
            "lang": "PHP",
            "label": "PHP",
            "source": "<?php\nrequire 'vendor/autoload.php';\n\n$kang = new \\KangOpenBanking\\Client(getenv('KOB_API_KEY'));\n\n$response = $kang->request([\n    'method' => 'GET',\n    'path'   => '/v1/banks/{bankId}/batch-payments/{batchId}/download',\n]);\n\nprint_r($response->data);"
          }
        ]
      }
    },
    "/v1/banks/{bankId}/connector/status-files/upload": {
      "post": {
        "tags": [
          "BankConnectors"
        ],
        "summary": "Upload bank status file",
        "operationId": "connectorStatusFileUpload",
        "description": "Ingest a bank-returned status file (CSV or pacs.002-compatible XML). Updates payment lifecycle states and creates reconciliation cases for mismatches.",
        "security": [
          {
            "bearerAuth": []
          },
          {
            "oauth2": [
              "banking:write"
            ]
          }
        ],
        "parameters": [
          {
            "name": "bankId",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          },
          {
            "$ref": "#/components/parameters/RequestId"
          },
          {
            "$ref": "#/components/parameters/Traceparent"
          },
          {
            "$ref": "#/components/parameters/Tracestate"
          },
          {
            "$ref": "#/components/parameters/AcceptLanguage"
          }
        ],
        "responses": {
          "200": {
            "description": "Success",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                },
                "examples": {
                  "default": {
                    "$ref": "#/components/examples/GenericSuccess"
                  }
                }
              }
            },
            "headers": {
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/XRateLimitLimit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/XRateLimitRemaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/XRateLimitReset"
              },
              "x-fapi-interaction-id": {
                "$ref": "#/components/headers/XFapiInteractionId"
              },
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              },
              "traceparent": {
                "$ref": "#/components/headers/Traceparent"
              },
              "Content-Language": {
                "$ref": "#/components/headers/Content-Language"
              }
            }
          },
          "400": {
            "description": "Bad Request",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                },
                "example": {
                  "type": "https://api.kangopenbanking.com/v1/errors/validation-error",
                  "title": "Validation Error",
                  "status": 400
                }
              },
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                },
                "example": {
                  "type": "https://api.kangopenbanking.com/v1/errors/validation-error",
                  "title": "Validation Error",
                  "status": 400
                }
              }
            },
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/XRateLimitLimit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/XRateLimitRemaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/XRateLimitReset"
              }
            }
          },
          "401": {
            "description": "Unauthorized",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                },
                "example": {
                  "type": "https://api.kangopenbanking.com/v1/errors/unauthorized",
                  "title": "Unauthorized",
                  "status": 401
                }
              },
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                },
                "example": {
                  "type": "https://api.kangopenbanking.com/v1/errors/unauthorized",
                  "title": "Unauthorized",
                  "status": 401
                }
              }
            },
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/XRateLimitLimit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/XRateLimitRemaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/XRateLimitReset"
              }
            }
          },
          "403": {
            "description": "Forbidden",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                },
                "examples": {
                  "error": {
                    "$ref": "#/components/examples/ErrorForbidden"
                  }
                }
              },
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            },
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/XRateLimitLimit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/XRateLimitRemaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/XRateLimitReset"
              }
            }
          },
          "404": {
            "description": "Not Found",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                },
                "examples": {
                  "error": {
                    "$ref": "#/components/examples/ErrorNotFound"
                  }
                }
              },
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            },
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/XRateLimitLimit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/XRateLimitRemaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/XRateLimitReset"
              }
            }
          },
          "409": {
            "$ref": "#/components/responses/Conflict",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "429": {
            "$ref": "#/components/responses/TooManyRequests",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "500": {
            "description": "500 Internal Server Error — an unexpected condition prevented completion.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                },
                "example": {
                  "type": "https://api.kangopenbanking.com/v1/errors/internal-error",
                  "title": "Internal Server Error",
                  "status": 500
                }
              },
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                },
                "example": {
                  "type": "https://api.kangopenbanking.com/v1/errors/internal-error",
                  "title": "Internal Server Error",
                  "status": 500
                }
              }
            }
          },
          "default": {
            "description": "Server error — see ProblemDetails for trace ID.",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            },
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/XRateLimitLimit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/XRateLimitRemaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/XRateLimitReset"
              }
            }
          }
        },
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "required": [
                  "filename",
                  "file_base64"
                ],
                "properties": {
                  "filename": {
                    "type": "string"
                  },
                  "file_base64": {
                    "type": "string"
                  },
                  "format": {
                    "type": "string",
                    "enum": [
                      "csv",
                      "pacs002"
                    ],
                    "default": "csv"
                  },
                  "environment": {
                    "type": "string",
                    "enum": [
                      "sandbox",
                      "prod"
                    ],
                    "default": "sandbox"
                  }
                }
              }
            }
          }
        },
        "x-codeSamples": [
          {
            "lang": "cURL",
            "label": "cURL",
            "source": "curl -X POST \"https://api.kangopenbanking.com/v1/banks/{bankId}/connector/status-files/upload\" \\\n  -H \"Authorization: Bearer $KOB_API_KEY\" \\\n  -H \"X-Request-Id: $(uuidgen)\" \\\n  -H \"Idempotency-Key: $(uuidgen)\" \\\n  -H \"Content-Type: application/json\" \\\n  -d '{\"amount\":\"5000\",\"currency\":\"XAF\"}'"
          },
          {
            "lang": "JavaScript",
            "label": "Node.js",
            "source": "import { KangClient } from '@kangopenbanking/sdk';\n\nconst kang = new KangClient({ apiKey: process.env.KOB_API_KEY });\n\nconst response = await kang.request({\n  method: 'POST',\n  path: '/v1/banks/{bankId}/connector/status-files/upload',\n  body: { amount: '5000', currency: 'XAF' },\n  idempotencyKey: crypto.randomUUID(),\n});\n\nconsole.log(response.data);"
          },
          {
            "lang": "Python",
            "label": "Python",
            "source": "from kangopenbanking import Kang\nimport os, uuid\n\nkang = Kang(api_key=os.environ[\"KOB_API_KEY\"])\n\nresponse = kang.request(\n    method=\"POST\",\n    path=\"/v1/banks/{bankId}/connector/status-files/upload\",\n    body={\"amount\": \"5000\", \"currency\": \"XAF\"},\n    idempotency_key=str(uuid.uuid4()),\n)\n\nprint(response.data)"
          },
          {
            "lang": "PHP",
            "label": "PHP",
            "source": "<?php\nrequire 'vendor/autoload.php';\n\n$kang = new \\KangOpenBanking\\Client(getenv('KOB_API_KEY'));\n\n$response = $kang->request([\n    'method' => 'POST',\n    'path'   => '/v1/banks/{bankId}/connector/status-files/upload',\n    'body'   => ['amount' => '5000', 'currency' => 'XAF'],\n    'idempotency_key' => \\Ramsey\\Uuid\\Uuid::uuid4()->toString(),\n]);\n\nprint_r($response->data);"
          }
        ]
      }
    },
    "/v1/banks/{bankId}/reconciliation": {
      "get": {
        "tags": [
          "BankConnectors"
        ],
        "summary": "List reconciliation cases",
        "operationId": "connectorReconciliationList",
        "description": "List reconciliation buckets: matched, missing_at_bank, missing_at_kob, amount_mismatch, duplicate.",
        "security": [
          {
            "bearerAuth": []
          },
          {
            "oauth2": [
              "banking:write"
            ]
          }
        ],
        "parameters": [
          {
            "name": "bankId",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          },
          {
            "name": "bucket",
            "in": "query",
            "schema": {
              "type": "string",
              "enum": [
                "matched",
                "missing_at_bank",
                "missing_at_kob",
                "amount_mismatch",
                "duplicate"
              ]
            }
          },
          {
            "name": "from",
            "in": "query",
            "schema": {
              "type": "string",
              "format": "date"
            }
          },
          {
            "name": "to",
            "in": "query",
            "schema": {
              "type": "string",
              "format": "date"
            }
          },
          {
            "name": "limit",
            "in": "query",
            "schema": {
              "type": "integer",
              "minimum": 1,
              "maximum": 200,
              "default": 50
            }
          },
          {
            "name": "offset",
            "in": "query",
            "schema": {
              "type": "integer",
              "minimum": 0,
              "default": 0
            }
          },
          {
            "$ref": "#/components/parameters/StartingAfter"
          },
          {
            "$ref": "#/components/parameters/EndingBefore"
          },
          {
            "$ref": "#/components/parameters/RequestId"
          },
          {
            "$ref": "#/components/parameters/Traceparent"
          },
          {
            "$ref": "#/components/parameters/Tracestate"
          },
          {
            "$ref": "#/components/parameters/AcceptLanguage"
          }
        ],
        "responses": {
          "200": {
            "description": "Success",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                },
                "examples": {
                  "default": {
                    "$ref": "#/components/examples/GenericSuccess"
                  }
                }
              }
            },
            "headers": {
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/XRateLimitLimit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/XRateLimitRemaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/XRateLimitReset"
              },
              "x-fapi-interaction-id": {
                "$ref": "#/components/headers/XFapiInteractionId"
              },
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              },
              "traceparent": {
                "$ref": "#/components/headers/Traceparent"
              },
              "Content-Language": {
                "$ref": "#/components/headers/Content-Language"
              }
            }
          },
          "400": {
            "description": "Bad Request",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                },
                "example": {
                  "type": "https://api.kangopenbanking.com/v1/errors/validation-error",
                  "title": "Validation Error",
                  "status": 400
                }
              },
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                },
                "example": {
                  "type": "https://api.kangopenbanking.com/v1/errors/validation-error",
                  "title": "Validation Error",
                  "status": 400
                }
              }
            },
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/XRateLimitLimit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/XRateLimitRemaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/XRateLimitReset"
              }
            }
          },
          "401": {
            "description": "Unauthorized",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                },
                "example": {
                  "type": "https://api.kangopenbanking.com/v1/errors/unauthorized",
                  "title": "Unauthorized",
                  "status": 401
                }
              },
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                },
                "example": {
                  "type": "https://api.kangopenbanking.com/v1/errors/unauthorized",
                  "title": "Unauthorized",
                  "status": 401
                }
              }
            },
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/XRateLimitLimit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/XRateLimitRemaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/XRateLimitReset"
              }
            }
          },
          "403": {
            "description": "Forbidden",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                },
                "examples": {
                  "error": {
                    "$ref": "#/components/examples/ErrorForbidden"
                  }
                }
              },
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            },
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/XRateLimitLimit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/XRateLimitRemaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/XRateLimitReset"
              }
            }
          },
          "404": {
            "description": "Not Found",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                },
                "examples": {
                  "error": {
                    "$ref": "#/components/examples/ErrorNotFound"
                  }
                }
              },
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            },
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/XRateLimitLimit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/XRateLimitRemaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/XRateLimitReset"
              }
            }
          },
          "429": {
            "$ref": "#/components/responses/TooManyRequests",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "500": {
            "description": "500 Internal Server Error — an unexpected condition prevented completion.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                },
                "example": {
                  "type": "https://api.kangopenbanking.com/v1/errors/internal-error",
                  "title": "Internal Server Error",
                  "status": 500
                }
              },
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                },
                "example": {
                  "type": "https://api.kangopenbanking.com/v1/errors/internal-error",
                  "title": "Internal Server Error",
                  "status": 500
                }
              }
            }
          },
          "default": {
            "description": "Server error — see ProblemDetails for trace ID.",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            },
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/XRateLimitLimit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/XRateLimitRemaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/XRateLimitReset"
              }
            }
          }
        },
        "x-codeSamples": [
          {
            "lang": "cURL",
            "label": "cURL",
            "source": "curl -X GET \"https://api.kangopenbanking.com/v1/banks/{bankId}/reconciliation\" \\\n  -H \"Authorization: Bearer $KOB_API_KEY\" \\\n  -H \"X-Request-Id: $(uuidgen)\""
          },
          {
            "lang": "JavaScript",
            "label": "Node.js",
            "source": "import { KangClient } from '@kangopenbanking/sdk';\n\nconst kang = new KangClient({ apiKey: process.env.KOB_API_KEY });\n\nconst response = await kang.request({\n  method: 'GET',\n  path: '/v1/banks/{bankId}/reconciliation',\n});\n\nconsole.log(response.data);"
          },
          {
            "lang": "Python",
            "label": "Python",
            "source": "from kangopenbanking import Kang\nimport os, uuid\n\nkang = Kang(api_key=os.environ[\"KOB_API_KEY\"])\n\nresponse = kang.request(\n    method=\"GET\",\n    path=\"/v1/banks/{bankId}/reconciliation\",\n)\n\nprint(response.data)"
          },
          {
            "lang": "PHP",
            "label": "PHP",
            "source": "<?php\nrequire 'vendor/autoload.php';\n\n$kang = new \\KangOpenBanking\\Client(getenv('KOB_API_KEY'));\n\n$response = $kang->request([\n    'method' => 'GET',\n    'path'   => '/v1/banks/{bankId}/reconciliation',\n]);\n\nprint_r($response->data);"
          }
        ]
      }
    },
    "/v1/banks/{bankId}/reconciliation/resolve": {
      "post": {
        "tags": [
          "BankConnectors"
        ],
        "summary": "Resolve a reconciliation case",
        "operationId": "connectorReconciliationResolve",
        "description": "Resolve a reconciliation mismatch with a manual decision (accept_bank, accept_kob, write_off, retry, escalate). Audited.",
        "security": [
          {
            "bearerAuth": []
          },
          {
            "oauth2": [
              "banking:write"
            ]
          }
        ],
        "parameters": [
          {
            "name": "bankId",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          },
          {
            "$ref": "#/components/parameters/RequestId"
          },
          {
            "$ref": "#/components/parameters/Traceparent"
          },
          {
            "$ref": "#/components/parameters/Tracestate"
          },
          {
            "$ref": "#/components/parameters/AcceptLanguage"
          }
        ],
        "responses": {
          "200": {
            "description": "Success",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                },
                "examples": {
                  "default": {
                    "$ref": "#/components/examples/GenericSuccess"
                  }
                }
              }
            },
            "headers": {
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/XRateLimitLimit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/XRateLimitRemaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/XRateLimitReset"
              },
              "x-fapi-interaction-id": {
                "$ref": "#/components/headers/XFapiInteractionId"
              },
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              },
              "traceparent": {
                "$ref": "#/components/headers/Traceparent"
              },
              "Content-Language": {
                "$ref": "#/components/headers/Content-Language"
              }
            }
          },
          "400": {
            "description": "Bad Request",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                },
                "example": {
                  "type": "https://api.kangopenbanking.com/v1/errors/validation-error",
                  "title": "Validation Error",
                  "status": 400
                }
              },
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                },
                "example": {
                  "type": "https://api.kangopenbanking.com/v1/errors/validation-error",
                  "title": "Validation Error",
                  "status": 400
                }
              }
            },
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/XRateLimitLimit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/XRateLimitRemaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/XRateLimitReset"
              }
            }
          },
          "401": {
            "description": "Unauthorized",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                },
                "example": {
                  "type": "https://api.kangopenbanking.com/v1/errors/unauthorized",
                  "title": "Unauthorized",
                  "status": 401
                }
              },
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                },
                "example": {
                  "type": "https://api.kangopenbanking.com/v1/errors/unauthorized",
                  "title": "Unauthorized",
                  "status": 401
                }
              }
            },
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/XRateLimitLimit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/XRateLimitRemaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/XRateLimitReset"
              }
            }
          },
          "403": {
            "description": "Forbidden",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                },
                "examples": {
                  "error": {
                    "$ref": "#/components/examples/ErrorForbidden"
                  }
                }
              },
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            },
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/XRateLimitLimit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/XRateLimitRemaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/XRateLimitReset"
              }
            }
          },
          "404": {
            "description": "Not Found",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                },
                "examples": {
                  "error": {
                    "$ref": "#/components/examples/ErrorNotFound"
                  }
                }
              },
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            },
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/XRateLimitLimit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/XRateLimitRemaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/XRateLimitReset"
              }
            }
          },
          "409": {
            "$ref": "#/components/responses/Conflict",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "429": {
            "$ref": "#/components/responses/TooManyRequests",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "500": {
            "description": "500 Internal Server Error — an unexpected condition prevented completion.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                },
                "example": {
                  "type": "https://api.kangopenbanking.com/v1/errors/internal-error",
                  "title": "Internal Server Error",
                  "status": 500
                }
              },
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                },
                "example": {
                  "type": "https://api.kangopenbanking.com/v1/errors/internal-error",
                  "title": "Internal Server Error",
                  "status": 500
                }
              }
            }
          },
          "default": {
            "description": "Server error — see ProblemDetails for trace ID.",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            },
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/XRateLimitLimit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/XRateLimitRemaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/XRateLimitReset"
              }
            }
          }
        },
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "required": [
                  "case_id",
                  "resolution"
                ],
                "properties": {
                  "case_id": {
                    "type": "string",
                    "format": "uuid"
                  },
                  "resolution": {
                    "type": "string",
                    "enum": [
                      "accept_bank",
                      "accept_kob",
                      "write_off",
                      "retry",
                      "escalate"
                    ]
                  },
                  "notes": {
                    "type": "string",
                    "maxLength": 2000
                  }
                }
              }
            }
          }
        },
        "x-codeSamples": [
          {
            "lang": "cURL",
            "label": "cURL",
            "source": "curl -X POST \"https://api.kangopenbanking.com/v1/banks/{bankId}/reconciliation/resolve\" \\\n  -H \"Authorization: Bearer $KOB_API_KEY\" \\\n  -H \"X-Request-Id: $(uuidgen)\" \\\n  -H \"Idempotency-Key: $(uuidgen)\" \\\n  -H \"Content-Type: application/json\" \\\n  -d '{\"amount\":\"5000\",\"currency\":\"XAF\"}'"
          },
          {
            "lang": "JavaScript",
            "label": "Node.js",
            "source": "import { KangClient } from '@kangopenbanking/sdk';\n\nconst kang = new KangClient({ apiKey: process.env.KOB_API_KEY });\n\nconst response = await kang.request({\n  method: 'POST',\n  path: '/v1/banks/{bankId}/reconciliation/resolve',\n  body: { amount: '5000', currency: 'XAF' },\n  idempotencyKey: crypto.randomUUID(),\n});\n\nconsole.log(response.data);"
          },
          {
            "lang": "Python",
            "label": "Python",
            "source": "from kangopenbanking import Kang\nimport os, uuid\n\nkang = Kang(api_key=os.environ[\"KOB_API_KEY\"])\n\nresponse = kang.request(\n    method=\"POST\",\n    path=\"/v1/banks/{bankId}/reconciliation/resolve\",\n    body={\"amount\": \"5000\", \"currency\": \"XAF\"},\n    idempotency_key=str(uuid.uuid4()),\n)\n\nprint(response.data)"
          },
          {
            "lang": "PHP",
            "label": "PHP",
            "source": "<?php\nrequire 'vendor/autoload.php';\n\n$kang = new \\KangOpenBanking\\Client(getenv('KOB_API_KEY'));\n\n$response = $kang->request([\n    'method' => 'POST',\n    'path'   => '/v1/banks/{bankId}/reconciliation/resolve',\n    'body'   => ['amount' => '5000', 'currency' => 'XAF'],\n    'idempotency_key' => \\Ramsey\\Uuid\\Uuid::uuid4()->toString(),\n]);\n\nprint_r($response->data);"
          }
        ]
      }
    },
    "/v1/merchants/api-keys/{keyId}": {
      "get": {
        "tags": [
          "Merchants"
        ],
        "summary": "Get API key",
        "operationId": "merchantApiKeyGet",
        "description": "Retrieve metadata for a single API key (never the plaintext secret — secrets are shown one-time at creation per cryptographic-and-api-key-governance).",
        "security": [
          {
            "bearerAuth": []
          },
          {
            "oauth2": [
              "merchants:read"
            ]
          }
        ],
        "parameters": [
          {
            "name": "keyId",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          },
          {
            "$ref": "#/components/parameters/RequestId"
          },
          {
            "$ref": "#/components/parameters/Traceparent"
          },
          {
            "$ref": "#/components/parameters/Tracestate"
          },
          {
            "$ref": "#/components/parameters/AcceptLanguage"
          }
        ],
        "responses": {
          "200": {
            "description": "Success",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                },
                "examples": {
                  "default": {
                    "$ref": "#/components/examples/GenericSuccess"
                  }
                }
              }
            },
            "headers": {
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/XRateLimitLimit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/XRateLimitRemaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/XRateLimitReset"
              },
              "x-fapi-interaction-id": {
                "$ref": "#/components/headers/XFapiInteractionId"
              },
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              },
              "traceparent": {
                "$ref": "#/components/headers/Traceparent"
              },
              "Content-Language": {
                "$ref": "#/components/headers/Content-Language"
              }
            }
          },
          "400": {
            "description": "Bad Request",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                },
                "example": {
                  "type": "https://api.kangopenbanking.com/v1/errors/validation-error",
                  "title": "Validation Error",
                  "status": 400
                }
              },
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                },
                "example": {
                  "type": "https://api.kangopenbanking.com/v1/errors/validation-error",
                  "title": "Validation Error",
                  "status": 400
                }
              }
            },
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/XRateLimitLimit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/XRateLimitRemaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/XRateLimitReset"
              }
            }
          },
          "401": {
            "description": "Unauthorized",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                },
                "example": {
                  "type": "https://api.kangopenbanking.com/v1/errors/unauthorized",
                  "title": "Unauthorized",
                  "status": 401
                }
              },
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                },
                "example": {
                  "type": "https://api.kangopenbanking.com/v1/errors/unauthorized",
                  "title": "Unauthorized",
                  "status": 401
                }
              }
            },
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/XRateLimitLimit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/XRateLimitRemaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/XRateLimitReset"
              }
            }
          },
          "403": {
            "description": "Forbidden",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                },
                "examples": {
                  "error": {
                    "$ref": "#/components/examples/ErrorForbidden"
                  }
                }
              },
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            },
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/XRateLimitLimit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/XRateLimitRemaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/XRateLimitReset"
              }
            }
          },
          "404": {
            "description": "Not Found",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                },
                "examples": {
                  "error": {
                    "$ref": "#/components/examples/ErrorNotFound"
                  }
                }
              },
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            },
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/XRateLimitLimit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/XRateLimitRemaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/XRateLimitReset"
              }
            }
          },
          "429": {
            "$ref": "#/components/responses/TooManyRequests",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "500": {
            "description": "500 Internal Server Error — an unexpected condition prevented completion.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                },
                "example": {
                  "type": "https://api.kangopenbanking.com/v1/errors/internal-error",
                  "title": "Internal Server Error",
                  "status": 500
                }
              },
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                },
                "example": {
                  "type": "https://api.kangopenbanking.com/v1/errors/internal-error",
                  "title": "Internal Server Error",
                  "status": 500
                }
              }
            }
          },
          "default": {
            "description": "Server error — see ProblemDetails for trace ID.",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            },
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/XRateLimitLimit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/XRateLimitRemaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/XRateLimitReset"
              }
            }
          }
        },
        "x-codeSamples": [
          {
            "lang": "cURL",
            "label": "cURL",
            "source": "curl -X GET \"https://api.kangopenbanking.com/v1/merchants/api-keys/{keyId}\" \\\n  -H \"Authorization: Bearer $KOB_API_KEY\" \\\n  -H \"X-Request-Id: $(uuidgen)\""
          },
          {
            "lang": "JavaScript",
            "label": "Node.js",
            "source": "import { KangClient } from '@kangopenbanking/sdk';\n\nconst kang = new KangClient({ apiKey: process.env.KOB_API_KEY });\n\nconst response = await kang.request({\n  method: 'GET',\n  path: '/v1/merchants/api-keys/{keyId}',\n});\n\nconsole.log(response.data);"
          },
          {
            "lang": "Python",
            "label": "Python",
            "source": "from kangopenbanking import Kang\nimport os, uuid\n\nkang = Kang(api_key=os.environ[\"KOB_API_KEY\"])\n\nresponse = kang.request(\n    method=\"GET\",\n    path=\"/v1/merchants/api-keys/{keyId}\",\n)\n\nprint(response.data)"
          },
          {
            "lang": "PHP",
            "label": "PHP",
            "source": "<?php\nrequire 'vendor/autoload.php';\n\n$kang = new \\KangOpenBanking\\Client(getenv('KOB_API_KEY'));\n\n$response = $kang->request([\n    'method' => 'GET',\n    'path'   => '/v1/merchants/api-keys/{keyId}',\n]);\n\nprint_r($response->data);"
          }
        ]
      },
      "delete": {
        "tags": [
          "Merchants"
        ],
        "summary": "Revoke API key",
        "operationId": "merchantApiKeyRevoke",
        "description": "Permanently revoke an API key. Subsequent requests using the key receive 401 invalid_key.",
        "security": [
          {
            "bearerAuth": []
          },
          {
            "oauth2": [
              "merchants:write"
            ]
          }
        ],
        "parameters": [
          {
            "name": "keyId",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          },
          {
            "$ref": "#/components/parameters/IdempotencyKey"
          },
          {
            "$ref": "#/components/parameters/RequestId"
          },
          {
            "$ref": "#/components/parameters/Traceparent"
          },
          {
            "$ref": "#/components/parameters/Tracestate"
          },
          {
            "$ref": "#/components/parameters/AcceptLanguage"
          }
        ],
        "responses": {
          "200": {
            "description": "Success",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                },
                "examples": {
                  "default": {
                    "$ref": "#/components/examples/GenericSuccess"
                  }
                }
              }
            },
            "headers": {
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/XRateLimitLimit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/XRateLimitRemaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/XRateLimitReset"
              },
              "x-fapi-interaction-id": {
                "$ref": "#/components/headers/XFapiInteractionId"
              },
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              },
              "traceparent": {
                "$ref": "#/components/headers/Traceparent"
              },
              "Content-Language": {
                "$ref": "#/components/headers/Content-Language"
              }
            }
          },
          "400": {
            "description": "Bad Request",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                },
                "example": {
                  "type": "https://api.kangopenbanking.com/v1/errors/validation-error",
                  "title": "Validation Error",
                  "status": 400
                }
              },
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                },
                "example": {
                  "type": "https://api.kangopenbanking.com/v1/errors/validation-error",
                  "title": "Validation Error",
                  "status": 400
                }
              }
            },
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/XRateLimitLimit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/XRateLimitRemaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/XRateLimitReset"
              }
            }
          },
          "401": {
            "description": "Unauthorized",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                },
                "example": {
                  "type": "https://api.kangopenbanking.com/v1/errors/unauthorized",
                  "title": "Unauthorized",
                  "status": 401
                }
              },
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                },
                "example": {
                  "type": "https://api.kangopenbanking.com/v1/errors/unauthorized",
                  "title": "Unauthorized",
                  "status": 401
                }
              }
            },
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/XRateLimitLimit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/XRateLimitRemaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/XRateLimitReset"
              }
            }
          },
          "403": {
            "description": "Forbidden",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                },
                "examples": {
                  "error": {
                    "$ref": "#/components/examples/ErrorForbidden"
                  }
                }
              },
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            },
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/XRateLimitLimit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/XRateLimitRemaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/XRateLimitReset"
              }
            }
          },
          "404": {
            "description": "Not Found",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                },
                "examples": {
                  "error": {
                    "$ref": "#/components/examples/ErrorNotFound"
                  }
                }
              },
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            },
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/XRateLimitLimit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/XRateLimitRemaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/XRateLimitReset"
              }
            }
          },
          "409": {
            "$ref": "#/components/responses/Conflict",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "429": {
            "$ref": "#/components/responses/TooManyRequests",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "500": {
            "description": "500 Internal Server Error — an unexpected condition prevented completion.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                },
                "example": {
                  "type": "https://api.kangopenbanking.com/v1/errors/internal-error",
                  "title": "Internal Server Error",
                  "status": 500
                }
              },
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                },
                "example": {
                  "type": "https://api.kangopenbanking.com/v1/errors/internal-error",
                  "title": "Internal Server Error",
                  "status": 500
                }
              }
            }
          },
          "default": {
            "description": "Server error — see ProblemDetails for trace ID.",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            },
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/XRateLimitLimit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/XRateLimitRemaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/XRateLimitReset"
              }
            }
          }
        },
        "x-codeSamples": [
          {
            "lang": "cURL",
            "label": "cURL",
            "source": "curl -X DELETE \"https://api.kangopenbanking.com/v1/merchants/api-keys/{keyId}\" \\\n  -H \"Authorization: Bearer $KOB_API_KEY\" \\\n  -H \"X-Request-Id: $(uuidgen)\""
          },
          {
            "lang": "JavaScript",
            "label": "Node.js",
            "source": "import { KangClient } from '@kangopenbanking/sdk';\n\nconst kang = new KangClient({ apiKey: process.env.KOB_API_KEY });\n\nconst response = await kang.request({\n  method: 'DELETE',\n  path: '/v1/merchants/api-keys/{keyId}',\n});\n\nconsole.log(response.data);"
          },
          {
            "lang": "Python",
            "label": "Python",
            "source": "from kangopenbanking import Kang\nimport os, uuid\n\nkang = Kang(api_key=os.environ[\"KOB_API_KEY\"])\n\nresponse = kang.request(\n    method=\"DELETE\",\n    path=\"/v1/merchants/api-keys/{keyId}\",\n)\n\nprint(response.data)"
          },
          {
            "lang": "PHP",
            "label": "PHP",
            "source": "<?php\nrequire 'vendor/autoload.php';\n\n$kang = new \\KangOpenBanking\\Client(getenv('KOB_API_KEY'));\n\n$response = $kang->request([\n    'method' => 'DELETE',\n    'path'   => '/v1/merchants/api-keys/{keyId}',\n]);\n\nprint_r($response->data);"
          }
        ]
      }
    },
    "/v1/merchants/api-keys/{keyId}/rotate": {
      "post": {
        "tags": [
          "Merchants"
        ],
        "summary": "Rotate API key",
        "operationId": "merchantApiKeyRotate",
        "description": "Rotate the secret for an existing API key. Returns the new plaintext secret exactly once. The previous secret is revoked immediately. Justification: NIST SP 800-57 Part 1 §5.3 (cryptoperiod bounding).",
        "security": [
          {
            "bearerAuth": []
          },
          {
            "oauth2": [
              "merchants:write"
            ]
          }
        ],
        "parameters": [
          {
            "name": "keyId",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          },
          {
            "$ref": "#/components/parameters/RequestId"
          },
          {
            "$ref": "#/components/parameters/Traceparent"
          },
          {
            "$ref": "#/components/parameters/Tracestate"
          },
          {
            "$ref": "#/components/parameters/AcceptLanguage"
          }
        ],
        "responses": {
          "200": {
            "description": "Rotated",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "required": [
                    "key_id",
                    "public_key",
                    "secret_key",
                    "rotated_at"
                  ],
                  "properties": {
                    "key_id": {
                      "type": "string",
                      "format": "uuid"
                    },
                    "public_key": {
                      "type": "string"
                    },
                    "secret_key": {
                      "type": "string",
                      "description": "Plaintext secret — shown ONCE; store securely."
                    },
                    "rotated_at": {
                      "type": "string",
                      "format": "date-time"
                    }
                  }
                },
                "examples": {
                  "default": {
                    "summary": "Successful response envelope",
                    "value": {
                      "key_id": "3f1a6b52-9c84-4d2e-8f77-1b0c5a9e4d31",
                      "public_key": "public_key_value",
                      "secret_key": "secret_key_value",
                      "rotated_at": "2026-05-02T10:15:30Z",
                      "success": true,
                      "data": {
                        "id": "obj_01HZX9TRJ4M7YQK6P3W2VBDN5K",
                        "object": "resource",
                        "created_at": "2026-05-02T10:15:30Z"
                      },
                      "meta": {
                        "request_id": "7d1f0a1c-2b4e-4f6a-9c3d-5e8f0a1b2c3d",
                        "timestamp": "2026-05-02T10:15:30Z"
                      }
                    }
                  }
                }
              }
            },
            "headers": {
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/XRateLimitLimit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/XRateLimitRemaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/XRateLimitReset"
              },
              "x-fapi-interaction-id": {
                "$ref": "#/components/headers/XFapiInteractionId"
              },
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              },
              "traceparent": {
                "$ref": "#/components/headers/Traceparent"
              },
              "Content-Language": {
                "$ref": "#/components/headers/Content-Language"
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/BadRequest",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "401": {
            "description": "Unauthorized",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                },
                "example": {
                  "type": "https://api.kangopenbanking.com/v1/errors/unauthorized",
                  "title": "Unauthorized",
                  "status": 401
                }
              },
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                },
                "example": {
                  "type": "https://api.kangopenbanking.com/v1/errors/unauthorized",
                  "title": "Unauthorized",
                  "status": 401
                }
              }
            },
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/XRateLimitLimit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/XRateLimitRemaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/XRateLimitReset"
              }
            }
          },
          "404": {
            "description": "Not Found",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                },
                "examples": {
                  "error": {
                    "$ref": "#/components/examples/ErrorNotFound"
                  }
                }
              },
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            },
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/XRateLimitLimit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/XRateLimitRemaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/XRateLimitReset"
              }
            }
          },
          "409": {
            "$ref": "#/components/responses/Conflict",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "429": {
            "$ref": "#/components/responses/TooManyRequests",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "500": {
            "description": "500 Internal Server Error — an unexpected condition prevented completion.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                },
                "example": {
                  "type": "https://api.kangopenbanking.com/v1/errors/internal-error",
                  "title": "Internal Server Error",
                  "status": 500
                }
              },
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                },
                "example": {
                  "type": "https://api.kangopenbanking.com/v1/errors/internal-error",
                  "title": "Internal Server Error",
                  "status": 500
                }
              }
            }
          },
          "default": {
            "description": "Server error — see ProblemDetails for trace ID.",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            },
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/XRateLimitLimit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/XRateLimitRemaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/XRateLimitReset"
              }
            }
          }
        },
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "reason": {
                    "type": "string",
                    "maxLength": 500
                  }
                }
              }
            }
          }
        },
        "x-codeSamples": [
          {
            "lang": "cURL",
            "label": "cURL",
            "source": "curl -X POST \"https://api.kangopenbanking.com/v1/merchants/api-keys/{keyId}/rotate\" \\\n  -H \"Authorization: Bearer $KOB_API_KEY\" \\\n  -H \"X-Request-Id: $(uuidgen)\" \\\n  -H \"Idempotency-Key: $(uuidgen)\" \\\n  -H \"Content-Type: application/json\" \\\n  -d '{\"amount\":\"5000\",\"currency\":\"XAF\"}'"
          },
          {
            "lang": "JavaScript",
            "label": "Node.js",
            "source": "import { KangClient } from '@kangopenbanking/sdk';\n\nconst kang = new KangClient({ apiKey: process.env.KOB_API_KEY });\n\nconst response = await kang.request({\n  method: 'POST',\n  path: '/v1/merchants/api-keys/{keyId}/rotate',\n  body: { amount: '5000', currency: 'XAF' },\n  idempotencyKey: crypto.randomUUID(),\n});\n\nconsole.log(response.data);"
          },
          {
            "lang": "Python",
            "label": "Python",
            "source": "from kangopenbanking import Kang\nimport os, uuid\n\nkang = Kang(api_key=os.environ[\"KOB_API_KEY\"])\n\nresponse = kang.request(\n    method=\"POST\",\n    path=\"/v1/merchants/api-keys/{keyId}/rotate\",\n    body={\"amount\": \"5000\", \"currency\": \"XAF\"},\n    idempotency_key=str(uuid.uuid4()),\n)\n\nprint(response.data)"
          },
          {
            "lang": "PHP",
            "label": "PHP",
            "source": "<?php\nrequire 'vendor/autoload.php';\n\n$kang = new \\KangOpenBanking\\Client(getenv('KOB_API_KEY'));\n\n$response = $kang->request([\n    'method' => 'POST',\n    'path'   => '/v1/merchants/api-keys/{keyId}/rotate',\n    'body'   => ['amount' => '5000', 'currency' => 'XAF'],\n    'idempotency_key' => \\Ramsey\\Uuid\\Uuid::uuid4()->toString(),\n]);\n\nprint_r($response->data);"
          }
        ]
      }
    },
    "/v1/merchants/webhooks/{webhookId}": {
      "get": {
        "tags": [
          "Merchants"
        ],
        "summary": "Get webhook endpoint",
        "operationId": "merchantWebhookGet",
        "description": "**Deprecated.** Use Webhooks v2 (`/v1/webhooks/v2/endpoints`). Sunset: 2026-12-31.\n\nGet webhook endpoint.\n\n**Tag:** Merchants\n\nAuthenticate with a bearer token issued by `/v1/oauth/token`. All state-changing requests\n(POST, PUT, PATCH, DELETE) MUST include an `Idempotency-Key` header (UUID v4) to make\nretries safe — Kang will return the original response for any duplicate key within 24 hours.\n\nErrors follow [RFC 7807](https://datatracker.ietf.org/doc/html/rfc7807) and are returned with\n`Content-Type: application/problem+json`. The `code` field is stable and machine-readable.\nRate-limit headers (`X-RateLimit-Limit`, `X-RateLimit-Remaining`, `X-RateLimit-Reset`)\nare present on every response.\n\n**Migration:** Replace with `webhookV2List`. Move the endpoint to Webhooks v2 and verify the timestamped `X-Webhook-Signature` described in the webhook definitions.",
        "security": [
          {
            "bearerAuth": []
          },
          {
            "oauth2": [
              "merchants:read"
            ]
          }
        ],
        "parameters": [
          {
            "name": "webhookId",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          },
          {
            "$ref": "#/components/parameters/RequestId"
          },
          {
            "$ref": "#/components/parameters/Traceparent"
          },
          {
            "$ref": "#/components/parameters/Tracestate"
          },
          {
            "$ref": "#/components/parameters/AcceptLanguage"
          }
        ],
        "responses": {
          "200": {
            "description": "Success",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                },
                "examples": {
                  "default": {
                    "$ref": "#/components/examples/GenericSuccess"
                  }
                }
              }
            },
            "headers": {
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/XRateLimitLimit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/XRateLimitRemaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/XRateLimitReset"
              },
              "x-fapi-interaction-id": {
                "$ref": "#/components/headers/XFapiInteractionId"
              },
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              },
              "traceparent": {
                "$ref": "#/components/headers/Traceparent"
              },
              "Content-Language": {
                "$ref": "#/components/headers/Content-Language"
              }
            }
          },
          "400": {
            "description": "Bad Request",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                },
                "example": {
                  "type": "https://api.kangopenbanking.com/v1/errors/validation-error",
                  "title": "Validation Error",
                  "status": 400
                }
              },
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                },
                "example": {
                  "type": "https://api.kangopenbanking.com/v1/errors/validation-error",
                  "title": "Validation Error",
                  "status": 400
                }
              }
            },
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/XRateLimitLimit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/XRateLimitRemaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/XRateLimitReset"
              }
            }
          },
          "401": {
            "description": "Unauthorized",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                },
                "example": {
                  "type": "https://api.kangopenbanking.com/v1/errors/unauthorized",
                  "title": "Unauthorized",
                  "status": 401
                }
              },
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                },
                "example": {
                  "type": "https://api.kangopenbanking.com/v1/errors/unauthorized",
                  "title": "Unauthorized",
                  "status": 401
                }
              }
            },
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/XRateLimitLimit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/XRateLimitRemaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/XRateLimitReset"
              }
            }
          },
          "403": {
            "description": "Forbidden",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                },
                "examples": {
                  "error": {
                    "$ref": "#/components/examples/ErrorForbidden"
                  }
                }
              },
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            },
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/XRateLimitLimit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/XRateLimitRemaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/XRateLimitReset"
              }
            }
          },
          "404": {
            "description": "Not Found",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                },
                "examples": {
                  "error": {
                    "$ref": "#/components/examples/ErrorNotFound"
                  }
                }
              },
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            },
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/XRateLimitLimit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/XRateLimitRemaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/XRateLimitReset"
              }
            }
          },
          "429": {
            "$ref": "#/components/responses/TooManyRequests",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "500": {
            "description": "500 Internal Server Error — an unexpected condition prevented completion.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                },
                "example": {
                  "type": "https://api.kangopenbanking.com/v1/errors/internal-error",
                  "title": "Internal Server Error",
                  "status": 500
                }
              },
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                },
                "example": {
                  "type": "https://api.kangopenbanking.com/v1/errors/internal-error",
                  "title": "Internal Server Error",
                  "status": 500
                }
              }
            }
          },
          "default": {
            "description": "Server error — see ProblemDetails for trace ID.",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            },
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/XRateLimitLimit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/XRateLimitRemaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/XRateLimitReset"
              }
            }
          }
        },
        "x-codeSamples": [
          {
            "lang": "cURL",
            "label": "cURL",
            "source": "curl -X GET \"https://api.kangopenbanking.com/v1/merchants/webhooks/{webhookId}\" \\\n  -H \"Authorization: Bearer $KOB_API_KEY\" \\\n  -H \"X-Request-Id: $(uuidgen)\""
          },
          {
            "lang": "JavaScript",
            "label": "Node.js",
            "source": "import { KangClient } from '@kangopenbanking/sdk';\n\nconst kang = new KangClient({ apiKey: process.env.KOB_API_KEY });\n\nconst response = await kang.request({\n  method: 'GET',\n  path: '/v1/merchants/webhooks/{webhookId}',\n});\n\nconsole.log(response.data);"
          },
          {
            "lang": "Python",
            "label": "Python",
            "source": "from kangopenbanking import Kang\nimport os, uuid\n\nkang = Kang(api_key=os.environ[\"KOB_API_KEY\"])\n\nresponse = kang.request(\n    method=\"GET\",\n    path=\"/v1/merchants/webhooks/{webhookId}\",\n)\n\nprint(response.data)"
          },
          {
            "lang": "PHP",
            "label": "PHP",
            "source": "<?php\nrequire 'vendor/autoload.php';\n\n$kang = new \\KangOpenBanking\\Client(getenv('KOB_API_KEY'));\n\n$response = $kang->request([\n    'method' => 'GET',\n    'path'   => '/v1/merchants/webhooks/{webhookId}',\n]);\n\nprint_r($response->data);"
          }
        ],
        "deprecated": true,
        "x-sunset-date": "2026-12-31",
        "x-successor": "/v1/webhooks/v2/endpoints",
        "x-replacement-operation-ids": [
          "webhookV2List"
        ],
        "x-migration-guide": "Move the endpoint to Webhooks v2 and verify the timestamped `X-Webhook-Signature` described in the webhook definitions."
      },
      "patch": {
        "tags": [
          "Merchants"
        ],
        "summary": "Update webhook endpoint",
        "operationId": "merchantWebhookUpdate",
        "description": "**Deprecated.** Use Webhooks v2 (`/v1/webhooks/v2/endpoints`). Sunset: 2026-12-31.\n\nUpdate URL, subscribed events, or active flag. Secret rotation uses /rotate-secret.\n\n**Migration:** Replace with `webhookV2Update`. Move the endpoint to Webhooks v2 and verify the timestamped `X-Webhook-Signature` described in the webhook definitions.",
        "security": [
          {
            "bearerAuth": []
          },
          {
            "oauth2": [
              "merchants:write"
            ]
          }
        ],
        "parameters": [
          {
            "name": "webhookId",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          },
          {
            "$ref": "#/components/parameters/RequestId"
          },
          {
            "$ref": "#/components/parameters/Traceparent"
          },
          {
            "$ref": "#/components/parameters/Tracestate"
          },
          {
            "$ref": "#/components/parameters/AcceptLanguage"
          }
        ],
        "responses": {
          "200": {
            "description": "Success",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                },
                "examples": {
                  "default": {
                    "$ref": "#/components/examples/GenericSuccess"
                  }
                }
              }
            },
            "headers": {
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/XRateLimitLimit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/XRateLimitRemaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/XRateLimitReset"
              },
              "x-fapi-interaction-id": {
                "$ref": "#/components/headers/XFapiInteractionId"
              },
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              },
              "traceparent": {
                "$ref": "#/components/headers/Traceparent"
              },
              "Content-Language": {
                "$ref": "#/components/headers/Content-Language"
              }
            }
          },
          "400": {
            "description": "Bad Request",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                },
                "example": {
                  "type": "https://api.kangopenbanking.com/v1/errors/validation-error",
                  "title": "Validation Error",
                  "status": 400
                }
              },
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                },
                "example": {
                  "type": "https://api.kangopenbanking.com/v1/errors/validation-error",
                  "title": "Validation Error",
                  "status": 400
                }
              }
            },
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/XRateLimitLimit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/XRateLimitRemaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/XRateLimitReset"
              }
            }
          },
          "401": {
            "description": "Unauthorized",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                },
                "example": {
                  "type": "https://api.kangopenbanking.com/v1/errors/unauthorized",
                  "title": "Unauthorized",
                  "status": 401
                }
              },
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                },
                "example": {
                  "type": "https://api.kangopenbanking.com/v1/errors/unauthorized",
                  "title": "Unauthorized",
                  "status": 401
                }
              }
            },
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/XRateLimitLimit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/XRateLimitRemaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/XRateLimitReset"
              }
            }
          },
          "403": {
            "description": "Forbidden",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                },
                "examples": {
                  "error": {
                    "$ref": "#/components/examples/ErrorForbidden"
                  }
                }
              },
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            },
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/XRateLimitLimit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/XRateLimitRemaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/XRateLimitReset"
              }
            }
          },
          "404": {
            "description": "Not Found",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                },
                "examples": {
                  "error": {
                    "$ref": "#/components/examples/ErrorNotFound"
                  }
                }
              },
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            },
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/XRateLimitLimit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/XRateLimitRemaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/XRateLimitReset"
              }
            }
          },
          "409": {
            "$ref": "#/components/responses/Conflict",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "429": {
            "$ref": "#/components/responses/TooManyRequests",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "500": {
            "description": "500 Internal Server Error — an unexpected condition prevented completion.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                },
                "example": {
                  "type": "https://api.kangopenbanking.com/v1/errors/internal-error",
                  "title": "Internal Server Error",
                  "status": 500
                }
              },
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                },
                "example": {
                  "type": "https://api.kangopenbanking.com/v1/errors/internal-error",
                  "title": "Internal Server Error",
                  "status": 500
                }
              }
            }
          },
          "default": {
            "description": "Server error — see ProblemDetails for trace ID.",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            },
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/XRateLimitLimit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/XRateLimitRemaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/XRateLimitReset"
              }
            }
          }
        },
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "url": {
                    "type": "string",
                    "format": "uri"
                  },
                  "events": {
                    "type": "array",
                    "items": {
                      "type": "string"
                    }
                  },
                  "active": {
                    "type": "boolean"
                  }
                }
              }
            }
          }
        },
        "x-codeSamples": [
          {
            "lang": "cURL",
            "label": "cURL",
            "source": "curl -X PATCH \"https://api.kangopenbanking.com/v1/merchants/webhooks/{webhookId}\" \\\n  -H \"Authorization: Bearer $KOB_API_KEY\" \\\n  -H \"X-Request-Id: $(uuidgen)\" \\\n  -H \"Idempotency-Key: $(uuidgen)\" \\\n  -H \"Content-Type: application/json\" \\\n  -d '{\"amount\":\"5000\",\"currency\":\"XAF\"}'"
          },
          {
            "lang": "JavaScript",
            "label": "Node.js",
            "source": "import { KangClient } from '@kangopenbanking/sdk';\n\nconst kang = new KangClient({ apiKey: process.env.KOB_API_KEY });\n\nconst response = await kang.request({\n  method: 'PATCH',\n  path: '/v1/merchants/webhooks/{webhookId}',\n  body: { amount: '5000', currency: 'XAF' },\n  idempotencyKey: crypto.randomUUID(),\n});\n\nconsole.log(response.data);"
          },
          {
            "lang": "Python",
            "label": "Python",
            "source": "from kangopenbanking import Kang\nimport os, uuid\n\nkang = Kang(api_key=os.environ[\"KOB_API_KEY\"])\n\nresponse = kang.request(\n    method=\"PATCH\",\n    path=\"/v1/merchants/webhooks/{webhookId}\",\n    body={\"amount\": \"5000\", \"currency\": \"XAF\"},\n    idempotency_key=str(uuid.uuid4()),\n)\n\nprint(response.data)"
          },
          {
            "lang": "PHP",
            "label": "PHP",
            "source": "<?php\nrequire 'vendor/autoload.php';\n\n$kang = new \\KangOpenBanking\\Client(getenv('KOB_API_KEY'));\n\n$response = $kang->request([\n    'method' => 'PATCH',\n    'path'   => '/v1/merchants/webhooks/{webhookId}',\n    'body'   => ['amount' => '5000', 'currency' => 'XAF'],\n    'idempotency_key' => \\Ramsey\\Uuid\\Uuid::uuid4()->toString(),\n]);\n\nprint_r($response->data);"
          }
        ],
        "deprecated": true,
        "x-sunset-date": "2026-12-31",
        "x-successor": "/v1/webhooks/v2/endpoints",
        "x-replacement-operation-ids": [
          "webhookV2Update"
        ],
        "x-migration-guide": "Move the endpoint to Webhooks v2 and verify the timestamped `X-Webhook-Signature` described in the webhook definitions."
      },
      "delete": {
        "tags": [
          "Merchants"
        ],
        "summary": "Delete webhook endpoint",
        "operationId": "merchantWebhookDelete",
        "description": "**Deprecated.** Use Webhooks v2 (`/v1/webhooks/v2/endpoints`). Sunset: 2026-12-31.\n\nPermanently delete a webhook endpoint. In-flight deliveries continue to retry up to max_attempts.\n\n**Migration:** Replace with `webhookV2Delete`. Move the endpoint to Webhooks v2 and verify the timestamped `X-Webhook-Signature` described in the webhook definitions.",
        "security": [
          {
            "bearerAuth": []
          },
          {
            "oauth2": [
              "merchants:write"
            ]
          }
        ],
        "parameters": [
          {
            "name": "webhookId",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          },
          {
            "$ref": "#/components/parameters/IdempotencyKey"
          },
          {
            "$ref": "#/components/parameters/RequestId"
          },
          {
            "$ref": "#/components/parameters/Traceparent"
          },
          {
            "$ref": "#/components/parameters/Tracestate"
          },
          {
            "$ref": "#/components/parameters/AcceptLanguage"
          }
        ],
        "responses": {
          "200": {
            "description": "Success",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                },
                "examples": {
                  "default": {
                    "$ref": "#/components/examples/GenericSuccess"
                  }
                }
              }
            },
            "headers": {
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/XRateLimitLimit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/XRateLimitRemaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/XRateLimitReset"
              },
              "x-fapi-interaction-id": {
                "$ref": "#/components/headers/XFapiInteractionId"
              },
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              },
              "traceparent": {
                "$ref": "#/components/headers/Traceparent"
              },
              "Content-Language": {
                "$ref": "#/components/headers/Content-Language"
              }
            }
          },
          "400": {
            "description": "Bad Request",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                },
                "example": {
                  "type": "https://api.kangopenbanking.com/v1/errors/validation-error",
                  "title": "Validation Error",
                  "status": 400
                }
              },
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                },
                "example": {
                  "type": "https://api.kangopenbanking.com/v1/errors/validation-error",
                  "title": "Validation Error",
                  "status": 400
                }
              }
            },
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/XRateLimitLimit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/XRateLimitRemaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/XRateLimitReset"
              }
            }
          },
          "401": {
            "description": "Unauthorized",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                },
                "example": {
                  "type": "https://api.kangopenbanking.com/v1/errors/unauthorized",
                  "title": "Unauthorized",
                  "status": 401
                }
              },
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                },
                "example": {
                  "type": "https://api.kangopenbanking.com/v1/errors/unauthorized",
                  "title": "Unauthorized",
                  "status": 401
                }
              }
            },
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/XRateLimitLimit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/XRateLimitRemaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/XRateLimitReset"
              }
            }
          },
          "403": {
            "description": "Forbidden",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                },
                "examples": {
                  "error": {
                    "$ref": "#/components/examples/ErrorForbidden"
                  }
                }
              },
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            },
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/XRateLimitLimit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/XRateLimitRemaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/XRateLimitReset"
              }
            }
          },
          "404": {
            "description": "Not Found",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                },
                "examples": {
                  "error": {
                    "$ref": "#/components/examples/ErrorNotFound"
                  }
                }
              },
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            },
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/XRateLimitLimit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/XRateLimitRemaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/XRateLimitReset"
              }
            }
          },
          "409": {
            "$ref": "#/components/responses/Conflict",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "429": {
            "$ref": "#/components/responses/TooManyRequests",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "500": {
            "description": "500 Internal Server Error — an unexpected condition prevented completion.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                },
                "example": {
                  "type": "https://api.kangopenbanking.com/v1/errors/internal-error",
                  "title": "Internal Server Error",
                  "status": 500
                }
              },
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                },
                "example": {
                  "type": "https://api.kangopenbanking.com/v1/errors/internal-error",
                  "title": "Internal Server Error",
                  "status": 500
                }
              }
            }
          },
          "default": {
            "description": "Server error — see ProblemDetails for trace ID.",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            },
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/XRateLimitLimit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/XRateLimitRemaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/XRateLimitReset"
              }
            }
          }
        },
        "x-codeSamples": [
          {
            "lang": "cURL",
            "label": "cURL",
            "source": "curl -X DELETE \"https://api.kangopenbanking.com/v1/merchants/webhooks/{webhookId}\" \\\n  -H \"Authorization: Bearer $KOB_API_KEY\" \\\n  -H \"X-Request-Id: $(uuidgen)\""
          },
          {
            "lang": "JavaScript",
            "label": "Node.js",
            "source": "import { KangClient } from '@kangopenbanking/sdk';\n\nconst kang = new KangClient({ apiKey: process.env.KOB_API_KEY });\n\nconst response = await kang.request({\n  method: 'DELETE',\n  path: '/v1/merchants/webhooks/{webhookId}',\n});\n\nconsole.log(response.data);"
          },
          {
            "lang": "Python",
            "label": "Python",
            "source": "from kangopenbanking import Kang\nimport os, uuid\n\nkang = Kang(api_key=os.environ[\"KOB_API_KEY\"])\n\nresponse = kang.request(\n    method=\"DELETE\",\n    path=\"/v1/merchants/webhooks/{webhookId}\",\n)\n\nprint(response.data)"
          },
          {
            "lang": "PHP",
            "label": "PHP",
            "source": "<?php\nrequire 'vendor/autoload.php';\n\n$kang = new \\KangOpenBanking\\Client(getenv('KOB_API_KEY'));\n\n$response = $kang->request([\n    'method' => 'DELETE',\n    'path'   => '/v1/merchants/webhooks/{webhookId}',\n]);\n\nprint_r($response->data);"
          }
        ],
        "deprecated": true,
        "x-sunset-date": "2026-12-31",
        "x-successor": "/v1/webhooks/v2/endpoints",
        "x-replacement-operation-ids": [
          "webhookV2Delete"
        ],
        "x-migration-guide": "Move the endpoint to Webhooks v2 and verify the timestamped `X-Webhook-Signature` described in the webhook definitions."
      }
    },
    "/v1/merchants/webhooks/{webhookId}/rotate-secret": {
      "post": {
        "tags": [
          "Merchants"
        ],
        "summary": "Rotate webhook signing secret",
        "operationId": "merchantWebhookRotateSecret",
        "description": "**Deprecated.** Use Webhooks v2 (`/v1/webhooks/v2/endpoints`). Sunset: 2026-12-31.\n\nRotate the HMAC signing secret for a webhook endpoint. The new secret is returned once. The previous secret remains valid for a 24h overlap window so receivers can roll over. Justification: webhook-governance-and-security memory + NIST SP 800-57.\n\n**Migration:** Replace with `webhookV2Update`. Move the endpoint to Webhooks v2 and verify the timestamped `X-Webhook-Signature` described in the webhook definitions.",
        "security": [
          {
            "bearerAuth": []
          },
          {
            "oauth2": [
              "merchants:write"
            ]
          }
        ],
        "parameters": [
          {
            "name": "webhookId",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          },
          {
            "$ref": "#/components/parameters/RequestId"
          },
          {
            "$ref": "#/components/parameters/Traceparent"
          },
          {
            "$ref": "#/components/parameters/Tracestate"
          },
          {
            "$ref": "#/components/parameters/AcceptLanguage"
          }
        ],
        "responses": {
          "200": {
            "description": "Rotated",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "required": [
                    "webhook_id",
                    "secret",
                    "rotated_at",
                    "previous_secret_valid_until"
                  ],
                  "properties": {
                    "webhook_id": {
                      "type": "string",
                      "format": "uuid"
                    },
                    "secret": {
                      "type": "string",
                      "description": "New HMAC secret — shown ONCE."
                    },
                    "rotated_at": {
                      "type": "string",
                      "format": "date-time"
                    },
                    "previous_secret_valid_until": {
                      "type": "string",
                      "format": "date-time"
                    }
                  }
                },
                "examples": {
                  "default": {
                    "summary": "Successful response envelope",
                    "value": {
                      "webhook_id": "3f1a6b52-9c84-4d2e-8f77-1b0c5a9e4d31",
                      "secret": "secret_value",
                      "rotated_at": "2026-05-02T10:15:30Z",
                      "previous_secret_valid_until": "2026-05-02T10:15:30Z",
                      "success": true,
                      "data": {
                        "id": "obj_01HZX9TRJ4M7YQK6P3W2VBDN5K",
                        "object": "resource",
                        "created_at": "2026-05-02T10:15:30Z"
                      },
                      "meta": {
                        "request_id": "7d1f0a1c-2b4e-4f6a-9c3d-5e8f0a1b2c3d",
                        "timestamp": "2026-05-02T10:15:30Z"
                      }
                    }
                  }
                }
              }
            },
            "headers": {
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/XRateLimitLimit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/XRateLimitRemaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/XRateLimitReset"
              },
              "x-fapi-interaction-id": {
                "$ref": "#/components/headers/XFapiInteractionId"
              },
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              },
              "traceparent": {
                "$ref": "#/components/headers/Traceparent"
              },
              "Content-Language": {
                "$ref": "#/components/headers/Content-Language"
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/BadRequest",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "404": {
            "description": "Not Found",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                },
                "examples": {
                  "error": {
                    "$ref": "#/components/examples/ErrorNotFound"
                  }
                }
              },
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            },
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/XRateLimitLimit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/XRateLimitRemaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/XRateLimitReset"
              }
            }
          },
          "409": {
            "$ref": "#/components/responses/Conflict",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "429": {
            "$ref": "#/components/responses/TooManyRequests",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "500": {
            "description": "500 Internal Server Error — an unexpected condition prevented completion.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                },
                "example": {
                  "type": "https://api.kangopenbanking.com/v1/errors/internal-error",
                  "title": "Internal Server Error",
                  "status": 500
                }
              },
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                },
                "example": {
                  "type": "https://api.kangopenbanking.com/v1/errors/internal-error",
                  "title": "Internal Server Error",
                  "status": 500
                }
              }
            }
          },
          "default": {
            "description": "Server error — see ProblemDetails for trace ID.",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            },
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/XRateLimitLimit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/XRateLimitRemaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/XRateLimitReset"
              }
            }
          }
        },
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "overlap_hours": {
                    "type": "integer",
                    "minimum": 0,
                    "maximum": 72,
                    "default": 24
                  }
                }
              }
            }
          }
        },
        "x-codeSamples": [
          {
            "lang": "cURL",
            "label": "cURL",
            "source": "curl -X POST \"https://api.kangopenbanking.com/v1/merchants/webhooks/{webhookId}/rotate-secret\" \\\n  -H \"Authorization: Bearer $KOB_API_KEY\" \\\n  -H \"X-Request-Id: $(uuidgen)\" \\\n  -H \"Idempotency-Key: $(uuidgen)\" \\\n  -H \"Content-Type: application/json\" \\\n  -d '{\"amount\":\"5000\",\"currency\":\"XAF\"}'"
          },
          {
            "lang": "JavaScript",
            "label": "Node.js",
            "source": "import { KangClient } from '@kangopenbanking/sdk';\n\nconst kang = new KangClient({ apiKey: process.env.KOB_API_KEY });\n\nconst response = await kang.request({\n  method: 'POST',\n  path: '/v1/merchants/webhooks/{webhookId}/rotate-secret',\n  body: { amount: '5000', currency: 'XAF' },\n  idempotencyKey: crypto.randomUUID(),\n});\n\nconsole.log(response.data);"
          },
          {
            "lang": "Python",
            "label": "Python",
            "source": "from kangopenbanking import Kang\nimport os, uuid\n\nkang = Kang(api_key=os.environ[\"KOB_API_KEY\"])\n\nresponse = kang.request(\n    method=\"POST\",\n    path=\"/v1/merchants/webhooks/{webhookId}/rotate-secret\",\n    body={\"amount\": \"5000\", \"currency\": \"XAF\"},\n    idempotency_key=str(uuid.uuid4()),\n)\n\nprint(response.data)"
          },
          {
            "lang": "PHP",
            "label": "PHP",
            "source": "<?php\nrequire 'vendor/autoload.php';\n\n$kang = new \\KangOpenBanking\\Client(getenv('KOB_API_KEY'));\n\n$response = $kang->request([\n    'method' => 'POST',\n    'path'   => '/v1/merchants/webhooks/{webhookId}/rotate-secret',\n    'body'   => ['amount' => '5000', 'currency' => 'XAF'],\n    'idempotency_key' => \\Ramsey\\Uuid\\Uuid::uuid4()->toString(),\n]);\n\nprint_r($response->data);"
          }
        ],
        "deprecated": true,
        "x-sunset-date": "2026-12-31",
        "x-successor": "/v1/webhooks/v2/endpoints",
        "x-replacement-operation-ids": [
          "webhookV2Update"
        ],
        "x-migration-guide": "Move the endpoint to Webhooks v2 and verify the timestamped `X-Webhook-Signature` described in the webhook definitions."
      }
    },
    "/v1/merchants/webhooks/{webhookId}/deliveries": {
      "get": {
        "tags": [
          "Merchants"
        ],
        "summary": "List webhook deliveries",
        "operationId": "merchantWebhookDeliveries",
        "description": "**Deprecated.** Use Webhooks v2 (`/v1/webhooks/v2/endpoints`). Sunset: 2026-12-31.\n\nList delivery attempts for a webhook endpoint with status, response code, and retry information. Per webhook-governance-and-security: 7-attempt exponential backoff.\n\n**Migration:** Replace with `webhookV2List`. Move the endpoint to Webhooks v2 and verify the timestamped `X-Webhook-Signature` described in the webhook definitions.",
        "security": [
          {
            "bearerAuth": []
          },
          {
            "oauth2": [
              "merchants:read"
            ]
          }
        ],
        "parameters": [
          {
            "name": "webhookId",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          },
          {
            "name": "status",
            "in": "query",
            "schema": {
              "type": "string",
              "enum": [
                "pending",
                "delivered",
                "failed",
                "retrying",
                "abandoned"
              ]
            }
          },
          {
            "name": "from",
            "in": "query",
            "schema": {
              "type": "string",
              "format": "date-time"
            },
            "description": "Inclusive RFC 3339 lower bound"
          },
          {
            "name": "to",
            "in": "query",
            "schema": {
              "type": "string",
              "format": "date-time"
            },
            "description": "Exclusive RFC 3339 upper bound"
          },
          {
            "name": "limit",
            "in": "query",
            "schema": {
              "type": "integer",
              "minimum": 1,
              "maximum": 200,
              "default": 50
            }
          },
          {
            "name": "offset",
            "in": "query",
            "schema": {
              "type": "integer",
              "minimum": 0,
              "default": 0
            }
          },
          {
            "$ref": "#/components/parameters/StartingAfter"
          },
          {
            "$ref": "#/components/parameters/EndingBefore"
          },
          {
            "$ref": "#/components/parameters/RequestId"
          },
          {
            "$ref": "#/components/parameters/Traceparent"
          },
          {
            "$ref": "#/components/parameters/Tracestate"
          },
          {
            "$ref": "#/components/parameters/AcceptLanguage"
          }
        ],
        "responses": {
          "200": {
            "description": "Success",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                },
                "examples": {
                  "default": {
                    "$ref": "#/components/examples/PaginatedList"
                  }
                }
              }
            },
            "headers": {
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/XRateLimitLimit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/XRateLimitRemaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/XRateLimitReset"
              },
              "x-fapi-interaction-id": {
                "$ref": "#/components/headers/XFapiInteractionId"
              },
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              },
              "traceparent": {
                "$ref": "#/components/headers/Traceparent"
              },
              "Content-Language": {
                "$ref": "#/components/headers/Content-Language"
              }
            }
          },
          "400": {
            "description": "Bad Request",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                },
                "example": {
                  "type": "https://api.kangopenbanking.com/v1/errors/validation-error",
                  "title": "Validation Error",
                  "status": 400
                }
              },
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                },
                "example": {
                  "type": "https://api.kangopenbanking.com/v1/errors/validation-error",
                  "title": "Validation Error",
                  "status": 400
                }
              }
            },
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/XRateLimitLimit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/XRateLimitRemaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/XRateLimitReset"
              }
            }
          },
          "401": {
            "description": "Unauthorized",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                },
                "example": {
                  "type": "https://api.kangopenbanking.com/v1/errors/unauthorized",
                  "title": "Unauthorized",
                  "status": 401
                }
              },
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                },
                "example": {
                  "type": "https://api.kangopenbanking.com/v1/errors/unauthorized",
                  "title": "Unauthorized",
                  "status": 401
                }
              }
            },
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/XRateLimitLimit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/XRateLimitRemaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/XRateLimitReset"
              }
            }
          },
          "403": {
            "description": "Forbidden",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                },
                "examples": {
                  "error": {
                    "$ref": "#/components/examples/ErrorForbidden"
                  }
                }
              },
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            },
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/XRateLimitLimit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/XRateLimitRemaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/XRateLimitReset"
              }
            }
          },
          "404": {
            "description": "Not Found",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                },
                "examples": {
                  "error": {
                    "$ref": "#/components/examples/ErrorNotFound"
                  }
                }
              },
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            },
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/XRateLimitLimit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/XRateLimitRemaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/XRateLimitReset"
              }
            }
          },
          "429": {
            "$ref": "#/components/responses/TooManyRequests",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "500": {
            "description": "500 Internal Server Error — an unexpected condition prevented completion.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                },
                "example": {
                  "type": "https://api.kangopenbanking.com/v1/errors/internal-error",
                  "title": "Internal Server Error",
                  "status": 500
                }
              },
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                },
                "example": {
                  "type": "https://api.kangopenbanking.com/v1/errors/internal-error",
                  "title": "Internal Server Error",
                  "status": 500
                }
              }
            }
          },
          "default": {
            "description": "Server error — see ProblemDetails for trace ID.",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            },
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/XRateLimitLimit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/XRateLimitRemaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/XRateLimitReset"
              }
            }
          }
        },
        "x-codeSamples": [
          {
            "lang": "cURL",
            "label": "cURL",
            "source": "curl -X GET \"https://api.kangopenbanking.com/v1/merchants/webhooks/{webhookId}/deliveries\" \\\n  -H \"Authorization: Bearer $KOB_API_KEY\" \\\n  -H \"X-Request-Id: $(uuidgen)\""
          },
          {
            "lang": "JavaScript",
            "label": "Node.js",
            "source": "import { KangClient } from '@kangopenbanking/sdk';\n\nconst kang = new KangClient({ apiKey: process.env.KOB_API_KEY });\n\nconst response = await kang.request({\n  method: 'GET',\n  path: '/v1/merchants/webhooks/{webhookId}/deliveries',\n});\n\nconsole.log(response.data);"
          },
          {
            "lang": "Python",
            "label": "Python",
            "source": "from kangopenbanking import Kang\nimport os, uuid\n\nkang = Kang(api_key=os.environ[\"KOB_API_KEY\"])\n\nresponse = kang.request(\n    method=\"GET\",\n    path=\"/v1/merchants/webhooks/{webhookId}/deliveries\",\n)\n\nprint(response.data)"
          },
          {
            "lang": "PHP",
            "label": "PHP",
            "source": "<?php\nrequire 'vendor/autoload.php';\n\n$kang = new \\KangOpenBanking\\Client(getenv('KOB_API_KEY'));\n\n$response = $kang->request([\n    'method' => 'GET',\n    'path'   => '/v1/merchants/webhooks/{webhookId}/deliveries',\n]);\n\nprint_r($response->data);"
          }
        ],
        "deprecated": true,
        "x-sunset-date": "2026-12-31",
        "x-successor": "/v1/webhooks/v2/endpoints",
        "x-replacement-operation-ids": [
          "webhookV2List"
        ],
        "x-migration-guide": "Move the endpoint to Webhooks v2 and verify the timestamped `X-Webhook-Signature` described in the webhook definitions."
      }
    },
    "/v1/merchants/webhooks/{webhookId}/deliveries/{deliveryId}/replay": {
      "post": {
        "tags": [
          "Merchants"
        ],
        "summary": "Replay a webhook delivery",
        "operationId": "merchantWebhookReplayDelivery",
        "description": "**Deprecated.** Use Webhooks v2 (`/v1/webhooks/v2/endpoints`). Sunset: 2026-12-31.\n\nRe-deliver a single past event to the endpoint. Useful when receivers were temporarily down. Replay creates a new delivery attempt record.\n\n**Migration:** Replace with `webhookV2ReplayDelivery`. Move the endpoint to Webhooks v2 and verify the timestamped `X-Webhook-Signature` described in the webhook definitions.",
        "security": [
          {
            "bearerAuth": []
          },
          {
            "oauth2": [
              "merchants:write"
            ]
          }
        ],
        "parameters": [
          {
            "name": "webhookId",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          },
          {
            "name": "deliveryId",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          },
          {
            "$ref": "#/components/parameters/RequestId"
          },
          {
            "$ref": "#/components/parameters/Traceparent"
          },
          {
            "$ref": "#/components/parameters/Tracestate"
          },
          {
            "$ref": "#/components/parameters/AcceptLanguage"
          }
        ],
        "responses": {
          "200": {
            "description": "Success",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                },
                "examples": {
                  "default": {
                    "$ref": "#/components/examples/GenericSuccess"
                  }
                }
              }
            },
            "headers": {
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/XRateLimitLimit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/XRateLimitRemaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/XRateLimitReset"
              },
              "x-fapi-interaction-id": {
                "$ref": "#/components/headers/XFapiInteractionId"
              },
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              },
              "traceparent": {
                "$ref": "#/components/headers/Traceparent"
              },
              "Content-Language": {
                "$ref": "#/components/headers/Content-Language"
              }
            }
          },
          "400": {
            "description": "Bad Request",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                },
                "example": {
                  "type": "https://api.kangopenbanking.com/v1/errors/validation-error",
                  "title": "Validation Error",
                  "status": 400
                }
              },
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                },
                "example": {
                  "type": "https://api.kangopenbanking.com/v1/errors/validation-error",
                  "title": "Validation Error",
                  "status": 400
                }
              }
            },
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/XRateLimitLimit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/XRateLimitRemaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/XRateLimitReset"
              }
            }
          },
          "401": {
            "description": "Unauthorized",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                },
                "example": {
                  "type": "https://api.kangopenbanking.com/v1/errors/unauthorized",
                  "title": "Unauthorized",
                  "status": 401
                }
              },
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                },
                "example": {
                  "type": "https://api.kangopenbanking.com/v1/errors/unauthorized",
                  "title": "Unauthorized",
                  "status": 401
                }
              }
            },
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/XRateLimitLimit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/XRateLimitRemaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/XRateLimitReset"
              }
            }
          },
          "403": {
            "description": "Forbidden",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                },
                "examples": {
                  "error": {
                    "$ref": "#/components/examples/ErrorForbidden"
                  }
                }
              },
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            },
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/XRateLimitLimit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/XRateLimitRemaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/XRateLimitReset"
              }
            }
          },
          "404": {
            "description": "Not Found",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                },
                "examples": {
                  "error": {
                    "$ref": "#/components/examples/ErrorNotFound"
                  }
                }
              },
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            },
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/XRateLimitLimit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/XRateLimitRemaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/XRateLimitReset"
              }
            }
          },
          "409": {
            "$ref": "#/components/responses/Conflict",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "429": {
            "$ref": "#/components/responses/TooManyRequests",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "500": {
            "description": "500 Internal Server Error — an unexpected condition prevented completion.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                },
                "example": {
                  "type": "https://api.kangopenbanking.com/v1/errors/internal-error",
                  "title": "Internal Server Error",
                  "status": 500
                }
              },
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                },
                "example": {
                  "type": "https://api.kangopenbanking.com/v1/errors/internal-error",
                  "title": "Internal Server Error",
                  "status": 500
                }
              }
            }
          },
          "default": {
            "description": "Server error — see ProblemDetails for trace ID.",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            },
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/XRateLimitLimit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/XRateLimitRemaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/XRateLimitReset"
              }
            }
          }
        },
        "x-codeSamples": [
          {
            "lang": "cURL",
            "label": "cURL",
            "source": "curl -X POST \"https://api.kangopenbanking.com/v1/merchants/webhooks/{webhookId}/deliveries/{deliveryId}/replay\" \\\n  -H \"Authorization: Bearer $KOB_API_KEY\" \\\n  -H \"X-Request-Id: $(uuidgen)\" \\\n  -H \"Idempotency-Key: $(uuidgen)\" \\\n  -H \"Content-Type: application/json\" \\\n  -d '{\"amount\":\"5000\",\"currency\":\"XAF\"}'"
          },
          {
            "lang": "JavaScript",
            "label": "Node.js",
            "source": "import { KangClient } from '@kangopenbanking/sdk';\n\nconst kang = new KangClient({ apiKey: process.env.KOB_API_KEY });\n\nconst response = await kang.request({\n  method: 'POST',\n  path: '/v1/merchants/webhooks/{webhookId}/deliveries/{deliveryId}/replay',\n  body: { amount: '5000', currency: 'XAF' },\n  idempotencyKey: crypto.randomUUID(),\n});\n\nconsole.log(response.data);"
          },
          {
            "lang": "Python",
            "label": "Python",
            "source": "from kangopenbanking import Kang\nimport os, uuid\n\nkang = Kang(api_key=os.environ[\"KOB_API_KEY\"])\n\nresponse = kang.request(\n    method=\"POST\",\n    path=\"/v1/merchants/webhooks/{webhookId}/deliveries/{deliveryId}/replay\",\n    body={\"amount\": \"5000\", \"currency\": \"XAF\"},\n    idempotency_key=str(uuid.uuid4()),\n)\n\nprint(response.data)"
          },
          {
            "lang": "PHP",
            "label": "PHP",
            "source": "<?php\nrequire 'vendor/autoload.php';\n\n$kang = new \\KangOpenBanking\\Client(getenv('KOB_API_KEY'));\n\n$response = $kang->request([\n    'method' => 'POST',\n    'path'   => '/v1/merchants/webhooks/{webhookId}/deliveries/{deliveryId}/replay',\n    'body'   => ['amount' => '5000', 'currency' => 'XAF'],\n    'idempotency_key' => \\Ramsey\\Uuid\\Uuid::uuid4()->toString(),\n]);\n\nprint_r($response->data);"
          }
        ],
        "deprecated": true,
        "x-sunset-date": "2026-12-31",
        "x-successor": "/v1/webhooks/v2/endpoints",
        "x-replacement-operation-ids": [
          "webhookV2ReplayDelivery"
        ],
        "x-migration-guide": "Move the endpoint to Webhooks v2 and verify the timestamped `X-Webhook-Signature` described in the webhook definitions."
      }
    },
    "/v1/admin/merchants": {
      "get": {
        "tags": [
          "Admin"
        ],
        "summary": "List merchants (admin)",
        "operationId": "adminMerchantsList",
        "description": "Admin-only listing of all merchants with KYB status, environment, plan tier and last activity. Justification: COBAC supervisory access (PSD2 RTS Article 95).",
        "security": [
          {
            "bearerAuth": []
          },
          {
            "oauth2": [
              "admin:read"
            ]
          }
        ],
        "parameters": [
          {
            "name": "status",
            "in": "query",
            "schema": {
              "type": "string",
              "enum": [
                "draft",
                "pending_review",
                "active",
                "suspended",
                "terminated"
              ]
            }
          },
          {
            "name": "kyb_status",
            "in": "query",
            "schema": {
              "type": "string",
              "enum": [
                "not_submitted",
                "submitted",
                "under_review",
                "approved",
                "rejected"
              ]
            }
          },
          {
            "name": "environment",
            "in": "query",
            "schema": {
              "type": "string",
              "enum": [
                "sandbox",
                "prod"
              ],
              "default": "sandbox"
            }
          },
          {
            "name": "limit",
            "in": "query",
            "schema": {
              "type": "integer",
              "minimum": 1,
              "maximum": 200,
              "default": 50
            }
          },
          {
            "name": "offset",
            "in": "query",
            "schema": {
              "type": "integer",
              "minimum": 0,
              "default": 0
            }
          },
          {
            "name": "q",
            "in": "query",
            "schema": {
              "type": "string",
              "maxLength": 200
            },
            "description": "Search business_name / email / id"
          },
          {
            "$ref": "#/components/parameters/StartingAfter"
          },
          {
            "$ref": "#/components/parameters/EndingBefore"
          },
          {
            "$ref": "#/components/parameters/RequestId"
          },
          {
            "$ref": "#/components/parameters/Traceparent"
          },
          {
            "$ref": "#/components/parameters/Tracestate"
          },
          {
            "$ref": "#/components/parameters/AcceptLanguage"
          }
        ],
        "responses": {
          "200": {
            "description": "Success",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                },
                "examples": {
                  "default": {
                    "$ref": "#/components/examples/PaginatedList"
                  }
                }
              }
            },
            "headers": {
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/XRateLimitLimit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/XRateLimitRemaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/XRateLimitReset"
              },
              "x-fapi-interaction-id": {
                "$ref": "#/components/headers/XFapiInteractionId"
              },
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              },
              "traceparent": {
                "$ref": "#/components/headers/Traceparent"
              },
              "Content-Language": {
                "$ref": "#/components/headers/Content-Language"
              }
            }
          },
          "400": {
            "description": "Bad Request",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                },
                "example": {
                  "type": "https://api.kangopenbanking.com/v1/errors/validation-error",
                  "title": "Validation Error",
                  "status": 400
                }
              },
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                },
                "example": {
                  "type": "https://api.kangopenbanking.com/v1/errors/validation-error",
                  "title": "Validation Error",
                  "status": 400
                }
              }
            },
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/XRateLimitLimit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/XRateLimitRemaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/XRateLimitReset"
              }
            }
          },
          "401": {
            "description": "Unauthorized",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                },
                "example": {
                  "type": "https://api.kangopenbanking.com/v1/errors/unauthorized",
                  "title": "Unauthorized",
                  "status": 401
                }
              },
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                },
                "example": {
                  "type": "https://api.kangopenbanking.com/v1/errors/unauthorized",
                  "title": "Unauthorized",
                  "status": 401
                }
              }
            },
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/XRateLimitLimit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/XRateLimitRemaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/XRateLimitReset"
              }
            }
          },
          "403": {
            "description": "Forbidden",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                },
                "examples": {
                  "error": {
                    "$ref": "#/components/examples/ErrorForbidden"
                  }
                }
              },
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            },
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/XRateLimitLimit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/XRateLimitRemaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/XRateLimitReset"
              }
            }
          },
          "404": {
            "description": "Not Found",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                },
                "examples": {
                  "error": {
                    "$ref": "#/components/examples/ErrorNotFound"
                  }
                }
              },
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            },
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/XRateLimitLimit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/XRateLimitRemaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/XRateLimitReset"
              }
            }
          },
          "429": {
            "$ref": "#/components/responses/TooManyRequests",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "500": {
            "description": "500 Internal Server Error — an unexpected condition prevented completion.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                },
                "example": {
                  "type": "https://api.kangopenbanking.com/v1/errors/internal-error",
                  "title": "Internal Server Error",
                  "status": 500
                }
              },
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                },
                "example": {
                  "type": "https://api.kangopenbanking.com/v1/errors/internal-error",
                  "title": "Internal Server Error",
                  "status": 500
                }
              }
            }
          },
          "default": {
            "description": "Server error — see ProblemDetails for trace ID.",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            },
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/XRateLimitLimit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/XRateLimitRemaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/XRateLimitReset"
              }
            }
          }
        },
        "x-codeSamples": [
          {
            "lang": "cURL",
            "label": "cURL",
            "source": "curl -X GET \"https://api.kangopenbanking.com/v1/admin/merchants\" \\\n  -H \"Authorization: Bearer $KOB_API_KEY\" \\\n  -H \"X-Request-Id: $(uuidgen)\""
          },
          {
            "lang": "JavaScript",
            "label": "Node.js",
            "source": "import { KangClient } from '@kangopenbanking/sdk';\n\nconst kang = new KangClient({ apiKey: process.env.KOB_API_KEY });\n\nconst response = await kang.request({\n  method: 'GET',\n  path: '/v1/admin/merchants',\n});\n\nconsole.log(response.data);"
          },
          {
            "lang": "Python",
            "label": "Python",
            "source": "from kangopenbanking import Kang\nimport os, uuid\n\nkang = Kang(api_key=os.environ[\"KOB_API_KEY\"])\n\nresponse = kang.request(\n    method=\"GET\",\n    path=\"/v1/admin/merchants\",\n)\n\nprint(response.data)"
          },
          {
            "lang": "PHP",
            "label": "PHP",
            "source": "<?php\nrequire 'vendor/autoload.php';\n\n$kang = new \\KangOpenBanking\\Client(getenv('KOB_API_KEY'));\n\n$response = $kang->request([\n    'method' => 'GET',\n    'path'   => '/v1/admin/merchants',\n]);\n\nprint_r($response->data);"
          }
        ]
      }
    },
    "/v1/admin/kyb/queue": {
      "get": {
        "tags": [
          "Admin"
        ],
        "summary": "KYB review queue (admin)",
        "operationId": "adminKybQueue",
        "description": "Admin queue of merchants awaiting KYB review, sorted by submission time. Returns documents, risk score, sanctions screening result.",
        "security": [
          {
            "bearerAuth": []
          },
          {
            "oauth2": [
              "admin:read"
            ]
          }
        ],
        "parameters": [
          {
            "name": "priority",
            "in": "query",
            "schema": {
              "type": "string",
              "enum": [
                "low",
                "normal",
                "high",
                "urgent"
              ]
            }
          },
          {
            "name": "limit",
            "in": "query",
            "schema": {
              "type": "integer",
              "minimum": 1,
              "maximum": 200,
              "default": 50
            }
          },
          {
            "name": "offset",
            "in": "query",
            "schema": {
              "type": "integer",
              "minimum": 0,
              "default": 0
            }
          },
          {
            "$ref": "#/components/parameters/StartingAfter"
          },
          {
            "$ref": "#/components/parameters/EndingBefore"
          },
          {
            "$ref": "#/components/parameters/RequestId"
          },
          {
            "$ref": "#/components/parameters/Traceparent"
          },
          {
            "$ref": "#/components/parameters/Tracestate"
          },
          {
            "$ref": "#/components/parameters/AcceptLanguage"
          }
        ],
        "responses": {
          "200": {
            "description": "Success",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                },
                "examples": {
                  "default": {
                    "$ref": "#/components/examples/GenericSuccess"
                  }
                }
              }
            },
            "headers": {
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/XRateLimitLimit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/XRateLimitRemaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/XRateLimitReset"
              },
              "x-fapi-interaction-id": {
                "$ref": "#/components/headers/XFapiInteractionId"
              },
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              },
              "traceparent": {
                "$ref": "#/components/headers/Traceparent"
              },
              "Content-Language": {
                "$ref": "#/components/headers/Content-Language"
              }
            }
          },
          "400": {
            "description": "Bad Request",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                },
                "example": {
                  "type": "https://api.kangopenbanking.com/v1/errors/validation-error",
                  "title": "Validation Error",
                  "status": 400
                }
              },
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                },
                "example": {
                  "type": "https://api.kangopenbanking.com/v1/errors/validation-error",
                  "title": "Validation Error",
                  "status": 400
                }
              }
            },
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/XRateLimitLimit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/XRateLimitRemaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/XRateLimitReset"
              }
            }
          },
          "401": {
            "description": "Unauthorized",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                },
                "example": {
                  "type": "https://api.kangopenbanking.com/v1/errors/unauthorized",
                  "title": "Unauthorized",
                  "status": 401
                }
              },
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                },
                "example": {
                  "type": "https://api.kangopenbanking.com/v1/errors/unauthorized",
                  "title": "Unauthorized",
                  "status": 401
                }
              }
            },
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/XRateLimitLimit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/XRateLimitRemaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/XRateLimitReset"
              }
            }
          },
          "403": {
            "description": "Forbidden",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                },
                "examples": {
                  "error": {
                    "$ref": "#/components/examples/ErrorForbidden"
                  }
                }
              },
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            },
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/XRateLimitLimit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/XRateLimitRemaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/XRateLimitReset"
              }
            }
          },
          "404": {
            "description": "Not Found",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                },
                "examples": {
                  "error": {
                    "$ref": "#/components/examples/ErrorNotFound"
                  }
                }
              },
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            },
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/XRateLimitLimit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/XRateLimitRemaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/XRateLimitReset"
              }
            }
          },
          "429": {
            "$ref": "#/components/responses/TooManyRequests",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "500": {
            "description": "500 Internal Server Error — an unexpected condition prevented completion.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                },
                "example": {
                  "type": "https://api.kangopenbanking.com/v1/errors/internal-error",
                  "title": "Internal Server Error",
                  "status": 500
                }
              },
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                },
                "example": {
                  "type": "https://api.kangopenbanking.com/v1/errors/internal-error",
                  "title": "Internal Server Error",
                  "status": 500
                }
              }
            }
          },
          "default": {
            "description": "Server error — see ProblemDetails for trace ID.",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            },
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/XRateLimitLimit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/XRateLimitRemaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/XRateLimitReset"
              }
            }
          }
        },
        "x-codeSamples": [
          {
            "lang": "cURL",
            "label": "cURL",
            "source": "curl -X GET \"https://api.kangopenbanking.com/v1/admin/kyb/queue\" \\\n  -H \"Authorization: Bearer $KOB_API_KEY\" \\\n  -H \"X-Request-Id: $(uuidgen)\""
          },
          {
            "lang": "JavaScript",
            "label": "Node.js",
            "source": "import { KangClient } from '@kangopenbanking/sdk';\n\nconst kang = new KangClient({ apiKey: process.env.KOB_API_KEY });\n\nconst response = await kang.request({\n  method: 'GET',\n  path: '/v1/admin/kyb/queue',\n});\n\nconsole.log(response.data);"
          },
          {
            "lang": "Python",
            "label": "Python",
            "source": "from kangopenbanking import Kang\nimport os, uuid\n\nkang = Kang(api_key=os.environ[\"KOB_API_KEY\"])\n\nresponse = kang.request(\n    method=\"GET\",\n    path=\"/v1/admin/kyb/queue\",\n)\n\nprint(response.data)"
          },
          {
            "lang": "PHP",
            "label": "PHP",
            "source": "<?php\nrequire 'vendor/autoload.php';\n\n$kang = new \\KangOpenBanking\\Client(getenv('KOB_API_KEY'));\n\n$response = $kang->request([\n    'method' => 'GET',\n    'path'   => '/v1/admin/kyb/queue',\n]);\n\nprint_r($response->data);"
          }
        ]
      }
    },
    "/v1/admin/merchants/{merchantId}/approve": {
      "post": {
        "tags": [
          "Admin"
        ],
        "summary": "Approve merchant KYB (admin)",
        "operationId": "adminMerchantApprove",
        "description": "Approve KYB and activate merchant for production. Audited (4-eyes when configured per banking-operations-and-risk-governance).",
        "security": [
          {
            "bearerAuth": []
          },
          {
            "oauth2": [
              "admin:write"
            ]
          }
        ],
        "parameters": [
          {
            "name": "merchantId",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          },
          {
            "$ref": "#/components/parameters/RequestId"
          },
          {
            "$ref": "#/components/parameters/Traceparent"
          },
          {
            "$ref": "#/components/parameters/Tracestate"
          },
          {
            "$ref": "#/components/parameters/AcceptLanguage"
          }
        ],
        "responses": {
          "200": {
            "description": "Success",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                },
                "examples": {
                  "default": {
                    "$ref": "#/components/examples/GenericSuccess"
                  }
                }
              }
            },
            "headers": {
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/XRateLimitLimit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/XRateLimitRemaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/XRateLimitReset"
              },
              "x-fapi-interaction-id": {
                "$ref": "#/components/headers/XFapiInteractionId"
              },
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              },
              "traceparent": {
                "$ref": "#/components/headers/Traceparent"
              },
              "Content-Language": {
                "$ref": "#/components/headers/Content-Language"
              }
            }
          },
          "400": {
            "description": "Bad Request",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                },
                "example": {
                  "type": "https://api.kangopenbanking.com/v1/errors/validation-error",
                  "title": "Validation Error",
                  "status": 400
                }
              },
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                },
                "example": {
                  "type": "https://api.kangopenbanking.com/v1/errors/validation-error",
                  "title": "Validation Error",
                  "status": 400
                }
              }
            },
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/XRateLimitLimit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/XRateLimitRemaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/XRateLimitReset"
              }
            }
          },
          "401": {
            "description": "Unauthorized",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                },
                "example": {
                  "type": "https://api.kangopenbanking.com/v1/errors/unauthorized",
                  "title": "Unauthorized",
                  "status": 401
                }
              },
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                },
                "example": {
                  "type": "https://api.kangopenbanking.com/v1/errors/unauthorized",
                  "title": "Unauthorized",
                  "status": 401
                }
              }
            },
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/XRateLimitLimit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/XRateLimitRemaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/XRateLimitReset"
              }
            }
          },
          "403": {
            "description": "Forbidden",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                },
                "examples": {
                  "error": {
                    "$ref": "#/components/examples/ErrorForbidden"
                  }
                }
              },
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            },
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/XRateLimitLimit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/XRateLimitRemaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/XRateLimitReset"
              }
            }
          },
          "404": {
            "description": "Not Found",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                },
                "examples": {
                  "error": {
                    "$ref": "#/components/examples/ErrorNotFound"
                  }
                }
              },
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            },
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/XRateLimitLimit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/XRateLimitRemaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/XRateLimitReset"
              }
            }
          },
          "409": {
            "$ref": "#/components/responses/Conflict",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "429": {
            "$ref": "#/components/responses/TooManyRequests",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "500": {
            "description": "500 Internal Server Error — an unexpected condition prevented completion.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                },
                "example": {
                  "type": "https://api.kangopenbanking.com/v1/errors/internal-error",
                  "title": "Internal Server Error",
                  "status": 500
                }
              },
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                },
                "example": {
                  "type": "https://api.kangopenbanking.com/v1/errors/internal-error",
                  "title": "Internal Server Error",
                  "status": 500
                }
              }
            }
          },
          "default": {
            "description": "Server error — see ProblemDetails for trace ID.",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            },
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/XRateLimitLimit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/XRateLimitRemaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/XRateLimitReset"
              }
            }
          }
        },
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "notes": {
                    "type": "string",
                    "maxLength": 2000
                  },
                  "limits": {
                    "type": "object",
                    "description": "Optional per-merchant override of daily/single/monthly limits"
                  }
                }
              }
            }
          }
        },
        "x-codeSamples": [
          {
            "lang": "cURL",
            "label": "cURL",
            "source": "curl -X POST \"https://api.kangopenbanking.com/v1/admin/merchants/{merchantId}/approve\" \\\n  -H \"Authorization: Bearer $KOB_API_KEY\" \\\n  -H \"X-Request-Id: $(uuidgen)\" \\\n  -H \"Idempotency-Key: $(uuidgen)\" \\\n  -H \"Content-Type: application/json\" \\\n  -d '{\"amount\":\"5000\",\"currency\":\"XAF\"}'"
          },
          {
            "lang": "JavaScript",
            "label": "Node.js",
            "source": "import { KangClient } from '@kangopenbanking/sdk';\n\nconst kang = new KangClient({ apiKey: process.env.KOB_API_KEY });\n\nconst response = await kang.request({\n  method: 'POST',\n  path: '/v1/admin/merchants/{merchantId}/approve',\n  body: { amount: '5000', currency: 'XAF' },\n  idempotencyKey: crypto.randomUUID(),\n});\n\nconsole.log(response.data);"
          },
          {
            "lang": "Python",
            "label": "Python",
            "source": "from kangopenbanking import Kang\nimport os, uuid\n\nkang = Kang(api_key=os.environ[\"KOB_API_KEY\"])\n\nresponse = kang.request(\n    method=\"POST\",\n    path=\"/v1/admin/merchants/{merchantId}/approve\",\n    body={\"amount\": \"5000\", \"currency\": \"XAF\"},\n    idempotency_key=str(uuid.uuid4()),\n)\n\nprint(response.data)"
          },
          {
            "lang": "PHP",
            "label": "PHP",
            "source": "<?php\nrequire 'vendor/autoload.php';\n\n$kang = new \\KangOpenBanking\\Client(getenv('KOB_API_KEY'));\n\n$response = $kang->request([\n    'method' => 'POST',\n    'path'   => '/v1/admin/merchants/{merchantId}/approve',\n    'body'   => ['amount' => '5000', 'currency' => 'XAF'],\n    'idempotency_key' => \\Ramsey\\Uuid\\Uuid::uuid4()->toString(),\n]);\n\nprint_r($response->data);"
          }
        ]
      }
    },
    "/v1/admin/merchants/{merchantId}/reject": {
      "post": {
        "tags": [
          "Admin"
        ],
        "summary": "Reject merchant KYB (admin)",
        "operationId": "adminMerchantReject",
        "description": "Reject KYB submission with reason. Merchant returns to `not_submitted` and may resubmit.",
        "security": [
          {
            "bearerAuth": []
          },
          {
            "oauth2": [
              "admin:write"
            ]
          }
        ],
        "parameters": [
          {
            "name": "merchantId",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          },
          {
            "$ref": "#/components/parameters/RequestId"
          },
          {
            "$ref": "#/components/parameters/Traceparent"
          },
          {
            "$ref": "#/components/parameters/Tracestate"
          },
          {
            "$ref": "#/components/parameters/AcceptLanguage"
          }
        ],
        "responses": {
          "200": {
            "description": "Success",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                },
                "examples": {
                  "default": {
                    "$ref": "#/components/examples/GenericSuccess"
                  }
                }
              }
            },
            "headers": {
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/XRateLimitLimit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/XRateLimitRemaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/XRateLimitReset"
              },
              "x-fapi-interaction-id": {
                "$ref": "#/components/headers/XFapiInteractionId"
              },
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              },
              "traceparent": {
                "$ref": "#/components/headers/Traceparent"
              },
              "Content-Language": {
                "$ref": "#/components/headers/Content-Language"
              }
            }
          },
          "400": {
            "description": "Bad Request",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                },
                "example": {
                  "type": "https://api.kangopenbanking.com/v1/errors/validation-error",
                  "title": "Validation Error",
                  "status": 400
                }
              },
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                },
                "example": {
                  "type": "https://api.kangopenbanking.com/v1/errors/validation-error",
                  "title": "Validation Error",
                  "status": 400
                }
              }
            },
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/XRateLimitLimit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/XRateLimitRemaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/XRateLimitReset"
              }
            }
          },
          "401": {
            "description": "Unauthorized",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                },
                "example": {
                  "type": "https://api.kangopenbanking.com/v1/errors/unauthorized",
                  "title": "Unauthorized",
                  "status": 401
                }
              },
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                },
                "example": {
                  "type": "https://api.kangopenbanking.com/v1/errors/unauthorized",
                  "title": "Unauthorized",
                  "status": 401
                }
              }
            },
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/XRateLimitLimit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/XRateLimitRemaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/XRateLimitReset"
              }
            }
          },
          "403": {
            "description": "Forbidden",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                },
                "examples": {
                  "error": {
                    "$ref": "#/components/examples/ErrorForbidden"
                  }
                }
              },
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            },
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/XRateLimitLimit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/XRateLimitRemaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/XRateLimitReset"
              }
            }
          },
          "404": {
            "description": "Not Found",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                },
                "examples": {
                  "error": {
                    "$ref": "#/components/examples/ErrorNotFound"
                  }
                }
              },
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            },
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/XRateLimitLimit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/XRateLimitRemaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/XRateLimitReset"
              }
            }
          },
          "409": {
            "$ref": "#/components/responses/Conflict",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "429": {
            "$ref": "#/components/responses/TooManyRequests",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "500": {
            "description": "500 Internal Server Error — an unexpected condition prevented completion.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                },
                "example": {
                  "type": "https://api.kangopenbanking.com/v1/errors/internal-error",
                  "title": "Internal Server Error",
                  "status": 500
                }
              },
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                },
                "example": {
                  "type": "https://api.kangopenbanking.com/v1/errors/internal-error",
                  "title": "Internal Server Error",
                  "status": 500
                }
              }
            }
          },
          "default": {
            "description": "Server error — see ProblemDetails for trace ID.",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            },
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/XRateLimitLimit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/XRateLimitRemaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/XRateLimitReset"
              }
            }
          }
        },
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "required": [
                  "reason"
                ],
                "properties": {
                  "reason": {
                    "type": "string",
                    "minLength": 3,
                    "maxLength": 2000
                  },
                  "reason_code": {
                    "type": "string",
                    "enum": [
                      "incomplete_documents",
                      "sanctions_hit",
                      "prohibited_industry",
                      "fraud_suspected",
                      "other"
                    ]
                  }
                }
              }
            }
          }
        },
        "x-codeSamples": [
          {
            "lang": "cURL",
            "label": "cURL",
            "source": "curl -X POST \"https://api.kangopenbanking.com/v1/admin/merchants/{merchantId}/reject\" \\\n  -H \"Authorization: Bearer $KOB_API_KEY\" \\\n  -H \"X-Request-Id: $(uuidgen)\" \\\n  -H \"Idempotency-Key: $(uuidgen)\" \\\n  -H \"Content-Type: application/json\" \\\n  -d '{\"amount\":\"5000\",\"currency\":\"XAF\"}'"
          },
          {
            "lang": "JavaScript",
            "label": "Node.js",
            "source": "import { KangClient } from '@kangopenbanking/sdk';\n\nconst kang = new KangClient({ apiKey: process.env.KOB_API_KEY });\n\nconst response = await kang.request({\n  method: 'POST',\n  path: '/v1/admin/merchants/{merchantId}/reject',\n  body: { amount: '5000', currency: 'XAF' },\n  idempotencyKey: crypto.randomUUID(),\n});\n\nconsole.log(response.data);"
          },
          {
            "lang": "Python",
            "label": "Python",
            "source": "from kangopenbanking import Kang\nimport os, uuid\n\nkang = Kang(api_key=os.environ[\"KOB_API_KEY\"])\n\nresponse = kang.request(\n    method=\"POST\",\n    path=\"/v1/admin/merchants/{merchantId}/reject\",\n    body={\"amount\": \"5000\", \"currency\": \"XAF\"},\n    idempotency_key=str(uuid.uuid4()),\n)\n\nprint(response.data)"
          },
          {
            "lang": "PHP",
            "label": "PHP",
            "source": "<?php\nrequire 'vendor/autoload.php';\n\n$kang = new \\KangOpenBanking\\Client(getenv('KOB_API_KEY'));\n\n$response = $kang->request([\n    'method' => 'POST',\n    'path'   => '/v1/admin/merchants/{merchantId}/reject',\n    'body'   => ['amount' => '5000', 'currency' => 'XAF'],\n    'idempotency_key' => \\Ramsey\\Uuid\\Uuid::uuid4()->toString(),\n]);\n\nprint_r($response->data);"
          }
        ]
      }
    },
    "/v1/admin/merchants/{merchantId}/suspend": {
      "post": {
        "tags": [
          "Admin"
        ],
        "summary": "Suspend merchant (admin)",
        "operationId": "adminMerchantSuspend",
        "description": "Suspend a merchant. All charges/payouts return 403 merchant_suspended until reinstated. Existing settlements continue per policy.",
        "security": [
          {
            "bearerAuth": []
          },
          {
            "oauth2": [
              "admin:write"
            ]
          }
        ],
        "parameters": [
          {
            "name": "merchantId",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          },
          {
            "$ref": "#/components/parameters/RequestId"
          },
          {
            "$ref": "#/components/parameters/Traceparent"
          },
          {
            "$ref": "#/components/parameters/Tracestate"
          },
          {
            "$ref": "#/components/parameters/AcceptLanguage"
          }
        ],
        "responses": {
          "200": {
            "description": "Success",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                },
                "examples": {
                  "default": {
                    "$ref": "#/components/examples/GenericSuccess"
                  }
                }
              }
            },
            "headers": {
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/XRateLimitLimit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/XRateLimitRemaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/XRateLimitReset"
              },
              "x-fapi-interaction-id": {
                "$ref": "#/components/headers/XFapiInteractionId"
              },
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              },
              "traceparent": {
                "$ref": "#/components/headers/Traceparent"
              },
              "Content-Language": {
                "$ref": "#/components/headers/Content-Language"
              }
            }
          },
          "400": {
            "description": "Bad Request",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                },
                "example": {
                  "type": "https://api.kangopenbanking.com/v1/errors/validation-error",
                  "title": "Validation Error",
                  "status": 400
                }
              },
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                },
                "example": {
                  "type": "https://api.kangopenbanking.com/v1/errors/validation-error",
                  "title": "Validation Error",
                  "status": 400
                }
              }
            },
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/XRateLimitLimit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/XRateLimitRemaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/XRateLimitReset"
              }
            }
          },
          "401": {
            "description": "Unauthorized",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                },
                "example": {
                  "type": "https://api.kangopenbanking.com/v1/errors/unauthorized",
                  "title": "Unauthorized",
                  "status": 401
                }
              },
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                },
                "example": {
                  "type": "https://api.kangopenbanking.com/v1/errors/unauthorized",
                  "title": "Unauthorized",
                  "status": 401
                }
              }
            },
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/XRateLimitLimit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/XRateLimitRemaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/XRateLimitReset"
              }
            }
          },
          "403": {
            "description": "Forbidden",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                },
                "examples": {
                  "error": {
                    "$ref": "#/components/examples/ErrorForbidden"
                  }
                }
              },
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            },
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/XRateLimitLimit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/XRateLimitRemaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/XRateLimitReset"
              }
            }
          },
          "404": {
            "description": "Not Found",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                },
                "examples": {
                  "error": {
                    "$ref": "#/components/examples/ErrorNotFound"
                  }
                }
              },
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            },
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/XRateLimitLimit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/XRateLimitRemaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/XRateLimitReset"
              }
            }
          },
          "409": {
            "$ref": "#/components/responses/Conflict",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "429": {
            "$ref": "#/components/responses/TooManyRequests",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "500": {
            "description": "500 Internal Server Error — an unexpected condition prevented completion.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                },
                "example": {
                  "type": "https://api.kangopenbanking.com/v1/errors/internal-error",
                  "title": "Internal Server Error",
                  "status": 500
                }
              },
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                },
                "example": {
                  "type": "https://api.kangopenbanking.com/v1/errors/internal-error",
                  "title": "Internal Server Error",
                  "status": 500
                }
              }
            }
          },
          "default": {
            "description": "Server error — see ProblemDetails for trace ID.",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            },
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/XRateLimitLimit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/XRateLimitRemaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/XRateLimitReset"
              }
            }
          }
        },
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "required": [
                  "reason"
                ],
                "properties": {
                  "reason": {
                    "type": "string",
                    "maxLength": 2000
                  },
                  "reason_code": {
                    "type": "string",
                    "enum": [
                      "risk_review",
                      "compliance_breach",
                      "fraud_suspected",
                      "customer_complaints",
                      "regulatory_request",
                      "other"
                    ]
                  },
                  "freeze_payouts": {
                    "type": "boolean",
                    "default": true
                  }
                }
              }
            }
          }
        },
        "x-codeSamples": [
          {
            "lang": "cURL",
            "label": "cURL",
            "source": "curl -X POST \"https://api.kangopenbanking.com/v1/admin/merchants/{merchantId}/suspend\" \\\n  -H \"Authorization: Bearer $KOB_API_KEY\" \\\n  -H \"X-Request-Id: $(uuidgen)\" \\\n  -H \"Idempotency-Key: $(uuidgen)\" \\\n  -H \"Content-Type: application/json\" \\\n  -d '{\"amount\":\"5000\",\"currency\":\"XAF\"}'"
          },
          {
            "lang": "JavaScript",
            "label": "Node.js",
            "source": "import { KangClient } from '@kangopenbanking/sdk';\n\nconst kang = new KangClient({ apiKey: process.env.KOB_API_KEY });\n\nconst response = await kang.request({\n  method: 'POST',\n  path: '/v1/admin/merchants/{merchantId}/suspend',\n  body: { amount: '5000', currency: 'XAF' },\n  idempotencyKey: crypto.randomUUID(),\n});\n\nconsole.log(response.data);"
          },
          {
            "lang": "Python",
            "label": "Python",
            "source": "from kangopenbanking import Kang\nimport os, uuid\n\nkang = Kang(api_key=os.environ[\"KOB_API_KEY\"])\n\nresponse = kang.request(\n    method=\"POST\",\n    path=\"/v1/admin/merchants/{merchantId}/suspend\",\n    body={\"amount\": \"5000\", \"currency\": \"XAF\"},\n    idempotency_key=str(uuid.uuid4()),\n)\n\nprint(response.data)"
          },
          {
            "lang": "PHP",
            "label": "PHP",
            "source": "<?php\nrequire 'vendor/autoload.php';\n\n$kang = new \\KangOpenBanking\\Client(getenv('KOB_API_KEY'));\n\n$response = $kang->request([\n    'method' => 'POST',\n    'path'   => '/v1/admin/merchants/{merchantId}/suspend',\n    'body'   => ['amount' => '5000', 'currency' => 'XAF'],\n    'idempotency_key' => \\Ramsey\\Uuid\\Uuid::uuid4()->toString(),\n]);\n\nprint_r($response->data);"
          }
        ]
      }
    },
    "/v1/admin/merchants/{merchantId}/reinstate": {
      "post": {
        "tags": [
          "Admin"
        ],
        "summary": "Reinstate merchant (admin)",
        "operationId": "adminMerchantReinstate",
        "description": "Reinstate merchant (admin).\n\n**Tag:** Admin\n\nAuthenticate with a bearer token issued by `/v1/oauth/token`. All state-changing requests\n(POST, PUT, PATCH, DELETE) MUST include an `Idempotency-Key` header (UUID v4) to make\nretries safe — Kang will return the original response for any duplicate key within 24 hours.\n\nErrors follow [RFC 7807](https://datatracker.ietf.org/doc/html/rfc7807) and are returned with\n`Content-Type: application/problem+json`. The `code` field is stable and machine-readable.\nRate-limit headers (`X-RateLimit-Limit`, `X-RateLimit-Remaining`, `X-RateLimit-Reset`)\nare present on every response.",
        "security": [
          {
            "bearerAuth": []
          },
          {
            "oauth2": [
              "admin:write"
            ]
          }
        ],
        "parameters": [
          {
            "name": "merchantId",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          },
          {
            "$ref": "#/components/parameters/RequestId"
          },
          {
            "$ref": "#/components/parameters/Traceparent"
          },
          {
            "$ref": "#/components/parameters/Tracestate"
          },
          {
            "$ref": "#/components/parameters/AcceptLanguage"
          }
        ],
        "responses": {
          "200": {
            "description": "Success",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                },
                "examples": {
                  "default": {
                    "$ref": "#/components/examples/GenericSuccess"
                  }
                }
              }
            },
            "headers": {
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/XRateLimitLimit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/XRateLimitRemaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/XRateLimitReset"
              },
              "x-fapi-interaction-id": {
                "$ref": "#/components/headers/XFapiInteractionId"
              },
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              },
              "traceparent": {
                "$ref": "#/components/headers/Traceparent"
              },
              "Content-Language": {
                "$ref": "#/components/headers/Content-Language"
              }
            }
          },
          "400": {
            "description": "Bad Request",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                },
                "example": {
                  "type": "https://api.kangopenbanking.com/v1/errors/validation-error",
                  "title": "Validation Error",
                  "status": 400
                }
              },
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                },
                "example": {
                  "type": "https://api.kangopenbanking.com/v1/errors/validation-error",
                  "title": "Validation Error",
                  "status": 400
                }
              }
            },
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/XRateLimitLimit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/XRateLimitRemaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/XRateLimitReset"
              }
            }
          },
          "401": {
            "description": "Unauthorized",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                },
                "example": {
                  "type": "https://api.kangopenbanking.com/v1/errors/unauthorized",
                  "title": "Unauthorized",
                  "status": 401
                }
              },
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                },
                "example": {
                  "type": "https://api.kangopenbanking.com/v1/errors/unauthorized",
                  "title": "Unauthorized",
                  "status": 401
                }
              }
            },
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/XRateLimitLimit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/XRateLimitRemaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/XRateLimitReset"
              }
            }
          },
          "403": {
            "description": "Forbidden",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                },
                "examples": {
                  "error": {
                    "$ref": "#/components/examples/ErrorForbidden"
                  }
                }
              },
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            },
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/XRateLimitLimit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/XRateLimitRemaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/XRateLimitReset"
              }
            }
          },
          "404": {
            "description": "Not Found",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                },
                "examples": {
                  "error": {
                    "$ref": "#/components/examples/ErrorNotFound"
                  }
                }
              },
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            },
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/XRateLimitLimit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/XRateLimitRemaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/XRateLimitReset"
              }
            }
          },
          "409": {
            "$ref": "#/components/responses/Conflict",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "429": {
            "$ref": "#/components/responses/TooManyRequests",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "500": {
            "description": "500 Internal Server Error — an unexpected condition prevented completion.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                },
                "example": {
                  "type": "https://api.kangopenbanking.com/v1/errors/internal-error",
                  "title": "Internal Server Error",
                  "status": 500
                }
              },
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                },
                "example": {
                  "type": "https://api.kangopenbanking.com/v1/errors/internal-error",
                  "title": "Internal Server Error",
                  "status": 500
                }
              }
            }
          },
          "default": {
            "description": "Server error — see ProblemDetails for trace ID.",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            },
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/XRateLimitLimit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/XRateLimitRemaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/XRateLimitReset"
              }
            }
          }
        },
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "notes": {
                    "type": "string",
                    "maxLength": 2000
                  }
                }
              }
            }
          }
        },
        "x-codeSamples": [
          {
            "lang": "cURL",
            "label": "cURL",
            "source": "curl -X POST \"https://api.kangopenbanking.com/v1/admin/merchants/{merchantId}/reinstate\" \\\n  -H \"Authorization: Bearer $KOB_API_KEY\" \\\n  -H \"X-Request-Id: $(uuidgen)\" \\\n  -H \"Idempotency-Key: $(uuidgen)\" \\\n  -H \"Content-Type: application/json\" \\\n  -d '{\"amount\":\"5000\",\"currency\":\"XAF\"}'"
          },
          {
            "lang": "JavaScript",
            "label": "Node.js",
            "source": "import { KangClient } from '@kangopenbanking/sdk';\n\nconst kang = new KangClient({ apiKey: process.env.KOB_API_KEY });\n\nconst response = await kang.request({\n  method: 'POST',\n  path: '/v1/admin/merchants/{merchantId}/reinstate',\n  body: { amount: '5000', currency: 'XAF' },\n  idempotencyKey: crypto.randomUUID(),\n});\n\nconsole.log(response.data);"
          },
          {
            "lang": "Python",
            "label": "Python",
            "source": "from kangopenbanking import Kang\nimport os, uuid\n\nkang = Kang(api_key=os.environ[\"KOB_API_KEY\"])\n\nresponse = kang.request(\n    method=\"POST\",\n    path=\"/v1/admin/merchants/{merchantId}/reinstate\",\n    body={\"amount\": \"5000\", \"currency\": \"XAF\"},\n    idempotency_key=str(uuid.uuid4()),\n)\n\nprint(response.data)"
          },
          {
            "lang": "PHP",
            "label": "PHP",
            "source": "<?php\nrequire 'vendor/autoload.php';\n\n$kang = new \\KangOpenBanking\\Client(getenv('KOB_API_KEY'));\n\n$response = $kang->request([\n    'method' => 'POST',\n    'path'   => '/v1/admin/merchants/{merchantId}/reinstate',\n    'body'   => ['amount' => '5000', 'currency' => 'XAF'],\n    'idempotency_key' => \\Ramsey\\Uuid\\Uuid::uuid4()->toString(),\n]);\n\nprint_r($response->data);"
          }
        ]
      }
    },
    "/v1/gateway/reports/transactions/export": {
      "get": {
        "tags": [
          "Gateway"
        ],
        "summary": "Export transactions report",
        "operationId": "gatewayReportsTransactionsExport",
        "description": "Export transactions report.\n\n**Tag:** Gateway\n\nAuthenticate with a bearer token issued by `/v1/oauth/token`. All state-changing requests\n(POST, PUT, PATCH, DELETE) MUST include an `Idempotency-Key` header (UUID v4) to make\nretries safe — Kang will return the original response for any duplicate key within 24 hours.\n\nErrors follow [RFC 7807](https://datatracker.ietf.org/doc/html/rfc7807) and are returned with\n`Content-Type: application/problem+json`. The `code` field is stable and machine-readable.\nRate-limit headers (`X-RateLimit-Limit`, `X-RateLimit-Remaining`, `X-RateLimit-Reset`)\nare present on every response.",
        "security": [
          {
            "bearerAuth": []
          },
          {
            "oauth2": [
              "gateway:read"
            ]
          }
        ],
        "parameters": [
          {
            "name": "from",
            "in": "query",
            "schema": {
              "type": "string",
              "format": "date-time"
            },
            "description": "Inclusive RFC 3339 lower bound"
          },
          {
            "name": "to",
            "in": "query",
            "schema": {
              "type": "string",
              "format": "date-time"
            },
            "description": "Exclusive RFC 3339 upper bound"
          },
          {
            "name": "environment",
            "in": "query",
            "schema": {
              "type": "string",
              "enum": [
                "sandbox",
                "prod"
              ],
              "default": "sandbox"
            }
          },
          {
            "name": "format",
            "in": "query",
            "schema": {
              "type": "string",
              "enum": [
                "csv",
                "xlsx"
              ],
              "default": "csv"
            }
          },
          {
            "name": "currency",
            "in": "query",
            "schema": {
              "type": "string",
              "minLength": 3,
              "maxLength": 3
            }
          },
          {
            "$ref": "#/components/parameters/RequestId"
          },
          {
            "$ref": "#/components/parameters/Traceparent"
          },
          {
            "$ref": "#/components/parameters/Tracestate"
          },
          {
            "$ref": "#/components/parameters/AcceptLanguage"
          }
        ],
        "responses": {
          "200": {
            "description": "Export file",
            "content": {
              "text/csv": {
                "schema": {
                  "type": "string"
                }
              },
              "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet": {
                "schema": {
                  "type": "string",
                  "format": "binary"
                }
              },
              "application/json": {
                "examples": {
                  "default": {
                    "$ref": "#/components/examples/GenericSuccess"
                  }
                },
                "schema": {
                  "$ref": "#/components/schemas/GenericSuccessResponse"
                }
              }
            },
            "headers": {
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/XRateLimitLimit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/XRateLimitRemaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/XRateLimitReset"
              },
              "x-fapi-interaction-id": {
                "$ref": "#/components/headers/XFapiInteractionId"
              },
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              },
              "traceparent": {
                "$ref": "#/components/headers/Traceparent"
              },
              "Content-Language": {
                "$ref": "#/components/headers/Content-Language"
              }
            }
          },
          "400": {
            "description": "400 Bad Request — the request failed validation.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                },
                "example": {
                  "type": "https://api.kangopenbanking.com/v1/errors/validation-error",
                  "title": "Validation Error",
                  "status": 400
                }
              },
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                },
                "example": {
                  "type": "https://api.kangopenbanking.com/v1/errors/validation-error",
                  "title": "Validation Error",
                  "status": 400
                }
              }
            }
          },
          "401": {
            "description": "Unauthorized",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                },
                "example": {
                  "type": "https://api.kangopenbanking.com/v1/errors/unauthorized",
                  "title": "Unauthorized",
                  "status": 401
                }
              },
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                },
                "example": {
                  "type": "https://api.kangopenbanking.com/v1/errors/unauthorized",
                  "title": "Unauthorized",
                  "status": 401
                }
              }
            },
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/XRateLimitLimit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/XRateLimitRemaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/XRateLimitReset"
              }
            }
          },
          "429": {
            "$ref": "#/components/responses/TooManyRequests",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "500": {
            "description": "500 Internal Server Error — an unexpected condition prevented completion.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                },
                "example": {
                  "type": "https://api.kangopenbanking.com/v1/errors/internal-error",
                  "title": "Internal Server Error",
                  "status": 500
                }
              },
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                },
                "example": {
                  "type": "https://api.kangopenbanking.com/v1/errors/internal-error",
                  "title": "Internal Server Error",
                  "status": 500
                }
              }
            }
          },
          "default": {
            "description": "Server error — see ProblemDetails for trace ID.",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            },
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/XRateLimitLimit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/XRateLimitRemaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/XRateLimitReset"
              }
            }
          }
        },
        "x-codeSamples": [
          {
            "lang": "cURL",
            "label": "cURL",
            "source": "curl -X GET \"https://api.kangopenbanking.com/v1/gateway/reports/transactions/export\" \\\n  -H \"Authorization: Bearer $KOB_API_KEY\" \\\n  -H \"X-Request-Id: $(uuidgen)\""
          },
          {
            "lang": "JavaScript",
            "label": "Node.js",
            "source": "import { KangClient } from '@kangopenbanking/sdk';\n\nconst kang = new KangClient({ apiKey: process.env.KOB_API_KEY });\n\nconst response = await kang.request({\n  method: 'GET',\n  path: '/v1/gateway/reports/transactions/export',\n});\n\nconsole.log(response.data);"
          },
          {
            "lang": "Python",
            "label": "Python",
            "source": "from kangopenbanking import Kang\nimport os, uuid\n\nkang = Kang(api_key=os.environ[\"KOB_API_KEY\"])\n\nresponse = kang.request(\n    method=\"GET\",\n    path=\"/v1/gateway/reports/transactions/export\",\n)\n\nprint(response.data)"
          },
          {
            "lang": "PHP",
            "label": "PHP",
            "source": "<?php\nrequire 'vendor/autoload.php';\n\n$kang = new \\KangOpenBanking\\Client(getenv('KOB_API_KEY'));\n\n$response = $kang->request([\n    'method' => 'GET',\n    'path'   => '/v1/gateway/reports/transactions/export',\n]);\n\nprint_r($response->data);"
          }
        ]
      }
    },
    "/v1/gateway/reports/settlements/export": {
      "get": {
        "tags": [
          "Gateway"
        ],
        "summary": "Export settlements report",
        "operationId": "gatewayReportsSettlementsExport",
        "description": "Download a settlements report covering payout batches, gross/fees/net per period.",
        "security": [
          {
            "bearerAuth": []
          },
          {
            "oauth2": [
              "gateway:read"
            ]
          }
        ],
        "parameters": [
          {
            "name": "from",
            "in": "query",
            "schema": {
              "type": "string",
              "format": "date-time"
            },
            "description": "Inclusive RFC 3339 lower bound"
          },
          {
            "name": "to",
            "in": "query",
            "schema": {
              "type": "string",
              "format": "date-time"
            },
            "description": "Exclusive RFC 3339 upper bound"
          },
          {
            "name": "environment",
            "in": "query",
            "schema": {
              "type": "string",
              "enum": [
                "sandbox",
                "prod"
              ],
              "default": "sandbox"
            }
          },
          {
            "name": "format",
            "in": "query",
            "schema": {
              "type": "string",
              "enum": [
                "csv",
                "xlsx"
              ],
              "default": "csv"
            }
          },
          {
            "name": "currency",
            "in": "query",
            "schema": {
              "type": "string",
              "minLength": 3,
              "maxLength": 3
            }
          },
          {
            "$ref": "#/components/parameters/RequestId"
          },
          {
            "$ref": "#/components/parameters/Traceparent"
          },
          {
            "$ref": "#/components/parameters/Tracestate"
          },
          {
            "$ref": "#/components/parameters/AcceptLanguage"
          }
        ],
        "responses": {
          "200": {
            "description": "Export file",
            "content": {
              "text/csv": {
                "schema": {
                  "type": "string"
                }
              },
              "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet": {
                "schema": {
                  "type": "string",
                  "format": "binary"
                }
              },
              "application/json": {
                "examples": {
                  "default": {
                    "$ref": "#/components/examples/GenericSuccess"
                  }
                },
                "schema": {
                  "$ref": "#/components/schemas/GenericSuccessResponse"
                }
              }
            },
            "headers": {
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/XRateLimitLimit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/XRateLimitRemaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/XRateLimitReset"
              },
              "x-fapi-interaction-id": {
                "$ref": "#/components/headers/XFapiInteractionId"
              },
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              },
              "traceparent": {
                "$ref": "#/components/headers/Traceparent"
              },
              "Content-Language": {
                "$ref": "#/components/headers/Content-Language"
              }
            }
          },
          "400": {
            "description": "400 Bad Request — the request failed validation.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                },
                "example": {
                  "type": "https://api.kangopenbanking.com/v1/errors/validation-error",
                  "title": "Validation Error",
                  "status": 400
                }
              },
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                },
                "example": {
                  "type": "https://api.kangopenbanking.com/v1/errors/validation-error",
                  "title": "Validation Error",
                  "status": 400
                }
              }
            }
          },
          "401": {
            "description": "Unauthorized",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                },
                "example": {
                  "type": "https://api.kangopenbanking.com/v1/errors/unauthorized",
                  "title": "Unauthorized",
                  "status": 401
                }
              },
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                },
                "example": {
                  "type": "https://api.kangopenbanking.com/v1/errors/unauthorized",
                  "title": "Unauthorized",
                  "status": 401
                }
              }
            },
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/XRateLimitLimit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/XRateLimitRemaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/XRateLimitReset"
              }
            }
          },
          "429": {
            "$ref": "#/components/responses/TooManyRequests",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "500": {
            "description": "500 Internal Server Error — an unexpected condition prevented completion.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                },
                "example": {
                  "type": "https://api.kangopenbanking.com/v1/errors/internal-error",
                  "title": "Internal Server Error",
                  "status": 500
                }
              },
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                },
                "example": {
                  "type": "https://api.kangopenbanking.com/v1/errors/internal-error",
                  "title": "Internal Server Error",
                  "status": 500
                }
              }
            }
          },
          "default": {
            "description": "Server error — see ProblemDetails for trace ID.",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            },
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/XRateLimitLimit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/XRateLimitRemaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/XRateLimitReset"
              }
            }
          }
        },
        "x-codeSamples": [
          {
            "lang": "cURL",
            "label": "cURL",
            "source": "curl -X GET \"https://api.kangopenbanking.com/v1/gateway/reports/settlements/export\" \\\n  -H \"Authorization: Bearer $KOB_API_KEY\" \\\n  -H \"X-Request-Id: $(uuidgen)\""
          },
          {
            "lang": "JavaScript",
            "label": "Node.js",
            "source": "import { KangClient } from '@kangopenbanking/sdk';\n\nconst kang = new KangClient({ apiKey: process.env.KOB_API_KEY });\n\nconst response = await kang.request({\n  method: 'GET',\n  path: '/v1/gateway/reports/settlements/export',\n});\n\nconsole.log(response.data);"
          },
          {
            "lang": "Python",
            "label": "Python",
            "source": "from kangopenbanking import Kang\nimport os, uuid\n\nkang = Kang(api_key=os.environ[\"KOB_API_KEY\"])\n\nresponse = kang.request(\n    method=\"GET\",\n    path=\"/v1/gateway/reports/settlements/export\",\n)\n\nprint(response.data)"
          },
          {
            "lang": "PHP",
            "label": "PHP",
            "source": "<?php\nrequire 'vendor/autoload.php';\n\n$kang = new \\KangOpenBanking\\Client(getenv('KOB_API_KEY'));\n\n$response = $kang->request([\n    'method' => 'GET',\n    'path'   => '/v1/gateway/reports/settlements/export',\n]);\n\nprint_r($response->data);"
          }
        ]
      }
    },
    "/v1/gateway/reports/fees/export": {
      "get": {
        "tags": [
          "Gateway"
        ],
        "summary": "Export fee breakdown",
        "operationId": "gatewayReportsFeesExport",
        "description": "Download fee analytics broken down by category (per fee-management-and-governance: 49 categories).",
        "security": [
          {
            "bearerAuth": []
          },
          {
            "oauth2": [
              "gateway:read"
            ]
          }
        ],
        "parameters": [
          {
            "name": "from",
            "in": "query",
            "schema": {
              "type": "string",
              "format": "date-time"
            },
            "description": "Inclusive RFC 3339 lower bound"
          },
          {
            "name": "to",
            "in": "query",
            "schema": {
              "type": "string",
              "format": "date-time"
            },
            "description": "Exclusive RFC 3339 upper bound"
          },
          {
            "name": "environment",
            "in": "query",
            "schema": {
              "type": "string",
              "enum": [
                "sandbox",
                "prod"
              ],
              "default": "sandbox"
            }
          },
          {
            "name": "format",
            "in": "query",
            "schema": {
              "type": "string",
              "enum": [
                "csv",
                "xlsx"
              ],
              "default": "csv"
            }
          },
          {
            "name": "currency",
            "in": "query",
            "schema": {
              "type": "string",
              "minLength": 3,
              "maxLength": 3
            }
          },
          {
            "$ref": "#/components/parameters/RequestId"
          },
          {
            "$ref": "#/components/parameters/Traceparent"
          },
          {
            "$ref": "#/components/parameters/Tracestate"
          },
          {
            "$ref": "#/components/parameters/AcceptLanguage"
          }
        ],
        "responses": {
          "200": {
            "description": "Export file",
            "content": {
              "text/csv": {
                "schema": {
                  "type": "string"
                }
              },
              "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet": {
                "schema": {
                  "type": "string",
                  "format": "binary"
                }
              },
              "application/json": {
                "examples": {
                  "default": {
                    "$ref": "#/components/examples/GenericSuccess"
                  }
                },
                "schema": {
                  "$ref": "#/components/schemas/GenericSuccessResponse"
                }
              }
            },
            "headers": {
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/XRateLimitLimit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/XRateLimitRemaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/XRateLimitReset"
              },
              "x-fapi-interaction-id": {
                "$ref": "#/components/headers/XFapiInteractionId"
              },
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              },
              "traceparent": {
                "$ref": "#/components/headers/Traceparent"
              },
              "Content-Language": {
                "$ref": "#/components/headers/Content-Language"
              }
            }
          },
          "400": {
            "description": "400 Bad Request — the request failed validation.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                },
                "example": {
                  "type": "https://api.kangopenbanking.com/v1/errors/validation-error",
                  "title": "Validation Error",
                  "status": 400
                }
              },
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                },
                "example": {
                  "type": "https://api.kangopenbanking.com/v1/errors/validation-error",
                  "title": "Validation Error",
                  "status": 400
                }
              }
            }
          },
          "401": {
            "description": "Unauthorized",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                },
                "example": {
                  "type": "https://api.kangopenbanking.com/v1/errors/unauthorized",
                  "title": "Unauthorized",
                  "status": 401
                }
              },
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                },
                "example": {
                  "type": "https://api.kangopenbanking.com/v1/errors/unauthorized",
                  "title": "Unauthorized",
                  "status": 401
                }
              }
            },
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/XRateLimitLimit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/XRateLimitRemaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/XRateLimitReset"
              }
            }
          },
          "429": {
            "$ref": "#/components/responses/TooManyRequests",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "500": {
            "description": "500 Internal Server Error — an unexpected condition prevented completion.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                },
                "example": {
                  "type": "https://api.kangopenbanking.com/v1/errors/internal-error",
                  "title": "Internal Server Error",
                  "status": 500
                }
              },
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                },
                "example": {
                  "type": "https://api.kangopenbanking.com/v1/errors/internal-error",
                  "title": "Internal Server Error",
                  "status": 500
                }
              }
            }
          },
          "default": {
            "description": "Server error — see ProblemDetails for trace ID.",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            },
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/XRateLimitLimit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/XRateLimitRemaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/XRateLimitReset"
              }
            }
          }
        },
        "x-codeSamples": [
          {
            "lang": "cURL",
            "label": "cURL",
            "source": "curl -X GET \"https://api.kangopenbanking.com/v1/gateway/reports/fees/export\" \\\n  -H \"Authorization: Bearer $KOB_API_KEY\" \\\n  -H \"X-Request-Id: $(uuidgen)\""
          },
          {
            "lang": "JavaScript",
            "label": "Node.js",
            "source": "import { KangClient } from '@kangopenbanking/sdk';\n\nconst kang = new KangClient({ apiKey: process.env.KOB_API_KEY });\n\nconst response = await kang.request({\n  method: 'GET',\n  path: '/v1/gateway/reports/fees/export',\n});\n\nconsole.log(response.data);"
          },
          {
            "lang": "Python",
            "label": "Python",
            "source": "from kangopenbanking import Kang\nimport os, uuid\n\nkang = Kang(api_key=os.environ[\"KOB_API_KEY\"])\n\nresponse = kang.request(\n    method=\"GET\",\n    path=\"/v1/gateway/reports/fees/export\",\n)\n\nprint(response.data)"
          },
          {
            "lang": "PHP",
            "label": "PHP",
            "source": "<?php\nrequire 'vendor/autoload.php';\n\n$kang = new \\KangOpenBanking\\Client(getenv('KOB_API_KEY'));\n\n$response = $kang->request([\n    'method' => 'GET',\n    'path'   => '/v1/gateway/reports/fees/export',\n]);\n\nprint_r($response->data);"
          }
        ]
      }
    },
    "/v1/gateway/statements": {
      "get": {
        "tags": [
          "Gateway"
        ],
        "summary": "List merchant settlement statements",
        "operationId": "gatewayStatementsList",
        "description": "List downloadable settlement statements per period. Each statement aggregates charges, refunds, fees, FX, and net payout.",
        "security": [
          {
            "bearerAuth": []
          },
          {
            "oauth2": [
              "gateway:read"
            ]
          }
        ],
        "parameters": [
          {
            "name": "merchant_id",
            "in": "query",
            "schema": {
              "type": "string",
              "format": "uuid"
            },
            "description": "Required for admin; ignored otherwise (defaults to caller's merchant)"
          },
          {
            "name": "period",
            "in": "query",
            "schema": {
              "type": "string",
              "enum": [
                "daily",
                "weekly",
                "monthly",
                "custom"
              ],
              "default": "monthly"
            }
          },
          {
            "name": "from",
            "in": "query",
            "schema": {
              "type": "string",
              "format": "date-time"
            },
            "description": "Inclusive RFC 3339 lower bound"
          },
          {
            "name": "to",
            "in": "query",
            "schema": {
              "type": "string",
              "format": "date-time"
            },
            "description": "Exclusive RFC 3339 upper bound"
          },
          {
            "name": "limit",
            "in": "query",
            "schema": {
              "type": "integer",
              "minimum": 1,
              "maximum": 200,
              "default": 50
            }
          },
          {
            "name": "offset",
            "in": "query",
            "schema": {
              "type": "integer",
              "minimum": 0,
              "default": 0
            }
          },
          {
            "$ref": "#/components/parameters/StartingAfter"
          },
          {
            "$ref": "#/components/parameters/EndingBefore"
          },
          {
            "$ref": "#/components/parameters/RequestId"
          },
          {
            "$ref": "#/components/parameters/Traceparent"
          },
          {
            "$ref": "#/components/parameters/Tracestate"
          },
          {
            "$ref": "#/components/parameters/AcceptLanguage"
          }
        ],
        "responses": {
          "200": {
            "description": "Success",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                },
                "examples": {
                  "default": {
                    "$ref": "#/components/examples/PaginatedList"
                  }
                }
              }
            },
            "headers": {
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/XRateLimitLimit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/XRateLimitRemaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/XRateLimitReset"
              },
              "x-fapi-interaction-id": {
                "$ref": "#/components/headers/XFapiInteractionId"
              },
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              },
              "traceparent": {
                "$ref": "#/components/headers/Traceparent"
              },
              "Content-Language": {
                "$ref": "#/components/headers/Content-Language"
              }
            }
          },
          "400": {
            "description": "Bad Request",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                },
                "example": {
                  "type": "https://api.kangopenbanking.com/v1/errors/validation-error",
                  "title": "Validation Error",
                  "status": 400
                }
              },
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                },
                "example": {
                  "type": "https://api.kangopenbanking.com/v1/errors/validation-error",
                  "title": "Validation Error",
                  "status": 400
                }
              }
            },
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/XRateLimitLimit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/XRateLimitRemaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/XRateLimitReset"
              }
            }
          },
          "401": {
            "description": "Unauthorized",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                },
                "example": {
                  "type": "https://api.kangopenbanking.com/v1/errors/unauthorized",
                  "title": "Unauthorized",
                  "status": 401
                }
              },
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                },
                "example": {
                  "type": "https://api.kangopenbanking.com/v1/errors/unauthorized",
                  "title": "Unauthorized",
                  "status": 401
                }
              }
            },
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/XRateLimitLimit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/XRateLimitRemaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/XRateLimitReset"
              }
            }
          },
          "403": {
            "description": "Forbidden",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                },
                "examples": {
                  "error": {
                    "$ref": "#/components/examples/ErrorForbidden"
                  }
                }
              },
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            },
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/XRateLimitLimit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/XRateLimitRemaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/XRateLimitReset"
              }
            }
          },
          "404": {
            "description": "Not Found",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                },
                "examples": {
                  "error": {
                    "$ref": "#/components/examples/ErrorNotFound"
                  }
                }
              },
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            },
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/XRateLimitLimit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/XRateLimitRemaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/XRateLimitReset"
              }
            }
          },
          "429": {
            "$ref": "#/components/responses/TooManyRequests",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "500": {
            "description": "500 Internal Server Error — an unexpected condition prevented completion.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                },
                "example": {
                  "type": "https://api.kangopenbanking.com/v1/errors/internal-error",
                  "title": "Internal Server Error",
                  "status": 500
                }
              },
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                },
                "example": {
                  "type": "https://api.kangopenbanking.com/v1/errors/internal-error",
                  "title": "Internal Server Error",
                  "status": 500
                }
              }
            }
          },
          "default": {
            "description": "Server error — see ProblemDetails for trace ID.",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            },
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/XRateLimitLimit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/XRateLimitRemaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/XRateLimitReset"
              }
            }
          }
        },
        "x-codeSamples": [
          {
            "lang": "cURL",
            "label": "cURL",
            "source": "curl -X GET \"https://api.kangopenbanking.com/v1/gateway/statements\" \\\n  -H \"Authorization: Bearer $KOB_API_KEY\" \\\n  -H \"X-Request-Id: $(uuidgen)\""
          },
          {
            "lang": "JavaScript",
            "label": "Node.js",
            "source": "import { KangClient } from '@kangopenbanking/sdk';\n\nconst kang = new KangClient({ apiKey: process.env.KOB_API_KEY });\n\nconst response = await kang.request({\n  method: 'GET',\n  path: '/v1/gateway/statements',\n});\n\nconsole.log(response.data);"
          },
          {
            "lang": "Python",
            "label": "Python",
            "source": "from kangopenbanking import Kang\nimport os, uuid\n\nkang = Kang(api_key=os.environ[\"KOB_API_KEY\"])\n\nresponse = kang.request(\n    method=\"GET\",\n    path=\"/v1/gateway/statements\",\n)\n\nprint(response.data)"
          },
          {
            "lang": "PHP",
            "label": "PHP",
            "source": "<?php\nrequire 'vendor/autoload.php';\n\n$kang = new \\KangOpenBanking\\Client(getenv('KOB_API_KEY'));\n\n$response = $kang->request([\n    'method' => 'GET',\n    'path'   => '/v1/gateway/statements',\n]);\n\nprint_r($response->data);"
          }
        ]
      }
    },
    "/v1/gateway/statements/{statementId}/download": {
      "get": {
        "tags": [
          "Gateway"
        ],
        "summary": "Download settlement statement",
        "operationId": "gatewayStatementDownload",
        "description": "Download a settlement statement as PDF or CSV. PDF is signed with KOB issuer chain.",
        "security": [
          {
            "bearerAuth": []
          },
          {
            "oauth2": [
              "gateway:read"
            ]
          }
        ],
        "parameters": [
          {
            "name": "statementId",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          },
          {
            "name": "format",
            "in": "query",
            "schema": {
              "type": "string",
              "enum": [
                "pdf",
                "csv"
              ],
              "default": "pdf"
            }
          },
          {
            "$ref": "#/components/parameters/RequestId"
          },
          {
            "$ref": "#/components/parameters/Traceparent"
          },
          {
            "$ref": "#/components/parameters/Tracestate"
          },
          {
            "$ref": "#/components/parameters/AcceptLanguage"
          }
        ],
        "responses": {
          "200": {
            "description": "Statement",
            "content": {
              "application/pdf": {
                "schema": {
                  "type": "string",
                  "format": "binary"
                }
              },
              "text/csv": {
                "schema": {
                  "type": "string"
                }
              },
              "application/json": {
                "examples": {
                  "default": {
                    "$ref": "#/components/examples/GenericSuccess"
                  }
                },
                "schema": {
                  "$ref": "#/components/schemas/GenericSuccessResponse"
                }
              }
            },
            "headers": {
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/XRateLimitLimit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/XRateLimitRemaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/XRateLimitReset"
              },
              "x-fapi-interaction-id": {
                "$ref": "#/components/headers/XFapiInteractionId"
              },
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              },
              "traceparent": {
                "$ref": "#/components/headers/Traceparent"
              },
              "Content-Language": {
                "$ref": "#/components/headers/Content-Language"
              }
            }
          },
          "400": {
            "description": "400 Bad Request — the request failed validation.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                },
                "example": {
                  "type": "https://api.kangopenbanking.com/v1/errors/validation-error",
                  "title": "Validation Error",
                  "status": 400
                }
              },
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                },
                "example": {
                  "type": "https://api.kangopenbanking.com/v1/errors/validation-error",
                  "title": "Validation Error",
                  "status": 400
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "404": {
            "description": "Not Found",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                },
                "examples": {
                  "error": {
                    "$ref": "#/components/examples/ErrorNotFound"
                  }
                }
              },
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            },
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/XRateLimitLimit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/XRateLimitRemaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/XRateLimitReset"
              }
            }
          },
          "429": {
            "$ref": "#/components/responses/TooManyRequests",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "500": {
            "description": "500 Internal Server Error — an unexpected condition prevented completion.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                },
                "example": {
                  "type": "https://api.kangopenbanking.com/v1/errors/internal-error",
                  "title": "Internal Server Error",
                  "status": 500
                }
              },
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                },
                "example": {
                  "type": "https://api.kangopenbanking.com/v1/errors/internal-error",
                  "title": "Internal Server Error",
                  "status": 500
                }
              }
            }
          },
          "default": {
            "description": "Server error — see ProblemDetails for trace ID.",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            },
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/XRateLimitLimit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/XRateLimitRemaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/XRateLimitReset"
              }
            }
          }
        },
        "x-codeSamples": [
          {
            "lang": "cURL",
            "label": "cURL",
            "source": "curl -X GET \"https://api.kangopenbanking.com/v1/gateway/statements/{statementId}/download\" \\\n  -H \"Authorization: Bearer $KOB_API_KEY\" \\\n  -H \"X-Request-Id: $(uuidgen)\""
          },
          {
            "lang": "JavaScript",
            "label": "Node.js",
            "source": "import { KangClient } from '@kangopenbanking/sdk';\n\nconst kang = new KangClient({ apiKey: process.env.KOB_API_KEY });\n\nconst response = await kang.request({\n  method: 'GET',\n  path: '/v1/gateway/statements/{statementId}/download',\n});\n\nconsole.log(response.data);"
          },
          {
            "lang": "Python",
            "label": "Python",
            "source": "from kangopenbanking import Kang\nimport os, uuid\n\nkang = Kang(api_key=os.environ[\"KOB_API_KEY\"])\n\nresponse = kang.request(\n    method=\"GET\",\n    path=\"/v1/gateway/statements/{statementId}/download\",\n)\n\nprint(response.data)"
          },
          {
            "lang": "PHP",
            "label": "PHP",
            "source": "<?php\nrequire 'vendor/autoload.php';\n\n$kang = new \\KangOpenBanking\\Client(getenv('KOB_API_KEY'));\n\n$response = $kang->request([\n    'method' => 'GET',\n    'path'   => '/v1/gateway/statements/{statementId}/download',\n]);\n\nprint_r($response->data);"
          }
        ]
      }
    },
    "/v1/gateway/reconciliation/{runId}": {
      "get": {
        "tags": [
          "Gateway"
        ],
        "summary": "Get reconciliation run detail",
        "operationId": "gatewayReconciliationRunGet",
        "description": "Retrieve a single reconciliation run with bucketed counts (matched / missing_at_provider / missing_at_kob / amount_mismatch / duplicate) and per-mismatch references.",
        "security": [
          {
            "bearerAuth": []
          },
          {
            "oauth2": [
              "gateway:read"
            ]
          }
        ],
        "parameters": [
          {
            "name": "runId",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          },
          {
            "$ref": "#/components/parameters/RequestId"
          },
          {
            "$ref": "#/components/parameters/Traceparent"
          },
          {
            "$ref": "#/components/parameters/Tracestate"
          },
          {
            "$ref": "#/components/parameters/AcceptLanguage"
          }
        ],
        "responses": {
          "200": {
            "description": "Success",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                },
                "examples": {
                  "default": {
                    "$ref": "#/components/examples/GenericSuccess"
                  }
                }
              }
            },
            "headers": {
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/XRateLimitLimit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/XRateLimitRemaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/XRateLimitReset"
              },
              "x-fapi-interaction-id": {
                "$ref": "#/components/headers/XFapiInteractionId"
              },
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              },
              "traceparent": {
                "$ref": "#/components/headers/Traceparent"
              },
              "Content-Language": {
                "$ref": "#/components/headers/Content-Language"
              }
            }
          },
          "400": {
            "description": "Bad Request",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                },
                "example": {
                  "type": "https://api.kangopenbanking.com/v1/errors/validation-error",
                  "title": "Validation Error",
                  "status": 400
                }
              },
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                },
                "example": {
                  "type": "https://api.kangopenbanking.com/v1/errors/validation-error",
                  "title": "Validation Error",
                  "status": 400
                }
              }
            },
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/XRateLimitLimit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/XRateLimitRemaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/XRateLimitReset"
              }
            }
          },
          "401": {
            "description": "Unauthorized",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                },
                "example": {
                  "type": "https://api.kangopenbanking.com/v1/errors/unauthorized",
                  "title": "Unauthorized",
                  "status": 401
                }
              },
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                },
                "example": {
                  "type": "https://api.kangopenbanking.com/v1/errors/unauthorized",
                  "title": "Unauthorized",
                  "status": 401
                }
              }
            },
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/XRateLimitLimit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/XRateLimitRemaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/XRateLimitReset"
              }
            }
          },
          "403": {
            "description": "Forbidden",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                },
                "examples": {
                  "error": {
                    "$ref": "#/components/examples/ErrorForbidden"
                  }
                }
              },
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            },
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/XRateLimitLimit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/XRateLimitRemaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/XRateLimitReset"
              }
            }
          },
          "404": {
            "description": "Not Found",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                },
                "examples": {
                  "error": {
                    "$ref": "#/components/examples/ErrorNotFound"
                  }
                }
              },
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            },
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/XRateLimitLimit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/XRateLimitRemaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/XRateLimitReset"
              }
            }
          },
          "429": {
            "$ref": "#/components/responses/TooManyRequests",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "500": {
            "description": "500 Internal Server Error — an unexpected condition prevented completion.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                },
                "example": {
                  "type": "https://api.kangopenbanking.com/v1/errors/internal-error",
                  "title": "Internal Server Error",
                  "status": 500
                }
              },
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                },
                "example": {
                  "type": "https://api.kangopenbanking.com/v1/errors/internal-error",
                  "title": "Internal Server Error",
                  "status": 500
                }
              }
            }
          },
          "default": {
            "description": "Server error — see ProblemDetails for trace ID.",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            },
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/XRateLimitLimit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/XRateLimitRemaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/XRateLimitReset"
              }
            }
          }
        },
        "x-codeSamples": [
          {
            "lang": "cURL",
            "label": "cURL",
            "source": "curl -X GET \"https://api.kangopenbanking.com/v1/gateway/reconciliation/{runId}\" \\\n  -H \"Authorization: Bearer $KOB_API_KEY\" \\\n  -H \"X-Request-Id: $(uuidgen)\""
          },
          {
            "lang": "JavaScript",
            "label": "Node.js",
            "source": "import { KangClient } from '@kangopenbanking/sdk';\n\nconst kang = new KangClient({ apiKey: process.env.KOB_API_KEY });\n\nconst response = await kang.request({\n  method: 'GET',\n  path: '/v1/gateway/reconciliation/{runId}',\n});\n\nconsole.log(response.data);"
          },
          {
            "lang": "Python",
            "label": "Python",
            "source": "from kangopenbanking import Kang\nimport os, uuid\n\nkang = Kang(api_key=os.environ[\"KOB_API_KEY\"])\n\nresponse = kang.request(\n    method=\"GET\",\n    path=\"/v1/gateway/reconciliation/{runId}\",\n)\n\nprint(response.data)"
          },
          {
            "lang": "PHP",
            "label": "PHP",
            "source": "<?php\nrequire 'vendor/autoload.php';\n\n$kang = new \\KangOpenBanking\\Client(getenv('KOB_API_KEY'));\n\n$response = $kang->request([\n    'method' => 'GET',\n    'path'   => '/v1/gateway/reconciliation/{runId}',\n]);\n\nprint_r($response->data);"
          }
        ]
      }
    },
    "/v1/spec/versions": {
      "get": {
        "tags": [
          "Specification"
        ],
        "operationId": "listSpecVersions",
        "summary": "List published OpenAPI versions",
        "description": "Returns the manifest of published OpenAPI specification versions, including release dates and snapshot availability for the version-diff tool.",
        "x-public-endpoint": true,
        "responses": {
          "200": {
            "description": "OK",
            "headers": {
              "X-Fapi-Interaction-Id": {
                "$ref": "#/components/headers/XFapiInteractionId"
              },
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              },
              "traceparent": {
                "$ref": "#/components/headers/Traceparent"
              },
              "Content-Language": {
                "$ref": "#/components/headers/Content-Language"
              },
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/XRateLimitLimit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/XRateLimitRemaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/XRateLimitReset"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                },
                "example": {}
              }
            }
          },
          "400": {
            "description": "400 Bad Request — the request failed validation.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                },
                "example": {
                  "type": "https://api.kangopenbanking.com/v1/errors/validation-error",
                  "title": "Validation Error",
                  "status": 400
                }
              },
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                },
                "example": {
                  "type": "https://api.kangopenbanking.com/v1/errors/validation-error",
                  "title": "Validation Error",
                  "status": 400
                }
              }
            }
          },
          "401": {
            "description": "401 Unauthorized — credentials are missing, expired or invalid.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                },
                "example": {
                  "type": "https://api.kangopenbanking.com/v1/errors/unauthorized",
                  "title": "Unauthorized",
                  "status": 401
                }
              },
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                },
                "example": {
                  "type": "https://api.kangopenbanking.com/v1/errors/unauthorized",
                  "title": "Unauthorized",
                  "status": 401
                }
              }
            }
          },
          "429": {
            "description": "Too Many Requests",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              },
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                },
                "examples": {
                  "error": {
                    "$ref": "#/components/examples/ErrorRateLimited"
                  }
                }
              }
            },
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/XRateLimitLimit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/XRateLimitRemaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/XRateLimitReset"
              },
              "Retry-After": {
                "$ref": "#/components/headers/RetryAfter"
              }
            }
          },
          "500": {
            "description": "500 Internal Server Error — an unexpected condition prevented completion.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                },
                "example": {
                  "type": "https://api.kangopenbanking.com/v1/errors/internal-error",
                  "title": "Internal Server Error",
                  "status": 500
                }
              },
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                },
                "example": {
                  "type": "https://api.kangopenbanking.com/v1/errors/internal-error",
                  "title": "Internal Server Error",
                  "status": 500
                }
              }
            }
          },
          "default": {
            "description": "Server error — see ProblemDetails for trace ID.",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            },
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/XRateLimitLimit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/XRateLimitRemaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/XRateLimitReset"
              }
            }
          }
        },
        "parameters": [
          {
            "$ref": "#/components/parameters/RequestId"
          },
          {
            "$ref": "#/components/parameters/Traceparent"
          },
          {
            "$ref": "#/components/parameters/Tracestate"
          },
          {
            "$ref": "#/components/parameters/AcceptLanguage"
          },
          {
            "$ref": "#/components/parameters/LimitParam"
          },
          {
            "$ref": "#/components/parameters/CursorParam"
          }
        ],
        "x-codeSamples": [
          {
            "lang": "cURL",
            "label": "cURL",
            "source": "curl -X GET \"https://api.kangopenbanking.com/v1/spec/versions\" \\\n  -H \"Authorization: Bearer $KOB_ACCESS_TOKEN\" \\\n  -H \"Content-Type: application/json\""
          },
          {
            "lang": "JavaScript",
            "label": "Node.js",
            "source": "import { KangOpenBanking } from \"@kangopenbanking/sdk\";\n\nconst kob = new KangOpenBanking({ apiKey: process.env.KOB_API_KEY });\nconst res = await kob.request(\"GET\", \"/v1/spec/versions\");\nconsole.log(res);"
          },
          {
            "lang": "Python",
            "label": "Python",
            "source": "from kangopenbanking import KangOpenBanking\n\nkob = KangOpenBanking(api_key=os.environ[\"KOB_API_KEY\"])\nres = kob.request(\"GET\", \"/v1/spec/versions\")\nprint(res)"
          },
          {
            "lang": "PHP",
            "label": "PHP",
            "source": "<?php\n$kob = new KangOpenBanking\\KangOpenBanking(getenv('KOB_API_KEY'));\n$res = $kob->request('GET', '/v1/spec/versions');\nprint_r($res);"
          }
        ]
      }
    },
    "/v1/spec/diff": {
      "get": {
        "tags": [
          "Specification"
        ],
        "operationId": "diffSpecVersions",
        "summary": "Diff two OpenAPI versions",
        "description": "Returns a structured diff between two published OpenAPI versions: added paths, removed paths, schema changes, response-code changes, and required-field changes. Breaking changes are flagged.",
        "x-public-endpoint": true,
        "parameters": [
          {
            "name": "from",
            "in": "query",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "to",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string",
              "default": "current"
            }
          },
          {
            "$ref": "#/components/parameters/RequestId"
          },
          {
            "$ref": "#/components/parameters/Traceparent"
          },
          {
            "$ref": "#/components/parameters/Tracestate"
          },
          {
            "$ref": "#/components/parameters/AcceptLanguage"
          }
        ],
        "responses": {
          "200": {
            "description": "OK",
            "headers": {
              "X-Fapi-Interaction-Id": {
                "$ref": "#/components/headers/XFapiInteractionId"
              },
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              },
              "traceparent": {
                "$ref": "#/components/headers/Traceparent"
              },
              "Content-Language": {
                "$ref": "#/components/headers/Content-Language"
              },
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/XRateLimitLimit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/XRateLimitRemaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/XRateLimitReset"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                },
                "example": {}
              }
            }
          },
          "400": {
            "description": "Bad Request",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              },
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                },
                "examples": {
                  "error": {
                    "$ref": "#/components/examples/ErrorBadRequest"
                  }
                }
              }
            },
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/XRateLimitLimit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/XRateLimitRemaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/XRateLimitReset"
              }
            }
          },
          "401": {
            "description": "401 Unauthorized — credentials are missing, expired or invalid.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                },
                "example": {
                  "type": "https://api.kangopenbanking.com/v1/errors/unauthorized",
                  "title": "Unauthorized",
                  "status": 401
                }
              },
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                },
                "example": {
                  "type": "https://api.kangopenbanking.com/v1/errors/unauthorized",
                  "title": "Unauthorized",
                  "status": 401
                }
              }
            }
          },
          "404": {
            "description": "Version not found",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              },
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                },
                "examples": {
                  "error": {
                    "$ref": "#/components/examples/ErrorNotFound"
                  }
                }
              }
            },
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/XRateLimitLimit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/XRateLimitRemaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/XRateLimitReset"
              }
            }
          },
          "429": {
            "description": "Too Many Requests",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              },
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                },
                "examples": {
                  "error": {
                    "$ref": "#/components/examples/ErrorRateLimited"
                  }
                }
              }
            },
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/XRateLimitLimit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/XRateLimitRemaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/XRateLimitReset"
              },
              "Retry-After": {
                "$ref": "#/components/headers/RetryAfter"
              }
            }
          },
          "500": {
            "description": "500 Internal Server Error — an unexpected condition prevented completion.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                },
                "example": {
                  "type": "https://api.kangopenbanking.com/v1/errors/internal-error",
                  "title": "Internal Server Error",
                  "status": 500
                }
              },
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                },
                "example": {
                  "type": "https://api.kangopenbanking.com/v1/errors/internal-error",
                  "title": "Internal Server Error",
                  "status": 500
                }
              }
            }
          },
          "default": {
            "description": "Server error — see ProblemDetails for trace ID.",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            },
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/XRateLimitLimit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/XRateLimitRemaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/XRateLimitReset"
              }
            }
          }
        },
        "x-codeSamples": [
          {
            "lang": "cURL",
            "label": "cURL",
            "source": "curl -X GET \"https://api.kangopenbanking.com/v1/spec/diff\" \\\n  -H \"Authorization: Bearer $KOB_ACCESS_TOKEN\" \\\n  -H \"Content-Type: application/json\""
          },
          {
            "lang": "JavaScript",
            "label": "Node.js",
            "source": "import { KangOpenBanking } from \"@kangopenbanking/sdk\";\n\nconst kob = new KangOpenBanking({ apiKey: process.env.KOB_API_KEY });\nconst res = await kob.request(\"GET\", \"/v1/spec/diff\");\nconsole.log(res);"
          },
          {
            "lang": "Python",
            "label": "Python",
            "source": "from kangopenbanking import KangOpenBanking\n\nkob = KangOpenBanking(api_key=os.environ[\"KOB_API_KEY\"])\nres = kob.request(\"GET\", \"/v1/spec/diff\")\nprint(res)"
          },
          {
            "lang": "PHP",
            "label": "PHP",
            "source": "<?php\n$kob = new KangOpenBanking\\KangOpenBanking(getenv('KOB_API_KEY'));\n$res = $kob->request('GET', '/v1/spec/diff');\nprint_r($res);"
          }
        ]
      }
    },
    "/v1/sandbox/providers/{provider}/simulate": {
      "post": {
        "tags": [
          "Sandbox"
        ],
        "operationId": "simulateProviderEvent",
        "summary": "Simulate a provider webhook end-to-end",
        "description": "Mints a realistic provider event (Stripe, Flutterwave, or PayPal), signs it with the matching webhook secret, and forwards it through the canonical Kang receiver so the inbox row, charge update, and outbound merchant webhook all fire as in production.",
        "parameters": [
          {
            "name": "provider",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "enum": [
                "stripe",
                "flutterwave",
                "paypal"
              ]
            }
          },
          {
            "$ref": "#/components/parameters/RequestId"
          },
          {
            "$ref": "#/components/parameters/Traceparent"
          },
          {
            "$ref": "#/components/parameters/Tracestate"
          },
          {
            "$ref": "#/components/parameters/AcceptLanguage"
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "required": [
                  "scenario"
                ],
                "properties": {
                  "scenario": {
                    "type": "string",
                    "enum": [
                      "success",
                      "declined",
                      "timeout",
                      "dispute_opened",
                      "refund"
                    ]
                  },
                  "amount": {
                    "type": "integer"
                  },
                  "currency": {
                    "type": "string"
                  }
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "OK",
            "headers": {
              "X-Fapi-Interaction-Id": {
                "$ref": "#/components/headers/XFapiInteractionId"
              },
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              },
              "traceparent": {
                "$ref": "#/components/headers/Traceparent"
              },
              "Content-Language": {
                "$ref": "#/components/headers/Content-Language"
              },
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/XRateLimitLimit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/XRateLimitRemaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/XRateLimitReset"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                },
                "example": {}
              }
            }
          },
          "400": {
            "description": "Bad Request",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              },
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                },
                "examples": {
                  "error": {
                    "$ref": "#/components/examples/ErrorBadRequest"
                  }
                }
              }
            },
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/XRateLimitLimit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/XRateLimitRemaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/XRateLimitReset"
              }
            }
          },
          "401": {
            "description": "Unauthorized",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              },
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                },
                "examples": {
                  "error": {
                    "$ref": "#/components/examples/ErrorUnauthorized"
                  }
                }
              }
            },
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/XRateLimitLimit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/XRateLimitRemaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/XRateLimitReset"
              }
            }
          },
          "409": {
            "description": "Conflict — duplicate event ID",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                },
                "examples": {
                  "error": {
                    "$ref": "#/components/examples/ErrorConflict"
                  }
                }
              },
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            },
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/XRateLimitLimit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/XRateLimitRemaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/XRateLimitReset"
              }
            }
          },
          "429": {
            "description": "Too Many Requests",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              },
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                },
                "examples": {
                  "error": {
                    "$ref": "#/components/examples/ErrorRateLimited"
                  }
                }
              }
            },
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/XRateLimitLimit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/XRateLimitRemaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/XRateLimitReset"
              },
              "Retry-After": {
                "$ref": "#/components/headers/RetryAfter"
              }
            }
          },
          "500": {
            "description": "500 Internal Server Error — an unexpected condition prevented completion.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                },
                "example": {
                  "type": "https://api.kangopenbanking.com/v1/errors/internal-error",
                  "title": "Internal Server Error",
                  "status": 500
                }
              },
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                },
                "example": {
                  "type": "https://api.kangopenbanking.com/v1/errors/internal-error",
                  "title": "Internal Server Error",
                  "status": 500
                }
              }
            }
          },
          "default": {
            "description": "Server error — see ProblemDetails for trace ID.",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            },
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/XRateLimitLimit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/XRateLimitRemaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/XRateLimitReset"
              }
            }
          }
        },
        "x-codeSamples": [
          {
            "lang": "cURL",
            "label": "cURL",
            "source": "curl -X POST \"https://api.kangopenbanking.com/v1/sandbox/providers/{provider}/simulate\" \\\n  -H \"Authorization: Bearer $KOB_ACCESS_TOKEN\" \\\n  -H \"Content-Type: application/json\" \\\n  -d '{}'"
          },
          {
            "lang": "JavaScript",
            "label": "Node.js",
            "source": "import { KangOpenBanking } from \"@kangopenbanking/sdk\";\n\nconst kob = new KangOpenBanking({ apiKey: process.env.KOB_API_KEY });\nconst res = await kob.request(\"POST\", \"/v1/sandbox/providers/{provider}/simulate\", { /* payload */ });\nconsole.log(res);"
          },
          {
            "lang": "Python",
            "label": "Python",
            "source": "from kangopenbanking import KangOpenBanking\n\nkob = KangOpenBanking(api_key=os.environ[\"KOB_API_KEY\"])\nres = kob.request(\"POST\", \"/v1/sandbox/providers/{provider}/simulate\", json={})\nprint(res)"
          },
          {
            "lang": "PHP",
            "label": "PHP",
            "source": "<?php\n$kob = new KangOpenBanking\\KangOpenBanking(getenv('KOB_API_KEY'));\n$res = $kob->request('POST', '/v1/sandbox/providers/{provider}/simulate', []);\nprint_r($res);"
          }
        ]
      }
    },
    "/v1/payments/qr-initiate": {
      "post": {
        "tags": [
          "Payments"
        ],
        "summary": "Initiate a payment from an EMVCo Merchant-Presented QR (MPQR)",
        "description": "Decodes a scanned EMVCo MPM payload, validates CRC + currency + country (CEMAC/UEMOA), debits the user's virtual card, and forwards the push to the KOB PISP rail. Replay-protected via dedicated `qr_payment_idempotency` table.",
        "operationId": "paymentsQrInitiate",
        "security": [
          {
            "bearerAuth": []
          }
        ],
        "parameters": [
          {
            "$ref": "#/components/parameters/IdempotencyKey"
          },
          {
            "name": "X-Partner-Cardholder-Ref",
            "in": "header",
            "required": false,
            "schema": {
              "type": "string",
              "maxLength": 128
            },
            "description": "Partner mode only. Opaque, partner-stable cardholder reference. When present the request is authenticated against an OAuth2 client_credentials access token bearing scope payments:qr; in that mode partner_card_token_id + auth_evidence replace virtual_card_id + pin_token."
          },
          {
            "$ref": "#/components/parameters/RequestId"
          },
          {
            "$ref": "#/components/parameters/Traceparent"
          },
          {
            "$ref": "#/components/parameters/Tracestate"
          },
          {
            "$ref": "#/components/parameters/AcceptLanguage"
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "required": [
                  "qr_payload",
                  "virtual_card_id",
                  "pin_token"
                ],
                "properties": {
                  "qr_payload": {
                    "type": "string",
                    "description": "Raw EMVCo MPM string from the scanner.",
                    "example": "00020101021226...6304ABCD"
                  },
                  "virtual_card_id": {
                    "type": "string",
                    "format": "uuid",
                    "description": "User mode. KOB virtual card to debit. Ignored in partner mode."
                  },
                  "amount_override": {
                    "type": "string",
                    "pattern": "^[0-9]+(\\.[0-9]{1,2})?$",
                    "description": "Required for static (POI=11) QRs that omit tag 54."
                  },
                  "pin_token": {
                    "type": "string",
                    "minLength": 4,
                    "maxLength": 12,
                    "description": "User mode. PIN or biometric step-up token. Ignored in partner mode."
                  },
                  "partner_card_token_id": {
                    "type": "string",
                    "format": "uuid",
                    "description": "Partner mode only. Reference to an active partner_card_tokens row (network token + last4)."
                  },
                  "auth_evidence": {
                    "type": "object",
                    "description": "Partner mode only. PSD2 RTS Art. 18 SCA attestation produced by the partner (e.g. 3DS v2 ARES, on-device biometric, device binding, or TRA exemption justification).",
                    "required": [
                      "method"
                    ],
                    "properties": {
                      "method": {
                        "type": "string",
                        "enum": [
                          "3ds_v2",
                          "biometric",
                          "device_binding",
                          "tra_exemption"
                        ]
                      },
                      "challenge_id": {
                        "type": "string"
                      },
                      "issued_at": {
                        "type": "string",
                        "format": "date-time"
                      },
                      "expires_at": {
                        "type": "string",
                        "format": "date-time"
                      }
                    }
                  }
                }
              },
              "examples": {
                "dynamic_xaf": {
                  "summary": "Dynamic Cameroon MoMo QR",
                  "value": {
                    "qr_payload": "00020101021226...6304ABCD",
                    "virtual_card_id": "9b1c8c1e-1234-4f00-9aaa-aaaaaaaaaaaa",
                    "pin_token": "123456"
                  }
                },
                "static_with_override": {
                  "summary": "Static QR + customer-entered amount",
                  "value": {
                    "qr_payload": "00020101021126...6304WXYZ",
                    "virtual_card_id": "9b1c8c1e-1234-4f00-9aaa-aaaaaaaaaaaa",
                    "amount_override": "5000",
                    "pin_token": "123456"
                  }
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Payment initiated and submitted to PISP rail.",
            "headers": {
              "X-Idempotent-Replayed": {
                "schema": {
                  "type": "string",
                  "enum": [
                    "true"
                  ]
                },
                "description": "Present when this response was served from the idempotency cache."
              },
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              },
              "X-Idempotent-Replay": {
                "$ref": "#/components/headers/X-Idempotent-Replay"
              },
              "X-Idempotency-Status": {
                "$ref": "#/components/headers/X-Idempotency-Status"
              },
              "traceparent": {
                "$ref": "#/components/headers/Traceparent"
              },
              "Content-Language": {
                "$ref": "#/components/headers/Content-Language"
              },
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/XRateLimitLimit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/XRateLimitRemaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/XRateLimitReset"
              },
              "x-fapi-interaction-id": {
                "$ref": "#/components/headers/XFapiInteractionId"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "id": {
                      "type": "string",
                      "format": "uuid"
                    },
                    "status": {
                      "type": "string",
                      "enum": [
                        "pending",
                        "completed",
                        "failed",
                        "refunded"
                      ]
                    },
                    "reference": {
                      "type": [
                        "string",
                        "null"
                      ],
                      "description": "Upstream PISP DomesticPaymentId."
                    },
                    "merchant": {
                      "type": "object",
                      "properties": {
                        "name": {
                          "type": "string"
                        },
                        "id": {
                          "type": [
                            "string",
                            "null"
                          ]
                        },
                        "external": {
                          "type": "boolean"
                        }
                      }
                    },
                    "amount": {
                      "type": "number",
                      "deprecated": true,
                      "x-successor": "amount_money",
                      "x-sunset": "5.0.0",
                      "description": "Deprecated: floating-point monetary value (IEEE-754 binary64 cannot represent decimal minor units exactly). Use `amount_money` instead. Removal is scheduled for v5.0.0."
                    },
                    "currency": {
                      "type": "string",
                      "enum": [
                        "XAF",
                        "XOF",
                        "USD",
                        "EUR"
                      ]
                    },
                    "charged_usd": {
                      "type": "number",
                      "deprecated": true,
                      "x-successor": "charged_usd_money",
                      "x-sunset": "5.0.0",
                      "description": "Deprecated: floating-point monetary value (IEEE-754 binary64 cannot represent decimal minor units exactly). Use `charged_usd_money` instead. Removal is scheduled for v5.0.0."
                    },
                    "qr_type": {
                      "type": "string",
                      "enum": [
                        "static",
                        "dynamic"
                      ]
                    },
                    "amount_money": {
                      "$ref": "#/components/schemas/Money",
                      "description": "Canonical string-encoded successor to `amount`. Amount and ISO 4217 currency travel together (ISO 20022 ActiveCurrencyAndAmount). Prefer this field: it is exact for zero-decimal currencies (XAF, XOF) and immune to IEEE-754 drift.",
                      "x-added-in": "4.54.0"
                    },
                    "charged_usd_money": {
                      "$ref": "#/components/schemas/Money",
                      "description": "Canonical string-encoded successor to `charged_usd`. Amount and ISO 4217 currency travel together (ISO 20022 ActiveCurrencyAndAmount). Prefer this field: it is exact for zero-decimal currencies (XAF, XOF) and immune to IEEE-754 drift.",
                      "x-added-in": "4.54.0"
                    }
                  }
                },
                "example": {
                  "id": "00000000-0000-4000-8000-000000000000",
                  "status": "pending",
                  "reference": "string",
                  "merchant": {
                    "name": "string",
                    "id": "string",
                    "external": true
                  },
                  "amount": 0,
                  "currency": "XAF",
                  "charged_usd": 0,
                  "qr_type": "static",
                  "amount_money": {
                    "amount": "15000",
                    "currency": "XAF"
                  },
                  "charged_usd_money": {
                    "amount": "15000",
                    "currency": "XAF"
                  }
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/BadRequest",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "402": {
            "description": "QR_003 card_unavailable: insufficient virtual-card balance.",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                },
                "examples": {
                  "error": {
                    "$ref": "#/components/examples/ErrorBadRequest"
                  }
                }
              },
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            },
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/XRateLimitLimit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/XRateLimitRemaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/XRateLimitReset"
              }
            }
          },
          "403": {
            "$ref": "#/components/responses/Forbidden",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "404": {
            "$ref": "#/components/responses/NotFound",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "409": {
            "$ref": "#/components/responses/Conflict",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "412": {
            "description": "QR_009 partner_sca_evidence_missing: PSD2 RTS Art. 18 SCA attestation absent or expired.",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                },
                "examples": {
                  "error": {
                    "$ref": "#/components/examples/ErrorBadRequest"
                  }
                }
              },
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            },
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/XRateLimitLimit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/XRateLimitRemaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/XRateLimitReset"
              }
            }
          },
          "429": {
            "$ref": "#/components/responses/TooManyRequests",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "500": {
            "description": "500 Internal Server Error — an unexpected condition prevented completion.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                },
                "example": {
                  "type": "https://api.kangopenbanking.com/v1/errors/internal-error",
                  "title": "Internal Server Error",
                  "status": 500
                }
              },
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                },
                "example": {
                  "type": "https://api.kangopenbanking.com/v1/errors/internal-error",
                  "title": "Internal Server Error",
                  "status": 500
                }
              }
            }
          },
          "502": {
            "description": "QR_005 upstream_pisp_error: PISP consent/payment/submission failed (user-mode debit auto-refunded).",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                },
                "examples": {
                  "error": {
                    "$ref": "#/components/examples/ErrorServer"
                  }
                }
              },
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            },
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/XRateLimitLimit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/XRateLimitRemaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/XRateLimitReset"
              }
            }
          }
        },
        "x-codeSamples": [
          {
            "lang": "cURL",
            "label": "cURL",
            "source": "curl -X POST \"https://api.kangopenbanking.com/v1/payments/qr-initiate\" \\\n  -H \"Authorization: Bearer $KOB_ACCESS_TOKEN\" \\\n  -H \"Content-Type: application/json\" \\\n  -d '{}'"
          },
          {
            "lang": "JavaScript",
            "label": "Node.js",
            "source": "import { KangOpenBanking } from \"@kangopenbanking/sdk\";\n\nconst kob = new KangOpenBanking({ apiKey: process.env.KOB_API_KEY });\nconst res = await kob.request(\"POST\", \"/v1/payments/qr-initiate\", { /* payload */ });\nconsole.log(res);"
          },
          {
            "lang": "Python",
            "label": "Python",
            "source": "from kangopenbanking import KangOpenBanking\n\nkob = KangOpenBanking(api_key=os.environ[\"KOB_API_KEY\"])\nres = kob.request(\"POST\", \"/v1/payments/qr-initiate\", json={})\nprint(res)"
          },
          {
            "lang": "PHP",
            "label": "PHP",
            "source": "<?php\n$kob = new KangOpenBanking\\KangOpenBanking(getenv('KOB_API_KEY'));\n$res = $kob->request('POST', '/v1/payments/qr-initiate', []);\nprint_r($res);"
          }
        ]
      }
    },
    "/v1/merchants/qr-directory": {
      "get": {
        "tags": [
          "Payments"
        ],
        "summary": "List verified KOB merchants accepting QR payments",
        "description": "Public, paginated discovery endpoint for partner virtual-card apps. Returns active KYB-approved merchants with their EMVCo MPQR static payload, country, MCC, and verification flag.",
        "operationId": "merchantsQrDirectoryList",
        "parameters": [
          {
            "name": "country",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string",
              "minLength": 2,
              "maxLength": 2,
              "description": "ISO 3166-1 alpha-2"
            }
          },
          {
            "name": "category",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string",
              "pattern": "^[0-9]{4}$",
              "description": "ISO 18245 MCC"
            }
          },
          {
            "name": "cursor",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "limit",
            "in": "query",
            "required": false,
            "schema": {
              "type": "integer",
              "minimum": 1,
              "maximum": 100,
              "default": 25
            }
          },
          {
            "$ref": "#/components/parameters/RequestId"
          },
          {
            "$ref": "#/components/parameters/Traceparent"
          },
          {
            "$ref": "#/components/parameters/Tracestate"
          },
          {
            "$ref": "#/components/parameters/AcceptLanguage"
          }
        ],
        "responses": {
          "200": {
            "description": "Paginated merchant directory.",
            "content": {
              "application/json": {
                "schema": {
                  "allOf": [
                    {
                      "$ref": "#/components/schemas/PaginatedResponse"
                    },
                    {
                      "type": "object",
                      "properties": {
                        "data": {
                          "type": "array",
                          "items": {
                            "type": "object",
                            "properties": {
                              "id": {
                                "type": "string",
                                "format": "uuid"
                              },
                              "name": {
                                "type": "string"
                              },
                              "country": {
                                "type": "string"
                              },
                              "mcc": {
                                "type": "string"
                              },
                              "verified": {
                                "type": "boolean"
                              },
                              "logo_url": {
                                "type": [
                                  "string",
                                  "null"
                                ]
                              },
                              "static_qr_payload": {
                                "type": "string",
                                "description": "EMVCo MPM POI=11 static payload (CRC included)."
                              }
                            }
                          }
                        }
                      }
                    }
                  ]
                },
                "example": {
                  "data": [
                    {
                      "id": "00000000-0000-4000-8000-000000000000",
                      "name": "string",
                      "country": "string",
                      "mcc": "string",
                      "verified": true,
                      "logo_url": "string",
                      "static_qr_payload": "string"
                    }
                  ],
                  "pagination": {
                    "page": 1,
                    "limit": 20,
                    "total": 150,
                    "has_next": true,
                    "next_cursor": "eyJpZCI6IjEyMyJ9"
                  },
                  "meta": {
                    "request_id": "550e8400-e29b-41d4-a716-446655440000",
                    "timestamp": "2025-03-27T12:00:00Z",
                    "api_version": "4.3.0"
                  }
                }
              }
            },
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              },
              "traceparent": {
                "$ref": "#/components/headers/Traceparent"
              },
              "Content-Language": {
                "$ref": "#/components/headers/Content-Language"
              },
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/XRateLimitLimit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/XRateLimitRemaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/XRateLimitReset"
              },
              "x-fapi-interaction-id": {
                "$ref": "#/components/headers/XFapiInteractionId"
              }
            }
          },
          "400": {
            "description": "400 Bad Request — the request failed validation.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                },
                "example": {
                  "type": "https://api.kangopenbanking.com/v1/errors/validation-error",
                  "title": "Validation Error",
                  "status": 400
                }
              },
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                },
                "example": {
                  "type": "https://api.kangopenbanking.com/v1/errors/validation-error",
                  "title": "Validation Error",
                  "status": 400
                }
              }
            }
          },
          "401": {
            "description": "401 Unauthorized — credentials are missing, expired or invalid.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                },
                "example": {
                  "type": "https://api.kangopenbanking.com/v1/errors/unauthorized",
                  "title": "Unauthorized",
                  "status": 401
                }
              },
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                },
                "example": {
                  "type": "https://api.kangopenbanking.com/v1/errors/unauthorized",
                  "title": "Unauthorized",
                  "status": 401
                }
              }
            }
          },
          "429": {
            "description": "Rate limit exceeded. Retry after the interval in `Retry-After`.",
            "headers": {
              "Retry-After": {
                "schema": {
                  "type": "integer"
                },
                "description": "Seconds to wait before retrying."
              },
              "X-RateLimit-Limit": {
                "schema": {
                  "type": "integer"
                }
              },
              "X-RateLimit-Remaining": {
                "schema": {
                  "type": "integer"
                }
              },
              "X-RateLimit-Reset": {
                "schema": {
                  "type": "integer"
                }
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                },
                "examples": {
                  "rateLimited": {
                    "$ref": "#/components/examples/ErrorRateLimited"
                  }
                }
              }
            }
          },
          "500": {
            "description": "500 Internal Server Error — an unexpected condition prevented completion.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                },
                "example": {
                  "type": "https://api.kangopenbanking.com/v1/errors/internal-error",
                  "title": "Internal Server Error",
                  "status": 500
                }
              },
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                },
                "example": {
                  "type": "https://api.kangopenbanking.com/v1/errors/internal-error",
                  "title": "Internal Server Error",
                  "status": 500
                }
              }
            }
          }
        },
        "x-codeSamples": [
          {
            "lang": "cURL",
            "label": "cURL",
            "source": "curl -X GET \"https://api.kangopenbanking.com/v1/merchants/qr-directory\" \\\n  -H \"Authorization: Bearer $KOB_ACCESS_TOKEN\" \\\n  -H \"Content-Type: application/json\""
          },
          {
            "lang": "JavaScript",
            "label": "Node.js",
            "source": "import { KangOpenBanking } from \"@kangopenbanking/sdk\";\n\nconst kob = new KangOpenBanking({ apiKey: process.env.KOB_API_KEY });\nconst res = await kob.request(\"GET\", \"/v1/merchants/qr-directory\");\nconsole.log(res);"
          },
          {
            "lang": "Python",
            "label": "Python",
            "source": "from kangopenbanking import KangOpenBanking\n\nkob = KangOpenBanking(api_key=os.environ[\"KOB_API_KEY\"])\nres = kob.request(\"GET\", \"/v1/merchants/qr-directory\")\nprint(res)"
          },
          {
            "lang": "PHP",
            "label": "PHP",
            "source": "<?php\n$kob = new KangOpenBanking\\KangOpenBanking(getenv('KOB_API_KEY'));\n$res = $kob->request('GET', '/v1/merchants/qr-directory');\nprint_r($res);"
          }
        ]
      }
    },
    "/v1/merchants/qr-directory/{id}": {
      "get": {
        "tags": [
          "Payments"
        ],
        "summary": "Get one merchant + freshly built EMVCo MPQR payload",
        "description": "Returns merchant info plus a CRC-valid EMVCo MPM payload. Pass amount + ref for a dynamic (POI=12) payload, otherwise a static (POI=11) one is returned.",
        "operationId": "merchantsQrGet",
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          },
          {
            "name": "amount",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string",
              "pattern": "^[0-9]+(\\.[0-9]{1,2})?$"
            }
          },
          {
            "name": "ref",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string",
              "maxLength": 25
            }
          },
          {
            "$ref": "#/components/parameters/RequestId"
          },
          {
            "$ref": "#/components/parameters/Traceparent"
          },
          {
            "$ref": "#/components/parameters/Tracestate"
          },
          {
            "$ref": "#/components/parameters/AcceptLanguage"
          }
        ],
        "responses": {
          "200": {
            "description": "Merchant + EMVCo payload.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "id": {
                      "type": "string",
                      "format": "uuid"
                    },
                    "name": {
                      "type": "string"
                    },
                    "country": {
                      "type": "string"
                    },
                    "currency": {
                      "type": "string",
                      "enum": [
                        "XAF",
                        "XOF",
                        "USD",
                        "EUR"
                      ]
                    },
                    "mcc": {
                      "type": "string"
                    },
                    "verified": {
                      "type": "boolean"
                    },
                    "qr_type": {
                      "type": "string",
                      "enum": [
                        "static",
                        "dynamic"
                      ]
                    },
                    "qr_payload": {
                      "type": "string"
                    }
                  }
                },
                "example": {
                  "id": "00000000-0000-4000-8000-000000000000",
                  "name": "string",
                  "country": "string",
                  "currency": "XAF",
                  "mcc": "string",
                  "verified": true,
                  "qr_type": "static",
                  "qr_payload": "string"
                }
              }
            },
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              },
              "traceparent": {
                "$ref": "#/components/headers/Traceparent"
              },
              "Content-Language": {
                "$ref": "#/components/headers/Content-Language"
              },
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/XRateLimitLimit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/XRateLimitRemaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/XRateLimitReset"
              },
              "x-fapi-interaction-id": {
                "$ref": "#/components/headers/XFapiInteractionId"
              }
            }
          },
          "400": {
            "description": "400 Bad Request — the request failed validation.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                },
                "example": {
                  "type": "https://api.kangopenbanking.com/v1/errors/validation-error",
                  "title": "Validation Error",
                  "status": 400
                }
              },
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                },
                "example": {
                  "type": "https://api.kangopenbanking.com/v1/errors/validation-error",
                  "title": "Validation Error",
                  "status": 400
                }
              }
            }
          },
          "401": {
            "description": "401 Unauthorized — credentials are missing, expired or invalid.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                },
                "example": {
                  "type": "https://api.kangopenbanking.com/v1/errors/unauthorized",
                  "title": "Unauthorized",
                  "status": 401
                }
              },
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                },
                "example": {
                  "type": "https://api.kangopenbanking.com/v1/errors/unauthorized",
                  "title": "Unauthorized",
                  "status": 401
                }
              }
            }
          },
          "404": {
            "$ref": "#/components/responses/NotFound",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "429": {
            "description": "Rate limit exceeded. Retry after the interval in `Retry-After`.",
            "headers": {
              "Retry-After": {
                "schema": {
                  "type": "integer"
                },
                "description": "Seconds to wait before retrying."
              },
              "X-RateLimit-Limit": {
                "schema": {
                  "type": "integer"
                }
              },
              "X-RateLimit-Remaining": {
                "schema": {
                  "type": "integer"
                }
              },
              "X-RateLimit-Reset": {
                "schema": {
                  "type": "integer"
                }
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                },
                "examples": {
                  "rateLimited": {
                    "$ref": "#/components/examples/ErrorRateLimited"
                  }
                }
              }
            }
          },
          "500": {
            "description": "500 Internal Server Error — an unexpected condition prevented completion.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                },
                "example": {
                  "type": "https://api.kangopenbanking.com/v1/errors/internal-error",
                  "title": "Internal Server Error",
                  "status": 500
                }
              },
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                },
                "example": {
                  "type": "https://api.kangopenbanking.com/v1/errors/internal-error",
                  "title": "Internal Server Error",
                  "status": 500
                }
              }
            }
          }
        },
        "x-codeSamples": [
          {
            "lang": "cURL",
            "label": "cURL",
            "source": "curl -X GET \"https://api.kangopenbanking.com/v1/merchants/qr-directory/{id}\" \\\n  -H \"Authorization: Bearer $KOB_ACCESS_TOKEN\" \\\n  -H \"Content-Type: application/json\""
          },
          {
            "lang": "JavaScript",
            "label": "Node.js",
            "source": "import { KangOpenBanking } from \"@kangopenbanking/sdk\";\n\nconst kob = new KangOpenBanking({ apiKey: process.env.KOB_API_KEY });\nconst res = await kob.request(\"GET\", \"/v1/merchants/qr-directory/{id}\");\nconsole.log(res);"
          },
          {
            "lang": "Python",
            "label": "Python",
            "source": "from kangopenbanking import KangOpenBanking\n\nkob = KangOpenBanking(api_key=os.environ[\"KOB_API_KEY\"])\nres = kob.request(\"GET\", \"/v1/merchants/qr-directory/{id}\")\nprint(res)"
          },
          {
            "lang": "PHP",
            "label": "PHP",
            "source": "<?php\n$kob = new KangOpenBanking\\KangOpenBanking(getenv('KOB_API_KEY'));\n$res = $kob->request('GET', '/v1/merchants/qr-directory/{id}');\nprint_r($res);"
          }
        ]
      }
    },
    "/v1/issuing/cardholders": {
      "post": {
        "operationId": "createCardholder",
        "tags": [
          "Issuing"
        ],
        "summary": "Create a cardholder",
        "security": [
          {
            "bearerAuth": []
          }
        ],
        "parameters": [
          {
            "name": "Idempotency-Key",
            "in": "header",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          },
          {
            "$ref": "#/components/parameters/RequestId"
          },
          {
            "$ref": "#/components/parameters/Traceparent"
          },
          {
            "$ref": "#/components/parameters/Tracestate"
          },
          {
            "$ref": "#/components/parameters/AcceptLanguage"
          }
        ],
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                },
                "example": {}
              }
            },
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              },
              "traceparent": {
                "$ref": "#/components/headers/Traceparent"
              },
              "Content-Language": {
                "$ref": "#/components/headers/Content-Language"
              },
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/XRateLimitLimit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/XRateLimitRemaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/XRateLimitReset"
              },
              "x-fapi-interaction-id": {
                "$ref": "#/components/headers/XFapiInteractionId"
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/BadRequest",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "403": {
            "$ref": "#/components/responses/Forbidden",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "409": {
            "$ref": "#/components/responses/Conflict",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "429": {
            "$ref": "#/components/responses/TooManyRequests",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "500": {
            "description": "500 Internal Server Error — an unexpected condition prevented completion.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                },
                "example": {
                  "type": "https://api.kangopenbanking.com/v1/errors/internal-error",
                  "title": "Internal Server Error",
                  "status": 500
                }
              },
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                },
                "example": {
                  "type": "https://api.kangopenbanking.com/v1/errors/internal-error",
                  "title": "Internal Server Error",
                  "status": 500
                }
              }
            }
          }
        },
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object"
              }
            }
          }
        },
        "x-versioned-since": "4.32.0",
        "description": "Issuing API. Create a cardholder. This is a state-changing operation. Where the contract declares an `Idempotency-Key` parameter, the header is required and a retried key replays the original result instead of creating a duplicate.",
        "x-codeSamples": [
          {
            "lang": "cURL",
            "label": "cURL",
            "source": "curl -X POST \"https://api.kangopenbanking.com/v1/issuing/cardholders\" \\\n  -H \"Authorization: Bearer $KOB_ACCESS_TOKEN\" \\\n  -H \"Content-Type: application/json\" \\\n  -d '{}'"
          },
          {
            "lang": "JavaScript",
            "label": "Node.js",
            "source": "import { KangOpenBanking } from \"@kangopenbanking/sdk\";\n\nconst kob = new KangOpenBanking({ apiKey: process.env.KOB_API_KEY });\nconst res = await kob.request(\"POST\", \"/v1/issuing/cardholders\", { /* payload */ });\nconsole.log(res);"
          },
          {
            "lang": "Python",
            "label": "Python",
            "source": "from kangopenbanking import KangOpenBanking\n\nkob = KangOpenBanking(api_key=os.environ[\"KOB_API_KEY\"])\nres = kob.request(\"POST\", \"/v1/issuing/cardholders\", json={})\nprint(res)"
          },
          {
            "lang": "PHP",
            "label": "PHP",
            "source": "<?php\n$kob = new KangOpenBanking\\KangOpenBanking(getenv('KOB_API_KEY'));\n$res = $kob->request('POST', '/v1/issuing/cardholders', []);\nprint_r($res);"
          }
        ]
      }
    },
    "/v1/issuing/cards": {
      "post": {
        "operationId": "issueVirtualCard",
        "tags": [
          "Issuing"
        ],
        "summary": "Issue a virtual card",
        "security": [
          {
            "bearerAuth": []
          }
        ],
        "parameters": [
          {
            "name": "Idempotency-Key",
            "in": "header",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          },
          {
            "$ref": "#/components/parameters/RequestId"
          },
          {
            "$ref": "#/components/parameters/Traceparent"
          },
          {
            "$ref": "#/components/parameters/Tracestate"
          },
          {
            "$ref": "#/components/parameters/AcceptLanguage"
          }
        ],
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                },
                "example": {}
              }
            },
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              },
              "traceparent": {
                "$ref": "#/components/headers/Traceparent"
              },
              "Content-Language": {
                "$ref": "#/components/headers/Content-Language"
              },
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/XRateLimitLimit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/XRateLimitRemaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/XRateLimitReset"
              },
              "x-fapi-interaction-id": {
                "$ref": "#/components/headers/XFapiInteractionId"
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/BadRequest",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "403": {
            "$ref": "#/components/responses/Forbidden",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "409": {
            "$ref": "#/components/responses/Conflict",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "429": {
            "$ref": "#/components/responses/TooManyRequests",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "500": {
            "description": "500 Internal Server Error — an unexpected condition prevented completion.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                },
                "example": {
                  "type": "https://api.kangopenbanking.com/v1/errors/internal-error",
                  "title": "Internal Server Error",
                  "status": 500
                }
              },
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                },
                "example": {
                  "type": "https://api.kangopenbanking.com/v1/errors/internal-error",
                  "title": "Internal Server Error",
                  "status": 500
                }
              }
            }
          }
        },
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object"
              }
            }
          }
        },
        "x-versioned-since": "4.32.0",
        "description": "Issuing API. Issue a virtual card. This is a state-changing operation. Where the contract declares an `Idempotency-Key` parameter, the header is required and a retried key replays the original result instead of creating a duplicate.",
        "x-codeSamples": [
          {
            "lang": "cURL",
            "label": "cURL",
            "source": "curl -X POST \"https://api.kangopenbanking.com/v1/issuing/cards\" \\\n  -H \"Authorization: Bearer $KOB_ACCESS_TOKEN\" \\\n  -H \"Content-Type: application/json\" \\\n  -d '{}'"
          },
          {
            "lang": "JavaScript",
            "label": "Node.js",
            "source": "import { KangOpenBanking } from \"@kangopenbanking/sdk\";\n\nconst kob = new KangOpenBanking({ apiKey: process.env.KOB_API_KEY });\nconst res = await kob.request(\"POST\", \"/v1/issuing/cards\", { /* payload */ });\nconsole.log(res);"
          },
          {
            "lang": "Python",
            "label": "Python",
            "source": "from kangopenbanking import KangOpenBanking\n\nkob = KangOpenBanking(api_key=os.environ[\"KOB_API_KEY\"])\nres = kob.request(\"POST\", \"/v1/issuing/cards\", json={})\nprint(res)"
          },
          {
            "lang": "PHP",
            "label": "PHP",
            "source": "<?php\n$kob = new KangOpenBanking\\KangOpenBanking(getenv('KOB_API_KEY'));\n$res = $kob->request('POST', '/v1/issuing/cards', []);\nprint_r($res);"
          }
        ]
      },
      "get": {
        "operationId": "listVirtualCards",
        "tags": [
          "Issuing"
        ],
        "summary": "List virtual cards",
        "security": [
          {
            "bearerAuth": []
          }
        ],
        "parameters": [
          {
            "$ref": "#/components/parameters/RequestId"
          },
          {
            "$ref": "#/components/parameters/Traceparent"
          },
          {
            "$ref": "#/components/parameters/Tracestate"
          },
          {
            "$ref": "#/components/parameters/AcceptLanguage"
          },
          {
            "$ref": "#/components/parameters/LimitParam"
          },
          {
            "$ref": "#/components/parameters/CursorParam"
          }
        ],
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                },
                "example": {}
              }
            },
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              },
              "traceparent": {
                "$ref": "#/components/headers/Traceparent"
              },
              "Content-Language": {
                "$ref": "#/components/headers/Content-Language"
              },
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/XRateLimitLimit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/XRateLimitRemaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/XRateLimitReset"
              },
              "x-fapi-interaction-id": {
                "$ref": "#/components/headers/XFapiInteractionId"
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/BadRequest",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "403": {
            "$ref": "#/components/responses/Forbidden",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "429": {
            "description": "Rate limit exceeded. Retry after the interval in `Retry-After`.",
            "headers": {
              "Retry-After": {
                "schema": {
                  "type": "integer"
                },
                "description": "Seconds to wait before retrying."
              },
              "X-RateLimit-Limit": {
                "schema": {
                  "type": "integer"
                }
              },
              "X-RateLimit-Remaining": {
                "schema": {
                  "type": "integer"
                }
              },
              "X-RateLimit-Reset": {
                "schema": {
                  "type": "integer"
                }
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                },
                "examples": {
                  "rateLimited": {
                    "$ref": "#/components/examples/ErrorRateLimited"
                  }
                }
              }
            }
          },
          "500": {
            "description": "500 Internal Server Error — an unexpected condition prevented completion.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                },
                "example": {
                  "type": "https://api.kangopenbanking.com/v1/errors/internal-error",
                  "title": "Internal Server Error",
                  "status": 500
                }
              },
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                },
                "example": {
                  "type": "https://api.kangopenbanking.com/v1/errors/internal-error",
                  "title": "Internal Server Error",
                  "status": 500
                }
              }
            }
          }
        },
        "x-versioned-since": "4.32.0",
        "description": "Issuing API. List virtual cards. This is a read-only operation: it never mutates state and its result is scoped to the authenticated caller.",
        "x-codeSamples": [
          {
            "lang": "cURL",
            "label": "cURL",
            "source": "curl -X GET \"https://api.kangopenbanking.com/v1/issuing/cards\" \\\n  -H \"Authorization: Bearer $KOB_ACCESS_TOKEN\" \\\n  -H \"Content-Type: application/json\""
          },
          {
            "lang": "JavaScript",
            "label": "Node.js",
            "source": "import { KangOpenBanking } from \"@kangopenbanking/sdk\";\n\nconst kob = new KangOpenBanking({ apiKey: process.env.KOB_API_KEY });\nconst res = await kob.request(\"GET\", \"/v1/issuing/cards\");\nconsole.log(res);"
          },
          {
            "lang": "Python",
            "label": "Python",
            "source": "from kangopenbanking import KangOpenBanking\n\nkob = KangOpenBanking(api_key=os.environ[\"KOB_API_KEY\"])\nres = kob.request(\"GET\", \"/v1/issuing/cards\")\nprint(res)"
          },
          {
            "lang": "PHP",
            "label": "PHP",
            "source": "<?php\n$kob = new KangOpenBanking\\KangOpenBanking(getenv('KOB_API_KEY'));\n$res = $kob->request('GET', '/v1/issuing/cards');\nprint_r($res);"
          }
        ]
      }
    },
    "/v1/issuing/cards/{id}": {
      "get": {
        "operationId": "getVirtualCard",
        "tags": [
          "Issuing"
        ],
        "summary": "Retrieve a virtual card (masked)",
        "security": [
          {
            "bearerAuth": []
          }
        ],
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "$ref": "#/components/parameters/RequestId"
          },
          {
            "$ref": "#/components/parameters/Traceparent"
          },
          {
            "$ref": "#/components/parameters/Tracestate"
          },
          {
            "$ref": "#/components/parameters/AcceptLanguage"
          }
        ],
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                },
                "example": {}
              }
            },
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              },
              "traceparent": {
                "$ref": "#/components/headers/Traceparent"
              },
              "Content-Language": {
                "$ref": "#/components/headers/Content-Language"
              },
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/XRateLimitLimit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/XRateLimitRemaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/XRateLimitReset"
              },
              "x-fapi-interaction-id": {
                "$ref": "#/components/headers/XFapiInteractionId"
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/BadRequest",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "403": {
            "$ref": "#/components/responses/Forbidden",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "429": {
            "description": "Rate limit exceeded. Retry after the interval in `Retry-After`.",
            "headers": {
              "Retry-After": {
                "schema": {
                  "type": "integer"
                },
                "description": "Seconds to wait before retrying."
              },
              "X-RateLimit-Limit": {
                "schema": {
                  "type": "integer"
                }
              },
              "X-RateLimit-Remaining": {
                "schema": {
                  "type": "integer"
                }
              },
              "X-RateLimit-Reset": {
                "schema": {
                  "type": "integer"
                }
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                },
                "examples": {
                  "rateLimited": {
                    "$ref": "#/components/examples/ErrorRateLimited"
                  }
                }
              }
            }
          },
          "500": {
            "description": "500 Internal Server Error — an unexpected condition prevented completion.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                },
                "example": {
                  "type": "https://api.kangopenbanking.com/v1/errors/internal-error",
                  "title": "Internal Server Error",
                  "status": 500
                }
              },
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                },
                "example": {
                  "type": "https://api.kangopenbanking.com/v1/errors/internal-error",
                  "title": "Internal Server Error",
                  "status": 500
                }
              }
            }
          }
        },
        "x-versioned-since": "4.32.0",
        "description": "Issuing API. Retrieve a virtual card (masked). This is a read-only operation: it never mutates state and its result is scoped to the authenticated caller.",
        "x-codeSamples": [
          {
            "lang": "cURL",
            "label": "cURL",
            "source": "curl -X GET \"https://api.kangopenbanking.com/v1/issuing/cards/{id}\" \\\n  -H \"Authorization: Bearer $KOB_ACCESS_TOKEN\" \\\n  -H \"Content-Type: application/json\""
          },
          {
            "lang": "JavaScript",
            "label": "Node.js",
            "source": "import { KangOpenBanking } from \"@kangopenbanking/sdk\";\n\nconst kob = new KangOpenBanking({ apiKey: process.env.KOB_API_KEY });\nconst res = await kob.request(\"GET\", \"/v1/issuing/cards/{id}\");\nconsole.log(res);"
          },
          {
            "lang": "Python",
            "label": "Python",
            "source": "from kangopenbanking import KangOpenBanking\n\nkob = KangOpenBanking(api_key=os.environ[\"KOB_API_KEY\"])\nres = kob.request(\"GET\", \"/v1/issuing/cards/{id}\")\nprint(res)"
          },
          {
            "lang": "PHP",
            "label": "PHP",
            "source": "<?php\n$kob = new KangOpenBanking\\KangOpenBanking(getenv('KOB_API_KEY'));\n$res = $kob->request('GET', '/v1/issuing/cards/{id}');\nprint_r($res);"
          }
        ]
      }
    },
    "/v1/issuing/cards/{id}/fund": {
      "post": {
        "operationId": "fundVirtualCard",
        "tags": [
          "Issuing"
        ],
        "summary": "Fund a virtual card",
        "security": [
          {
            "bearerAuth": []
          }
        ],
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "Idempotency-Key",
            "in": "header",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          },
          {
            "$ref": "#/components/parameters/RequestId"
          },
          {
            "$ref": "#/components/parameters/Traceparent"
          },
          {
            "$ref": "#/components/parameters/Tracestate"
          },
          {
            "$ref": "#/components/parameters/AcceptLanguage"
          }
        ],
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                },
                "example": {}
              }
            },
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              },
              "traceparent": {
                "$ref": "#/components/headers/Traceparent"
              },
              "Content-Language": {
                "$ref": "#/components/headers/Content-Language"
              },
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/XRateLimitLimit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/XRateLimitRemaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/XRateLimitReset"
              },
              "x-fapi-interaction-id": {
                "$ref": "#/components/headers/XFapiInteractionId"
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/BadRequest",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "403": {
            "$ref": "#/components/responses/Forbidden",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "409": {
            "$ref": "#/components/responses/Conflict",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "429": {
            "$ref": "#/components/responses/TooManyRequests",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "500": {
            "description": "500 Internal Server Error — an unexpected condition prevented completion.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                },
                "example": {
                  "type": "https://api.kangopenbanking.com/v1/errors/internal-error",
                  "title": "Internal Server Error",
                  "status": 500
                }
              },
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                },
                "example": {
                  "type": "https://api.kangopenbanking.com/v1/errors/internal-error",
                  "title": "Internal Server Error",
                  "status": 500
                }
              }
            }
          }
        },
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object"
              }
            }
          }
        },
        "x-versioned-since": "4.32.0",
        "description": "Issuing API. Fund a virtual card. This is a state-changing operation. Where the contract declares an `Idempotency-Key` parameter, the header is required and a retried key replays the original result instead of creating a duplicate.",
        "x-codeSamples": [
          {
            "lang": "cURL",
            "label": "cURL",
            "source": "curl -X POST \"https://api.kangopenbanking.com/v1/issuing/cards/{id}/fund\" \\\n  -H \"Authorization: Bearer $KOB_ACCESS_TOKEN\" \\\n  -H \"Content-Type: application/json\" \\\n  -d '{}'"
          },
          {
            "lang": "JavaScript",
            "label": "Node.js",
            "source": "import { KangOpenBanking } from \"@kangopenbanking/sdk\";\n\nconst kob = new KangOpenBanking({ apiKey: process.env.KOB_API_KEY });\nconst res = await kob.request(\"POST\", \"/v1/issuing/cards/{id}/fund\", { /* payload */ });\nconsole.log(res);"
          },
          {
            "lang": "Python",
            "label": "Python",
            "source": "from kangopenbanking import KangOpenBanking\n\nkob = KangOpenBanking(api_key=os.environ[\"KOB_API_KEY\"])\nres = kob.request(\"POST\", \"/v1/issuing/cards/{id}/fund\", json={})\nprint(res)"
          },
          {
            "lang": "PHP",
            "label": "PHP",
            "source": "<?php\n$kob = new KangOpenBanking\\KangOpenBanking(getenv('KOB_API_KEY'));\n$res = $kob->request('POST', '/v1/issuing/cards/{id}/fund', []);\nprint_r($res);"
          }
        ]
      }
    },
    "/v1/issuing/cards/{id}/withdraw": {
      "post": {
        "operationId": "withdrawVirtualCard",
        "tags": [
          "Issuing"
        ],
        "summary": "Withdraw from a virtual card",
        "security": [
          {
            "bearerAuth": []
          }
        ],
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "Idempotency-Key",
            "in": "header",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          },
          {
            "$ref": "#/components/parameters/RequestId"
          },
          {
            "$ref": "#/components/parameters/Traceparent"
          },
          {
            "$ref": "#/components/parameters/Tracestate"
          },
          {
            "$ref": "#/components/parameters/AcceptLanguage"
          }
        ],
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                },
                "example": {}
              }
            },
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              },
              "traceparent": {
                "$ref": "#/components/headers/Traceparent"
              },
              "Content-Language": {
                "$ref": "#/components/headers/Content-Language"
              },
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/XRateLimitLimit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/XRateLimitRemaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/XRateLimitReset"
              },
              "x-fapi-interaction-id": {
                "$ref": "#/components/headers/XFapiInteractionId"
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/BadRequest",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "403": {
            "$ref": "#/components/responses/Forbidden",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "409": {
            "$ref": "#/components/responses/Conflict",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "429": {
            "$ref": "#/components/responses/TooManyRequests",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "500": {
            "description": "500 Internal Server Error — an unexpected condition prevented completion.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                },
                "example": {
                  "type": "https://api.kangopenbanking.com/v1/errors/internal-error",
                  "title": "Internal Server Error",
                  "status": 500
                }
              },
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                },
                "example": {
                  "type": "https://api.kangopenbanking.com/v1/errors/internal-error",
                  "title": "Internal Server Error",
                  "status": 500
                }
              }
            }
          }
        },
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object"
              }
            }
          }
        },
        "x-versioned-since": "4.32.0",
        "description": "Issuing API. Withdraw from a virtual card. This is a state-changing operation. Where the contract declares an `Idempotency-Key` parameter, the header is required and a retried key replays the original result instead of creating a duplicate.",
        "x-codeSamples": [
          {
            "lang": "cURL",
            "label": "cURL",
            "source": "curl -X POST \"https://api.kangopenbanking.com/v1/issuing/cards/{id}/withdraw\" \\\n  -H \"Authorization: Bearer $KOB_ACCESS_TOKEN\" \\\n  -H \"Content-Type: application/json\" \\\n  -d '{}'"
          },
          {
            "lang": "JavaScript",
            "label": "Node.js",
            "source": "import { KangOpenBanking } from \"@kangopenbanking/sdk\";\n\nconst kob = new KangOpenBanking({ apiKey: process.env.KOB_API_KEY });\nconst res = await kob.request(\"POST\", \"/v1/issuing/cards/{id}/withdraw\", { /* payload */ });\nconsole.log(res);"
          },
          {
            "lang": "Python",
            "label": "Python",
            "source": "from kangopenbanking import KangOpenBanking\n\nkob = KangOpenBanking(api_key=os.environ[\"KOB_API_KEY\"])\nres = kob.request(\"POST\", \"/v1/issuing/cards/{id}/withdraw\", json={})\nprint(res)"
          },
          {
            "lang": "PHP",
            "label": "PHP",
            "source": "<?php\n$kob = new KangOpenBanking\\KangOpenBanking(getenv('KOB_API_KEY'));\n$res = $kob->request('POST', '/v1/issuing/cards/{id}/withdraw', []);\nprint_r($res);"
          }
        ]
      }
    },
    "/v1/issuing/cards/{id}/freeze": {
      "post": {
        "operationId": "freezeVirtualCard",
        "tags": [
          "Issuing"
        ],
        "summary": "Freeze a virtual card",
        "security": [
          {
            "bearerAuth": []
          }
        ],
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "Idempotency-Key",
            "in": "header",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          },
          {
            "$ref": "#/components/parameters/RequestId"
          },
          {
            "$ref": "#/components/parameters/Traceparent"
          },
          {
            "$ref": "#/components/parameters/Tracestate"
          },
          {
            "$ref": "#/components/parameters/AcceptLanguage"
          }
        ],
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                },
                "example": {}
              }
            },
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              },
              "traceparent": {
                "$ref": "#/components/headers/Traceparent"
              },
              "Content-Language": {
                "$ref": "#/components/headers/Content-Language"
              },
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/XRateLimitLimit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/XRateLimitRemaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/XRateLimitReset"
              },
              "x-fapi-interaction-id": {
                "$ref": "#/components/headers/XFapiInteractionId"
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/BadRequest",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "403": {
            "$ref": "#/components/responses/Forbidden",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "409": {
            "$ref": "#/components/responses/Conflict",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "429": {
            "$ref": "#/components/responses/TooManyRequests",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "500": {
            "description": "500 Internal Server Error — an unexpected condition prevented completion.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                },
                "example": {
                  "type": "https://api.kangopenbanking.com/v1/errors/internal-error",
                  "title": "Internal Server Error",
                  "status": 500
                }
              },
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                },
                "example": {
                  "type": "https://api.kangopenbanking.com/v1/errors/internal-error",
                  "title": "Internal Server Error",
                  "status": 500
                }
              }
            }
          }
        },
        "x-versioned-since": "4.32.0",
        "description": "Issuing API. Freeze a virtual card. This is a state-changing operation. Where the contract declares an `Idempotency-Key` parameter, the header is required and a retried key replays the original result instead of creating a duplicate.",
        "x-codeSamples": [
          {
            "lang": "cURL",
            "label": "cURL",
            "source": "curl -X POST \"https://api.kangopenbanking.com/v1/issuing/cards/{id}/freeze\" \\\n  -H \"Authorization: Bearer $KOB_ACCESS_TOKEN\" \\\n  -H \"Content-Type: application/json\""
          },
          {
            "lang": "JavaScript",
            "label": "Node.js",
            "source": "import { KangOpenBanking } from \"@kangopenbanking/sdk\";\n\nconst kob = new KangOpenBanking({ apiKey: process.env.KOB_API_KEY });\nconst res = await kob.request(\"POST\", \"/v1/issuing/cards/{id}/freeze\");\nconsole.log(res);"
          },
          {
            "lang": "Python",
            "label": "Python",
            "source": "from kangopenbanking import KangOpenBanking\n\nkob = KangOpenBanking(api_key=os.environ[\"KOB_API_KEY\"])\nres = kob.request(\"POST\", \"/v1/issuing/cards/{id}/freeze\")\nprint(res)"
          },
          {
            "lang": "PHP",
            "label": "PHP",
            "source": "<?php\n$kob = new KangOpenBanking\\KangOpenBanking(getenv('KOB_API_KEY'));\n$res = $kob->request('POST', '/v1/issuing/cards/{id}/freeze');\nprint_r($res);"
          }
        ]
      }
    },
    "/v1/issuing/cards/{id}/unfreeze": {
      "post": {
        "operationId": "unfreezeVirtualCard",
        "tags": [
          "Issuing"
        ],
        "summary": "Unfreeze a virtual card",
        "security": [
          {
            "bearerAuth": []
          }
        ],
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "Idempotency-Key",
            "in": "header",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          },
          {
            "$ref": "#/components/parameters/RequestId"
          },
          {
            "$ref": "#/components/parameters/Traceparent"
          },
          {
            "$ref": "#/components/parameters/Tracestate"
          },
          {
            "$ref": "#/components/parameters/AcceptLanguage"
          }
        ],
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                },
                "example": {}
              }
            },
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              },
              "traceparent": {
                "$ref": "#/components/headers/Traceparent"
              },
              "Content-Language": {
                "$ref": "#/components/headers/Content-Language"
              },
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/XRateLimitLimit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/XRateLimitRemaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/XRateLimitReset"
              },
              "x-fapi-interaction-id": {
                "$ref": "#/components/headers/XFapiInteractionId"
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/BadRequest",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "403": {
            "$ref": "#/components/responses/Forbidden",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "409": {
            "$ref": "#/components/responses/Conflict",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "429": {
            "$ref": "#/components/responses/TooManyRequests",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "500": {
            "description": "500 Internal Server Error — an unexpected condition prevented completion.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                },
                "example": {
                  "type": "https://api.kangopenbanking.com/v1/errors/internal-error",
                  "title": "Internal Server Error",
                  "status": 500
                }
              },
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                },
                "example": {
                  "type": "https://api.kangopenbanking.com/v1/errors/internal-error",
                  "title": "Internal Server Error",
                  "status": 500
                }
              }
            }
          }
        },
        "x-versioned-since": "4.32.0",
        "description": "Issuing API. Unfreeze a virtual card. This is a state-changing operation. Where the contract declares an `Idempotency-Key` parameter, the header is required and a retried key replays the original result instead of creating a duplicate.",
        "x-codeSamples": [
          {
            "lang": "cURL",
            "label": "cURL",
            "source": "curl -X POST \"https://api.kangopenbanking.com/v1/issuing/cards/{id}/unfreeze\" \\\n  -H \"Authorization: Bearer $KOB_ACCESS_TOKEN\" \\\n  -H \"Content-Type: application/json\""
          },
          {
            "lang": "JavaScript",
            "label": "Node.js",
            "source": "import { KangOpenBanking } from \"@kangopenbanking/sdk\";\n\nconst kob = new KangOpenBanking({ apiKey: process.env.KOB_API_KEY });\nconst res = await kob.request(\"POST\", \"/v1/issuing/cards/{id}/unfreeze\");\nconsole.log(res);"
          },
          {
            "lang": "Python",
            "label": "Python",
            "source": "from kangopenbanking import KangOpenBanking\n\nkob = KangOpenBanking(api_key=os.environ[\"KOB_API_KEY\"])\nres = kob.request(\"POST\", \"/v1/issuing/cards/{id}/unfreeze\")\nprint(res)"
          },
          {
            "lang": "PHP",
            "label": "PHP",
            "source": "<?php\n$kob = new KangOpenBanking\\KangOpenBanking(getenv('KOB_API_KEY'));\n$res = $kob->request('POST', '/v1/issuing/cards/{id}/unfreeze');\nprint_r($res);"
          }
        ]
      }
    },
    "/v1/issuing/cards/{id}/terminate": {
      "post": {
        "operationId": "terminateVirtualCard",
        "tags": [
          "Issuing"
        ],
        "summary": "Permanently terminate a virtual card",
        "security": [
          {
            "bearerAuth": []
          }
        ],
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "Idempotency-Key",
            "in": "header",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          },
          {
            "$ref": "#/components/parameters/RequestId"
          },
          {
            "$ref": "#/components/parameters/Traceparent"
          },
          {
            "$ref": "#/components/parameters/Tracestate"
          },
          {
            "$ref": "#/components/parameters/AcceptLanguage"
          }
        ],
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                },
                "example": {}
              }
            },
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              },
              "traceparent": {
                "$ref": "#/components/headers/Traceparent"
              },
              "Content-Language": {
                "$ref": "#/components/headers/Content-Language"
              },
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/XRateLimitLimit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/XRateLimitRemaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/XRateLimitReset"
              },
              "x-fapi-interaction-id": {
                "$ref": "#/components/headers/XFapiInteractionId"
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/BadRequest",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "403": {
            "$ref": "#/components/responses/Forbidden",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "409": {
            "$ref": "#/components/responses/Conflict",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "429": {
            "$ref": "#/components/responses/TooManyRequests",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "500": {
            "description": "500 Internal Server Error — an unexpected condition prevented completion.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                },
                "example": {
                  "type": "https://api.kangopenbanking.com/v1/errors/internal-error",
                  "title": "Internal Server Error",
                  "status": 500
                }
              },
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                },
                "example": {
                  "type": "https://api.kangopenbanking.com/v1/errors/internal-error",
                  "title": "Internal Server Error",
                  "status": 500
                }
              }
            }
          }
        },
        "x-versioned-since": "4.32.0",
        "description": "Issuing API. Permanently terminate a virtual card. This is a state-changing operation. Where the contract declares an `Idempotency-Key` parameter, the header is required and a retried key replays the original result instead of creating a duplicate.",
        "x-codeSamples": [
          {
            "lang": "cURL",
            "label": "cURL",
            "source": "curl -X POST \"https://api.kangopenbanking.com/v1/issuing/cards/{id}/terminate\" \\\n  -H \"Authorization: Bearer $KOB_ACCESS_TOKEN\" \\\n  -H \"Content-Type: application/json\""
          },
          {
            "lang": "JavaScript",
            "label": "Node.js",
            "source": "import { KangOpenBanking } from \"@kangopenbanking/sdk\";\n\nconst kob = new KangOpenBanking({ apiKey: process.env.KOB_API_KEY });\nconst res = await kob.request(\"POST\", \"/v1/issuing/cards/{id}/terminate\");\nconsole.log(res);"
          },
          {
            "lang": "Python",
            "label": "Python",
            "source": "from kangopenbanking import KangOpenBanking\n\nkob = KangOpenBanking(api_key=os.environ[\"KOB_API_KEY\"])\nres = kob.request(\"POST\", \"/v1/issuing/cards/{id}/terminate\")\nprint(res)"
          },
          {
            "lang": "PHP",
            "label": "PHP",
            "source": "<?php\n$kob = new KangOpenBanking\\KangOpenBanking(getenv('KOB_API_KEY'));\n$res = $kob->request('POST', '/v1/issuing/cards/{id}/terminate');\nprint_r($res);"
          }
        ]
      }
    },
    "/v1/issuing/cards/{id}/transactions": {
      "get": {
        "operationId": "listVirtualCardTransactions",
        "tags": [
          "Issuing"
        ],
        "summary": "List card transactions",
        "security": [
          {
            "bearerAuth": []
          }
        ],
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "$ref": "#/components/parameters/RequestId"
          },
          {
            "$ref": "#/components/parameters/Traceparent"
          },
          {
            "$ref": "#/components/parameters/Tracestate"
          },
          {
            "$ref": "#/components/parameters/AcceptLanguage"
          },
          {
            "$ref": "#/components/parameters/LimitParam"
          },
          {
            "$ref": "#/components/parameters/CursorParam"
          }
        ],
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                },
                "example": {}
              }
            },
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              },
              "traceparent": {
                "$ref": "#/components/headers/Traceparent"
              },
              "Content-Language": {
                "$ref": "#/components/headers/Content-Language"
              },
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/XRateLimitLimit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/XRateLimitRemaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/XRateLimitReset"
              },
              "x-fapi-interaction-id": {
                "$ref": "#/components/headers/XFapiInteractionId"
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/BadRequest",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "403": {
            "$ref": "#/components/responses/Forbidden",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "429": {
            "description": "Rate limit exceeded. Retry after the interval in `Retry-After`.",
            "headers": {
              "Retry-After": {
                "schema": {
                  "type": "integer"
                },
                "description": "Seconds to wait before retrying."
              },
              "X-RateLimit-Limit": {
                "schema": {
                  "type": "integer"
                }
              },
              "X-RateLimit-Remaining": {
                "schema": {
                  "type": "integer"
                }
              },
              "X-RateLimit-Reset": {
                "schema": {
                  "type": "integer"
                }
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                },
                "examples": {
                  "rateLimited": {
                    "$ref": "#/components/examples/ErrorRateLimited"
                  }
                }
              }
            }
          },
          "500": {
            "description": "500 Internal Server Error — an unexpected condition prevented completion.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                },
                "example": {
                  "type": "https://api.kangopenbanking.com/v1/errors/internal-error",
                  "title": "Internal Server Error",
                  "status": 500
                }
              },
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                },
                "example": {
                  "type": "https://api.kangopenbanking.com/v1/errors/internal-error",
                  "title": "Internal Server Error",
                  "status": 500
                }
              }
            }
          }
        },
        "x-versioned-since": "4.32.0",
        "description": "Issuing API. List card transactions. This is a read-only operation: it never mutates state and its result is scoped to the authenticated caller.",
        "x-codeSamples": [
          {
            "lang": "cURL",
            "label": "cURL",
            "source": "curl -X GET \"https://api.kangopenbanking.com/v1/issuing/cards/{id}/transactions\" \\\n  -H \"Authorization: Bearer $KOB_ACCESS_TOKEN\" \\\n  -H \"Content-Type: application/json\""
          },
          {
            "lang": "JavaScript",
            "label": "Node.js",
            "source": "import { KangOpenBanking } from \"@kangopenbanking/sdk\";\n\nconst kob = new KangOpenBanking({ apiKey: process.env.KOB_API_KEY });\nconst res = await kob.request(\"GET\", \"/v1/issuing/cards/{id}/transactions\");\nconsole.log(res);"
          },
          {
            "lang": "Python",
            "label": "Python",
            "source": "from kangopenbanking import KangOpenBanking\n\nkob = KangOpenBanking(api_key=os.environ[\"KOB_API_KEY\"])\nres = kob.request(\"GET\", \"/v1/issuing/cards/{id}/transactions\")\nprint(res)"
          },
          {
            "lang": "PHP",
            "label": "PHP",
            "source": "<?php\n$kob = new KangOpenBanking\\KangOpenBanking(getenv('KOB_API_KEY'));\n$res = $kob->request('GET', '/v1/issuing/cards/{id}/transactions');\nprint_r($res);"
          }
        ]
      }
    },
    "/v1/issuing/cards/{id}/reveal": {
      "post": {
        "operationId": "revealVirtualCard",
        "tags": [
          "Issuing"
        ],
        "summary": "Reveal full PAN/CVV (step-up MFA required)",
        "security": [
          {
            "bearerAuth": []
          }
        ],
        "parameters": [
          {
            "$ref": "#/components/parameters/IdempotencyKey"
          },
          {
            "name": "id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "$ref": "#/components/parameters/RequestId"
          },
          {
            "$ref": "#/components/parameters/Traceparent"
          },
          {
            "$ref": "#/components/parameters/Tracestate"
          },
          {
            "$ref": "#/components/parameters/AcceptLanguage"
          }
        ],
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                },
                "example": {}
              }
            },
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              },
              "traceparent": {
                "$ref": "#/components/headers/Traceparent"
              },
              "Content-Language": {
                "$ref": "#/components/headers/Content-Language"
              },
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/XRateLimitLimit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/XRateLimitRemaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/XRateLimitReset"
              },
              "X-Idempotent-Replay": {
                "$ref": "#/components/headers/X-Idempotent-Replay"
              },
              "X-Idempotency-Status": {
                "$ref": "#/components/headers/X-Idempotency-Status"
              },
              "x-fapi-interaction-id": {
                "$ref": "#/components/headers/XFapiInteractionId"
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/BadRequest",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "403": {
            "$ref": "#/components/responses/Forbidden",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "409": {
            "$ref": "#/components/responses/Conflict",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "429": {
            "$ref": "#/components/responses/TooManyRequests",
            "headers": {
              "X-Trace-Id": {
                "description": "Distributed trace identifier for this request. Echoes the inbound X-Trace-Id or W3C traceparent when present; otherwise a server-generated UUID v4.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "500": {
            "description": "500 Internal Server Error — an unexpected condition prevented completion.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                },
                "example": {
                  "type": "https://api.kangopenbanking.com/v1/errors/internal-error",
                  "title": "Internal Server Error",
                  "status": 500
                }
              },
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                },
                "example": {
                  "type": "https://api.kangopenbanking.com/v1/errors/internal-error",
                  "title": "Internal Server Error",
                  "status": 500
                }
              }
            }
          }
        },
        "x-versioned-since": "4.32.0",
        "x-pci-scope": "cardholder_data",
        "x-pci-note": "Returns full PAN/CVV after step-up MFA. The PAN/CVV originate from the Kora card vault and are returned to the caller in-memory only; KOB does not persist them.",
        "description": "Issuing API. Reveal full PAN/CVV (step-up MFA required). This is a state-changing operation. Where the contract declares an `Idempotency-Key` parameter, the header is required and a retried key replays the original result instead of creating a duplicate.",
        "x-codeSamples": [
          {
            "lang": "cURL",
            "label": "cURL",
            "source": "curl -X POST \"https://api.kangopenbanking.com/v1/issuing/cards/{id}/reveal\" \\\n  -H \"Authorization: Bearer $KOB_ACCESS_TOKEN\" \\\n  -H \"Content-Type: application/json\""
          },
          {
            "lang": "JavaScript",
            "label": "Node.js",
            "source": "import { KangOpenBanking } from \"@kangopenbanking/sdk\";\n\nconst kob = new KangOpenBanking({ apiKey: process.env.KOB_API_KEY });\nconst res = await kob.request(\"POST\", \"/v1/issuing/cards/{id}/reveal\");\nconsole.log(res);"
          },
          {
            "lang": "Python",
            "label": "Python",
            "source": "from kangopenbanking import KangOpenBanking\n\nkob = KangOpenBanking(api_key=os.environ[\"KOB_API_KEY\"])\nres = kob.request(\"POST\", \"/v1/issuing/cards/{id}/reveal\")\nprint(res)"
          },
          {
            "lang": "PHP",
            "label": "PHP",
            "source": "<?php\n$kob = new KangOpenBanking\\KangOpenBanking(getenv('KOB_API_KEY'));\n$res = $kob->request('POST', '/v1/issuing/cards/{id}/reveal');\nprint_r($res);"
          }
        ]
      }
    },
    "/v1/budgeting/budgets": {
      "get": {
        "tags": [
          "Budgeting"
        ],
        "operationId": "budgetingListBudgets",
        "summary": "List budgets",
        "security": [
          {
            "bearerAuth": []
          }
        ],
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Budget"
                },
                "example": {
                  "id": "bgt_01HXYZ",
                  "consumer_id": "00000000-0000-4000-8000-000000000000",
                  "name": "May 2026 Budget",
                  "period": "monthly",
                  "start_date": "2026-01-01",
                  "end_date": "2026-01-01",
                  "total_limit": 0,
                  "categories": [
                    {
                      "id": "f1d6f4a0-1d4e-4a3a-9e0a-1a2b3c4d5e6f",
                      "name": "Food & Market",
                      "icon": "ShoppingCart",
                      "colour": "#10D9A0",
                      "limit": 0,
                      "spent": 0,
                      "remaining": 0,
                      "percentage_used": 0,
                      "transaction_count": 0,
                      "top_merchant": "XAF"
                    }
                  ],
                  "currency": "XAF",
                  "status": "active",
                  "created_at": "2026-01-01T00:00:00Z",
                  "updated_at": "2026-01-01T00:00:00Z"
                }
              }
            },
            "headers": {
              "traceparent": {
                "$ref": "#/components/headers/Traceparent"
              },
              "Content-Language": {
                "$ref": "#/components/headers/Content-Language"
              },
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/XRateLimitLimit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/XRateLimitRemaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/XRateLimitReset"
              },
              "x-fapi-interaction-id": {
                "$ref": "#/components/headers/XFapiInteractionId"
              }
            }
          },
          "400": {
            "description": "400 Bad Request — the request failed validation.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                },
                "example": {
                  "type": "https://api.kangopenbanking.com/v1/errors/validation-error",
                  "title": "Validation Error",
                  "status": 400
                }
              },
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                },
                "example": {
                  "type": "https://api.kangopenbanking.com/v1/errors/validation-error",
                  "title": "Validation Error",
                  "status": 400
                }
              }
            }
          },
          "401": {
            "description": "401 Unauthorized — credentials are missing, expired or invalid.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                },
                "example": {
                  "type": "https://api.kangopenbanking.com/v1/errors/unauthorized",
                  "title": "Unauthorized",
                  "status": 401
                }
              },
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                },
                "example": {
                  "type": "https://api.kangopenbanking.com/v1/errors/unauthorized",
                  "title": "Unauthorized",
                  "status": 401
                }
              }
            }
          },
          "429": {
            "description": "Rate limit exceeded. Retry after the interval in `Retry-After`.",
            "headers": {
              "Retry-After": {
                "schema": {
                  "type": "integer"
                },
                "description": "Seconds to wait before retrying."
              },
              "X-RateLimit-Limit": {
                "schema": {
                  "type": "integer"
                }
              },
              "X-RateLimit-Remaining": {
                "schema": {
                  "type": "integer"
                }
              },
              "X-RateLimit-Reset": {
                "schema": {
                  "type": "integer"
                }
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                },
                "examples": {
                  "rateLimited": {
                    "$ref": "#/components/examples/ErrorRateLimited"
                  }
                }
              }
            }
          },
          "500": {
            "description": "500 Internal Server Error — an unexpected condition prevented completion.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                },
                "example": {
                  "type": "https://api.kangopenbanking.com/v1/errors/internal-error",
                  "title": "Internal Server Error",
                  "status": 500
                }
              },
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                },
                "example": {
                  "type": "https://api.kangopenbanking.com/v1/errors/internal-error",
                  "title": "Internal Server Error",
                  "status": 500
                }
              }
            }
          }
        },
        "parameters": [
          {
            "$ref": "#/components/parameters/Traceparent"
          },
          {
            "$ref": "#/components/parameters/Tracestate"
          },
          {
            "$ref": "#/components/parameters/AcceptLanguage"
          },
          {
            "$ref": "#/components/parameters/LimitParam"
          },
          {
            "$ref": "#/components/parameters/CursorParam"
          }
        ],
        "description": "Budgeting API. List budgets. This is a read-only operation: it never mutates state and its result is scoped to the authenticated caller.",
        "x-codeSamples": [
          {
            "lang": "cURL",
            "label": "cURL",
            "source": "curl -X GET \"https://api.kangopenbanking.com/v1/budgeting/budgets\" \\\n  -H \"Authorization: Bearer $KOB_ACCESS_TOKEN\" \\\n  -H \"Content-Type: application/json\""
          },
          {
            "lang": "JavaScript",
            "label": "Node.js",
            "source": "import { KangOpenBanking } from \"@kangopenbanking/sdk\";\n\nconst kob = new KangOpenBanking({ apiKey: process.env.KOB_API_KEY });\nconst res = await kob.request(\"GET\", \"/v1/budgeting/budgets\");\nconsole.log(res);"
          },
          {
            "lang": "Python",
            "label": "Python",
            "source": "from kangopenbanking import KangOpenBanking\n\nkob = KangOpenBanking(api_key=os.environ[\"KOB_API_KEY\"])\nres = kob.request(\"GET\", \"/v1/budgeting/budgets\")\nprint(res)"
          },
          {
            "lang": "PHP",
            "label": "PHP",
            "source": "<?php\n$kob = new KangOpenBanking\\KangOpenBanking(getenv('KOB_API_KEY'));\n$res = $kob->request('GET', '/v1/budgeting/budgets');\nprint_r($res);"
          }
        ]
      },
      "post": {
        "tags": [
          "Budgeting"
        ],
        "operationId": "budgetingCreateBudget",
        "summary": "Create budget",
        "security": [
          {
            "bearerAuth": []
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/BudgetCreateRequest"
              }
            }
          }
        },
        "responses": {
          "201": {
            "description": "Created",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Budget"
                },
                "example": {
                  "id": "bgt_01HXYZ",
                  "consumer_id": "00000000-0000-4000-8000-000000000000",
                  "name": "May 2026 Budget",
                  "period": "monthly",
                  "start_date": "2026-01-01",
                  "end_date": "2026-01-01",
                  "total_limit": 0,
                  "categories": [
                    {
                      "id": "f1d6f4a0-1d4e-4a3a-9e0a-1a2b3c4d5e6f",
                      "name": "Food & Market",
                      "icon": "ShoppingCart",
                      "colour": "#10D9A0",
                      "limit": 0,
                      "spent": 0,
                      "remaining": 0,
                      "percentage_used": 0,
                      "transaction_count": 0,
                      "top_merchant": "XAF"
                    }
                  ],
                  "currency": "XAF",
                  "status": "active",
                  "created_at": "2026-01-01T00:00:00Z",
                  "updated_at": "2026-01-01T00:00:00Z"
                }
              }
            },
            "headers": {
              "traceparent": {
                "$ref": "#/components/headers/Traceparent"
              },
              "Content-Language": {
                "$ref": "#/components/headers/Content-Language"
              },
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/XRateLimitLimit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/XRateLimitRemaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/XRateLimitReset"
              },
              "x-fapi-interaction-id": {
                "$ref": "#/components/headers/XFapiInteractionId"
              }
            }
          },
          "400": {
            "description": "400 Bad Request — the request failed validation.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                },
                "example": {
                  "type": "https://api.kangopenbanking.com/v1/errors/validation-error",
                  "title": "Validation Error",
                  "status": 400
                }
              },
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                },
                "example": {
                  "type": "https://api.kangopenbanking.com/v1/errors/validation-error",
                  "title": "Validation Error",
                  "status": 400
                }
              }
            }
          },
          "401": {
            "description": "401 Unauthorized — credentials are missing, expired or invalid.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                },
                "example": {
                  "type": "https://api.kangopenbanking.com/v1/errors/unauthorized",
                  "title": "Unauthorized",
                  "status": 401
                }
              },
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                },
                "example": {
                  "type": "https://api.kangopenbanking.com/v1/errors/unauthorized",
                  "title": "Unauthorized",
                  "status": 401
                }
              }
            }
          },
          "429": {
            "description": "Rate limit exceeded. Retry after the interval in `Retry-After`.",
            "headers": {
              "Retry-After": {
                "schema": {
                  "type": "integer"
                },
                "description": "Seconds to wait before retrying."
              },
              "X-RateLimit-Limit": {
                "schema": {
                  "type": "integer"
                }
              },
              "X-RateLimit-Remaining": {
                "schema": {
                  "type": "integer"
                }
              },
              "X-RateLimit-Reset": {
                "schema": {
                  "type": "integer"
                }
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                },
                "examples": {
                  "rateLimited": {
                    "$ref": "#/components/examples/ErrorRateLimited"
                  }
                }
              }
            }
          },
          "500": {
            "description": "500 Internal Server Error — an unexpected condition prevented completion.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                },
                "example": {
                  "type": "https://api.kangopenbanking.com/v1/errors/internal-error",
                  "title": "Internal Server Error",
                  "status": 500
                }
              },
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                },
                "example": {
                  "type": "https://api.kangopenbanking.com/v1/errors/internal-error",
                  "title": "Internal Server Error",
                  "status": 500
                }
              }
            }
          }
        },
        "parameters": [
          {
            "$ref": "#/components/parameters/Traceparent"
          },
          {
            "$ref": "#/components/parameters/Tracestate"
          },
          {
            "$ref": "#/components/parameters/AcceptLanguage"
          }
        ],
        "description": "Budgeting API. Create budget. This is a state-changing operation. Where the contract declares an `Idempotency-Key` parameter, the header is required and a retried key replays the original result instead of creating a duplicate.",
        "x-codeSamples": [
          {
            "lang": "cURL",
            "label": "cURL",
            "source": "curl -X POST \"https://api.kangopenbanking.com/v1/budgeting/budgets\" \\\n  -H \"Authorization: Bearer $KOB_ACCESS_TOKEN\" \\\n  -H \"Content-Type: application/json\" \\\n  -d '{}'"
          },
          {
            "lang": "JavaScript",
            "label": "Node.js",
            "source": "import { KangOpenBanking } from \"@kangopenbanking/sdk\";\n\nconst kob = new KangOpenBanking({ apiKey: process.env.KOB_API_KEY });\nconst res = await kob.request(\"POST\", \"/v1/budgeting/budgets\", { /* payload */ });\nconsole.log(res);"
          },
          {
            "lang": "Python",
            "label": "Python",
            "source": "from kangopenbanking import KangOpenBanking\n\nkob = KangOpenBanking(api_key=os.environ[\"KOB_API_KEY\"])\nres = kob.request(\"POST\", \"/v1/budgeting/budgets\", json={})\nprint(res)"
          },
          {
            "lang": "PHP",
            "label": "PHP",
            "source": "<?php\n$kob = new KangOpenBanking\\KangOpenBanking(getenv('KOB_API_KEY'));\n$res = $kob->request('POST', '/v1/budgeting/budgets', []);\nprint_r($res);"
          }
        ]
      }
    },
    "/v1/budgeting/budgets/{budgetId}": {
      "parameters": [
        {
          "name": "budgetId",
          "in": "path",
          "required": true,
          "schema": {
            "type": "string"
          },
          "description": "Budget identifier"
        }
      ],
      "get": {
        "tags": [
          "Budgeting"
        ],
        "operationId": "budgetingGetBudget",
        "summary": "Get budget",
        "security": [
          {
            "bearerAuth": []
          }
        ],
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Budget"
                },
                "example": {
                  "id": "bgt_01HXYZ",
                  "consumer_id": "00000000-0000-4000-8000-000000000000",
                  "name": "May 2026 Budget",
                  "period": "monthly",
                  "start_date": "2026-01-01",
                  "end_date": "2026-01-01",
                  "total_limit": 0,
                  "categories": [
                    {
                      "id": "f1d6f4a0-1d4e-4a3a-9e0a-1a2b3c4d5e6f",
                      "name": "Food & Market",
                      "icon": "ShoppingCart",
                      "colour": "#10D9A0",
                      "limit": 0,
                      "spent": 0,
                      "remaining": 0,
                      "percentage_used": 0,
                      "transaction_count": 0,
                      "top_merchant": "XAF"
                    }
                  ],
                  "currency": "XAF",
                  "status": "active",
                  "created_at": "2026-01-01T00:00:00Z",
                  "updated_at": "2026-01-01T00:00:00Z"
                }
              }
            },
            "headers": {
              "traceparent": {
                "$ref": "#/components/headers/Traceparent"
              },
              "Content-Language": {
                "$ref": "#/components/headers/Content-Language"
              },
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/XRateLimitLimit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/XRateLimitRemaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/XRateLimitReset"
              },
              "x-fapi-interaction-id": {
                "$ref": "#/components/headers/XFapiInteractionId"
              }
            }
          },
          "400": {
            "description": "400 Bad Request — the request failed validation.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                },
                "example": {
                  "type": "https://api.kangopenbanking.com/v1/errors/validation-error",
                  "title": "Validation Error",
                  "status": 400
                }
              },
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                },
                "example": {
                  "type": "https://api.kangopenbanking.com/v1/errors/validation-error",
                  "title": "Validation Error",
                  "status": 400
                }
              }
            }
          },
          "401": {
            "description": "401 Unauthorized — credentials are missing, expired or invalid.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                },
                "example": {
                  "type": "https://api.kangopenbanking.com/v1/errors/unauthorized",
                  "title": "Unauthorized",
                  "status": 401
                }
              },
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                },
                "example": {
                  "type": "https://api.kangopenbanking.com/v1/errors/unauthorized",
                  "title": "Unauthorized",
                  "status": 401
                }
              }
            }
          },
          "429": {
            "description": "Rate limit exceeded. Retry after the interval in `Retry-After`.",
            "headers": {
              "Retry-After": {
                "schema": {
                  "type": "integer"
                },
                "description": "Seconds to wait before retrying."
              },
              "X-RateLimit-Limit": {
                "schema": {
                  "type": "integer"
                }
              },
              "X-RateLimit-Remaining": {
                "schema": {
                  "type": "integer"
                }
              },
              "X-RateLimit-Reset": {
                "schema": {
                  "type": "integer"
                }
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                },
                "examples": {
                  "rateLimited": {
                    "$ref": "#/components/examples/ErrorRateLimited"
                  }
                }
              }
            }
          },
          "500": {
            "description": "500 Internal Server Error — an unexpected condition prevented completion.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                },
                "example": {
                  "type": "https://api.kangopenbanking.com/v1/errors/internal-error",
                  "title": "Internal Server Error",
                  "status": 500
                }
              },
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                },
                "example": {
                  "type": "https://api.kangopenbanking.com/v1/errors/internal-error",
                  "title": "Internal Server Error",
                  "status": 500
                }
              }
            }
          }
        },
        "parameters": [
          {
            "$ref": "#/components/parameters/Traceparent"
          },
          {
            "$ref": "#/components/parameters/Tracestate"
          },
          {
            "$ref": "#/components/parameters/AcceptLanguage"
          }
        ],
        "description": "Budgeting API. Get budget. This is a read-only operation: it never mutates state and its result is scoped to the authenticated caller.",
        "x-codeSamples": [
          {
            "lang": "cURL",
            "label": "cURL",
            "source": "curl -X GET \"https://api.kangopenbanking.com/v1/budgeting/budgets/{budgetId}\" \\\n  -H \"Authorization: Bearer $KOB_ACCESS_TOKEN\" \\\n  -H \"Content-Type: application/json\""
          },
          {
            "lang": "JavaScript",
            "label": "Node.js",
            "source": "import { KangOpenBanking } from \"@kangopenbanking/sdk\";\n\nconst kob = new KangOpenBanking({ apiKey: process.env.KOB_API_KEY });\nconst res = await kob.request(\"GET\", \"/v1/budgeting/budgets/{budgetId}\");\nconsole.log(res);"
          },
          {
            "lang": "Python",
            "label": "Python",
            "source": "from kangopenbanking import KangOpenBanking\n\nkob = KangOpenBanking(api_key=os.environ[\"KOB_API_KEY\"])\nres = kob.request(\"GET\", \"/v1/budgeting/budgets/{budgetId}\")\nprint(res)"
          },
          {
            "lang": "PHP",
            "label": "PHP",
            "source": "<?php\n$kob = new KangOpenBanking\\KangOpenBanking(getenv('KOB_API_KEY'));\n$res = $kob->request('GET', '/v1/budgeting/budgets/{budgetId}');\nprint_r($res);"
          }
        ]
      },
      "patch": {
        "tags": [
          "Budgeting"
        ],
        "operationId": "budgetingUpdateBudget",
        "summary": "Update budget",
        "security": [
          {
            "bearerAuth": []
          }
        ],
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/BudgetCreateRequest"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Budget"
                },
                "example": {
                  "id": "bgt_01HXYZ",
                  "consumer_id": "00000000-0000-4000-8000-000000000000",
                  "name": "May 2026 Budget",
                  "period": "monthly",
                  "start_date": "2026-01-01",
                  "end_date": "2026-01-01",
                  "total_limit": 0,
                  "categories": [
                    {
                      "id": "f1d6f4a0-1d4e-4a3a-9e0a-1a2b3c4d5e6f",
                      "name": "Food & Market",
                      "icon": "ShoppingCart",
                      "colour": "#10D9A0",
                      "limit": 0,
                      "spent": 0,
                      "remaining": 0,
                      "percentage_used": 0,
                      "transaction_count": 0,
                      "top_merchant": "XAF"
                    }
                  ],
                  "currency": "XAF",
                  "status": "active",
                  "created_at": "2026-01-01T00:00:00Z",
                  "updated_at": "2026-01-01T00:00:00Z"
                }
              }
            },
            "headers": {
              "traceparent": {
                "$ref": "#/components/headers/Traceparent"
              },
              "Content-Language": {
                "$ref": "#/components/headers/Content-Language"
              },
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/XRateLimitLimit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/XRateLimitRemaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/XRateLimitReset"
              },
              "x-fapi-interaction-id": {
                "$ref": "#/components/headers/XFapiInteractionId"
              }
            }
          },
          "400": {
            "description": "400 Bad Request — the request failed validation.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                },
                "example": {
                  "type": "https://api.kangopenbanking.com/v1/errors/validation-error",
                  "title": "Validation Error",
                  "status": 400
                }
              },
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                },
                "example": {
                  "type": "https://api.kangopenbanking.com/v1/errors/validation-error",
                  "title": "Validation Error",
                  "status": 400
                }
              }
            }
          },
          "401": {
            "description": "401 Unauthorized — credentials are missing, expired or invalid.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                },
                "example": {
                  "type": "https://api.kangopenbanking.com/v1/errors/unauthorized",
                  "title": "Unauthorized",
                  "status": 401
                }
              },
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                },
                "example": {
                  "type": "https://api.kangopenbanking.com/v1/errors/unauthorized",
                  "title": "Unauthorized",
                  "status": 401
                }
              }
            }
          },
          "429": {
            "description": "Rate limit exceeded. Retry after the interval in `Retry-After`.",
            "headers": {
              "Retry-After": {
                "schema": {
                  "type": "integer"
                },
                "description": "Seconds to wait before retrying."
              },
              "X-RateLimit-Limit": {
                "schema": {
                  "type": "integer"
                }
              },
              "X-RateLimit-Remaining": {
                "schema": {
                  "type": "integer"
                }
              },
              "X-RateLimit-Reset": {
                "schema": {
                  "type": "integer"
                }
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                },
                "examples": {
                  "rateLimited": {
                    "$ref": "#/components/examples/ErrorRateLimited"
                  }
                }
              }
            }
          },
          "500": {
            "description": "500 Internal Server Error — an unexpected condition prevented completion.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                },
                "example": {
                  "type": "https://api.kangopenbanking.com/v1/errors/internal-error",
                  "title": "Internal Server Error",
                  "status": 500
                }
              },
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                },
                "example": {
                  "type": "https://api.kangopenbanking.com/v1/errors/internal-error",
                  "title": "Internal Server Error",
                  "status": 500
                }
              }
            }
          }
        },
        "parameters": [
          {
            "$ref": "#/components/parameters/Traceparent"
          },
          {
            "$ref": "#/components/parameters/Tracestate"
          },
          {
            "$ref": "#/components/parameters/AcceptLanguage"
          }
        ],
        "description": "Budgeting API. Update budget. This operation applies a partial update: only the fields present in the request body are modified.",
        "x-codeSamples": [
          {
            "lang": "cURL",
            "label": "cURL",
            "source": "curl -X PATCH \"https://api.kangopenbanking.com/v1/budgeting/budgets/{budgetId}\" \\\n  -H \"Authorization: Bearer $KOB_ACCESS_TOKEN\" \\\n  -H \"Content-Type: application/json\" \\\n  -d '{}'"
          },
          {
            "lang": "JavaScript",
            "label": "Node.js",
            "source": "import { KangOpenBanking } from \"@kangopenbanking/sdk\";\n\nconst kob = new KangOpenBanking({ apiKey: process.env.KOB_API_KEY });\nconst res = await kob.request(\"PATCH\", \"/v1/budgeting/budgets/{budgetId}\", { /* payload */ });\nconsole.log(res);"
          },
          {
            "lang": "Python",
            "label": "Python",
            "source": "from kangopenbanking import KangOpenBanking\n\nkob = KangOpenBanking(api_key=os.environ[\"KOB_API_KEY\"])\nres = kob.request(\"PATCH\", \"/v1/budgeting/budgets/{budgetId}\", json={})\nprint(res)"
          },
          {
            "lang": "PHP",
            "label": "PHP",
            "source": "<?php\n$kob = new KangOpenBanking\\KangOpenBanking(getenv('KOB_API_KEY'));\n$res = $kob->request('PATCH', '/v1/budgeting/budgets/{budgetId}', []);\nprint_r($res);"
          }
        ]
      },
      "delete": {
        "tags": [
          "Budgeting"
        ],
        "operationId": "budgetingDeleteBudget",
        "summary": "Archive budget",
        "security": [
          {
            "bearerAuth": []
          }
        ],
        "responses": {
          "204": {
            "description": "Budget archived, or already archived (idempotent terminal-state replay). No response body.",
            "headers": {
              "traceparent": {
                "$ref": "#/components/headers/Traceparent"
              },
              "Content-Language": {
                "$ref": "#/components/headers/Content-Language"
              },
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/XRateLimitLimit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/XRateLimitRemaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/XRateLimitReset"
              }
            }
          },
          "400": {
            "description": "Malformed budget identifier or malformed Idempotency-Key header (INVALID_RESOURCE_ID, INVALID_IDEMPOTENCY_KEY).",
            "headers": {},
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                },
                "examples": {
                  "invalid_idempotency_key": {
                    "$ref": "#/components/examples/ProblemDetailsInvalidIdempotencyKey"
                  }
                }
              },
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                },
                "example": {
                  "type": "https://api.kangopenbanking.com/v1/errors/validation-error",
                  "title": "Validation Error",
                  "status": 400
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "404": {
            "$ref": "#/components/responses/NotFound"
          },
          "409": {
            "description": "Idempotency conflict (IDEMPOTENCY_KEY_REUSED when the same key is reused with a changed request body; IDEMPOTENCY_REQUEST_IN_PROGRESS for a concurrent same-key request).",
            "headers": {},
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                },
                "examples": {
                  "idempotency_key_reused": {
                    "$ref": "#/components/examples/ProblemDetailsIdempotencyKeyReused"
                  }
                }
              },
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "429": {
            "$ref": "#/components/responses/TooManyRequests"
          },
          "500": {
            "$ref": "#/components/responses/InternalServerError"
          }
        },
        "parameters": [
          {
            "$ref": "#/components/parameters/Traceparent"
          },
          {
            "$ref": "#/components/parameters/Tracestate"
          },
          {
            "$ref": "#/components/parameters/AcceptLanguage"
          },
          {
            "$ref": "#/components/parameters/IdempotencyKeyHeader"
          }
        ],
        "description": "Archives the budget. The budget is not physically deleted; historical spending remains intact. Returns 204 on the first successful transition, on a valid same-key idempotent replay, and when the budget is already in the archived terminal state (no repeated mutation, audit event or notification is emitted). 404 is returned when the budget does not exist OR when it exists but lies outside the authenticated caller's authoritative scope (ownership/tenant boundaries are intentionally concealed).",
        "x-codeSamples": [
          {
            "lang": "cURL",
            "label": "cURL",
            "source": "curl -X DELETE \"https://api.kangopenbanking.com/v1/budgeting/budgets/{budgetId}\" \\\n  -H \"Authorization: Bearer $KOB_ACCESS_TOKEN\" \\\n  -H \"Content-Type: application/json\""
          },
          {
            "lang": "JavaScript",
            "label": "Node.js",
            "source": "import { KangOpenBanking } from \"@kangopenbanking/sdk\";\n\nconst kob = new KangOpenBanking({ apiKey: process.env.KOB_API_KEY });\nconst res = await kob.request(\"DELETE\", \"/v1/budgeting/budgets/{budgetId}\");\nconsole.log(res);"
          },
          {
            "lang": "Python",
            "label": "Python",
            "source": "from kangopenbanking import KangOpenBanking\n\nkob = KangOpenBanking(api_key=os.environ[\"KOB_API_KEY\"])\nres = kob.request(\"DELETE\", \"/v1/budgeting/budgets/{budgetId}\")\nprint(res)"
          },
          {
            "lang": "PHP",
            "label": "PHP",
            "source": "<?php\n$kob = new KangOpenBanking\\KangOpenBanking(getenv('KOB_API_KEY'));\n$res = $kob->request('DELETE', '/v1/budgeting/budgets/{budgetId}');\nprint_r($res);"
          }
        ]
      }
    },
    "/v1/budgeting/budgets/{budgetId}/summary": {
      "parameters": [
        {
          "name": "budgetId",
          "in": "path",
          "required": true,
          "schema": {
            "type": "string"
          },
          "description": "Budget identifier"
        }
      ],
      "get": {
        "tags": [
          "Budgeting"
        ],
        "operationId": "budgetingGetBudgetSummary",
        "summary": "Get budget summary",
        "security": [
          {
            "bearerAuth": []
          }
        ],
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/BudgetSummary"
                },
                "example": {
                  "budget_id": "string",
                  "period_start": "2026-01-01",
                  "period_end": "2026-01-01",
                  "total_limit": 0,
                  "total_spent": 0,
                  "total_remaining": 0,
                  "percentage_used": 0,
                  "days_remaining": 0,
                  "projected_overspend": true,
                  "projected_end_balance": 0,
                  "categories": [
                    {
                      "id": "f1d6f4a0-1d4e-4a3a-9e0a-1a2b3c4d5e6f",
                      "name": "Food & Market",
                      "icon": "ShoppingCart",
                      "colour": "#10D9A0",
                      "limit": 0,
                      "spent": 0,
                      "remaining": 0,
                      "percentage_used": 0,
                      "transaction_count": 0,
                      "top_merchant": "XAF"
                    }
                  ],
                  "currency": "XAF"
                }
              }
            },
            "headers": {
              "traceparent": {
                "$ref": "#/components/headers/Traceparent"
              },
              "Content-Language": {
                "$ref": "#/components/headers/Content-Language"
              },
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/XRateLimitLimit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/XRateLimitRemaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/XRateLimitReset"
              },
              "x-fapi-interaction-id": {
                "$ref": "#/components/headers/XFapiInteractionId"
              }
            }
          },
          "400": {
            "description": "400 Bad Request — the request failed validation.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                },
                "example": {
                  "type": "https://api.kangopenbanking.com/v1/errors/validation-error",
                  "title": "Validation Error",
                  "status": 400
                }
              },
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                },
                "example": {
                  "type": "https://api.kangopenbanking.com/v1/errors/validation-error",
                  "title": "Validation Error",
                  "status": 400
                }
              }
            }
          },
          "401": {
            "description": "401 Unauthorized — credentials are missing, expired or invalid.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                },
                "example": {
                  "type": "https://api.kangopenbanking.com/v1/errors/unauthorized",
                  "title": "Unauthorized",
                  "status": 401
                }
              },
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                },
                "example": {
                  "type": "https://api.kangopenbanking.com/v1/errors/unauthorized",
                  "title": "Unauthorized",
                  "status": 401
                }
              }
            }
          },
          "429": {
            "description": "Rate limit exceeded. Retry after the interval in `Retry-After`.",
            "headers": {
              "Retry-After": {
                "schema": {
                  "type": "integer"
                },
                "description": "Seconds to wait before retrying."
              },
              "X-RateLimit-Limit": {
                "schema": {
                  "type": "integer"
                }
              },
              "X-RateLimit-Remaining": {
                "schema": {
                  "type": "integer"
                }
              },
              "X-RateLimit-Reset": {
                "schema": {
                  "type": "integer"
                }
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                },
                "examples": {
                  "rateLimited": {
                    "$ref": "#/components/examples/ErrorRateLimited"
                  }
                }
              }
            }
          },
          "500": {
            "description": "500 Internal Server Error — an unexpected condition prevented completion.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                },
                "example": {
                  "type": "https://api.kangopenbanking.com/v1/errors/internal-error",
                  "title": "Internal Server Error",
                  "status": 500
                }
              },
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                },
                "example": {
                  "type": "https://api.kangopenbanking.com/v1/errors/internal-error",
                  "title": "Internal Server Error",
                  "status": 500
                }
              }
            }
          }
        },
        "parameters": [
          {
            "$ref": "#/components/parameters/Traceparent"
          },
          {
            "$ref": "#/components/parameters/Tracestate"
          },
          {
            "$ref": "#/components/parameters/AcceptLanguage"
          }
        ],
        "description": "Budgeting API. Get budget summary. This is a read-only operation: it never mutates state and its result is scoped to the authenticated caller.",
        "x-codeSamples": [
          {
            "lang": "cURL",
            "label": "cURL",
            "source": "curl -X GET \"https://api.kangopenbanking.com/v1/budgeting/budgets/{budgetId}/summary\" \\\n  -H \"Authorization: Bearer $KOB_ACCESS_TOKEN\" \\\n  -H \"Content-Type: application/json\""
          },
          {
            "lang": "JavaScript",
            "label": "Node.js",
            "source": "import { KangOpenBanking } from \"@kangopenbanking/sdk\";\n\nconst kob = new KangOpenBanking({ apiKey: process.env.KOB_API_KEY });\nconst res = await kob.request(\"GET\", \"/v1/budgeting/budgets/{budgetId}/summary\");\nconsole.log(res);"
          },
          {
            "lang": "Python",
            "label": "Python",
            "source": "from kangopenbanking import KangOpenBanking\n\nkob = KangOpenBanking(api_key=os.environ[\"KOB_API_KEY\"])\nres = kob.request(\"GET\", \"/v1/budgeting/budgets/{budgetId}/summary\")\nprint(res)"
          },
          {
            "lang": "PHP",
            "label": "PHP",
            "source": "<?php\n$kob = new KangOpenBanking\\KangOpenBanking(getenv('KOB_API_KEY'));\n$res = $kob->request('GET', '/v1/budgeting/budgets/{budgetId}/summary');\nprint_r($res);"
          }
        ]
      }
    },
    "/v1/budgeting/categories": {
      "get": {
        "tags": [
          "Budgeting"
        ],
        "operationId": "budgetingListCategories",
        "summary": "List categories",
        "security": [
          {
            "bearerAuth": []
          }
        ],
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/BudgetCategory"
                },
                "example": {
                  "id": "cat_food",
                  "name": "Food & Market",
                  "icon": "ShoppingCart",
                  "colour": "#10D9A0",
                  "limit": 0,
                  "spent": 0,
                  "remaining": 0,
                  "percentage_used": 0,
                  "transaction_count": 0,
                  "top_merchant": "string"
                }
              }
            },
            "headers": {
              "traceparent": {
                "$ref": "#/components/headers/Traceparent"
              },
              "Content-Language": {
                "$ref": "#/components/headers/Content-Language"
              },
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/XRateLimitLimit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/XRateLimitRemaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/XRateLimitReset"
              },
              "x-fapi-interaction-id": {
                "$ref": "#/components/headers/XFapiInteractionId"
              }
            }
          },
          "400": {
            "description": "400 Bad Request — the request failed validation.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                },
                "example": {
                  "type": "https://api.kangopenbanking.com/v1/errors/validation-error",
                  "title": "Validation Error",
                  "status": 400
                }
              },
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                },
                "example": {
                  "type": "https://api.kangopenbanking.com/v1/errors/validation-error",
                  "title": "Validation Error",
                  "status": 400
                }
              }
            }
          },
          "401": {
            "description": "401 Unauthorized — credentials are missing, expired or invalid.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                },
                "example": {
                  "type": "https://api.kangopenbanking.com/v1/errors/unauthorized",
                  "title": "Unauthorized",
                  "status": 401
                }
              },
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                },
                "example": {
                  "type": "https://api.kangopenbanking.com/v1/errors/unauthorized",
                  "title": "Unauthorized",
                  "status": 401
                }
              }
            }
          },
          "429": {
            "description": "Rate limit exceeded. Retry after the interval in `Retry-After`.",
            "headers": {
              "Retry-After": {
                "schema": {
                  "type": "integer"
                },
                "description": "Seconds to wait before retrying."
              },
              "X-RateLimit-Limit": {
                "schema": {
                  "type": "integer"
                }
              },
              "X-RateLimit-Remaining": {
                "schema": {
                  "type": "integer"
                }
              },
              "X-RateLimit-Reset": {
                "schema": {
                  "type": "integer"
                }
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                },
                "examples": {
                  "rateLimited": {
                    "$ref": "#/components/examples/ErrorRateLimited"
                  }
                }
              }
            }
          },
          "500": {
            "description": "500 Internal Server Error — an unexpected condition prevented completion.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                },
                "example": {
                  "type": "https://api.kangopenbanking.com/v1/errors/internal-error",
                  "title": "Internal Server Error",
                  "status": 500
                }
              },
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                },
                "example": {
                  "type": "https://api.kangopenbanking.com/v1/errors/internal-error",
                  "title": "Internal Server Error",
                  "status": 500
                }
              }
            }
          }
        },
        "parameters": [
          {
            "$ref": "#/components/parameters/Traceparent"
          },
          {
            "$ref": "#/components/parameters/Tracestate"
          },
          {
            "$ref": "#/components/parameters/AcceptLanguage"
          },
          {
            "$ref": "#/components/parameters/LimitParam"
          },
          {
            "$ref": "#/components/parameters/CursorParam"
          }
        ],
        "description": "Budgeting API. List categories. This is a read-only operation: it never mutates state and its result is scoped to the authenticated caller.",
        "x-codeSamples": [
          {
            "lang": "cURL",
            "label": "cURL",
            "source": "curl -X GET \"https://api.kangopenbanking.com/v1/budgeting/categories\" \\\n  -H \"Authorization: Bearer $KOB_ACCESS_TOKEN\" \\\n  -H \"Content-Type: application/json\""
          },
          {
            "lang": "JavaScript",
            "label": "Node.js",
            "source": "import { KangOpenBanking } from \"@kangopenbanking/sdk\";\n\nconst kob = new KangOpenBanking({ apiKey: process.env.KOB_API_KEY });\nconst res = await kob.request(\"GET\", \"/v1/budgeting/categories\");\nconsole.log(res);"
          },
          {
            "lang": "Python",
            "label": "Python",
            "source": "from kangopenbanking import KangOpenBanking\n\nkob = KangOpenBanking(api_key=os.environ[\"KOB_API_KEY\"])\nres = kob.request(\"GET\", \"/v1/budgeting/categories\")\nprint(res)"
          },
          {
            "lang": "PHP",
            "label": "PHP",
            "source": "<?php\n$kob = new KangOpenBanking\\KangOpenBanking(getenv('KOB_API_KEY'));\n$res = $kob->request('GET', '/v1/budgeting/categories');\nprint_r($res);"
          }
        ]
      },
      "post": {
        "tags": [
          "Budgeting"
        ],
        "operationId": "budgetingCreateCategory",
        "summary": "Create category",
        "security": [
          {
            "bearerAuth": []
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/CategoryCreateRequest"
              }
            }
          }
        },
        "responses": {
          "201": {
            "description": "Created",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/BudgetCategory"
                },
                "example": {
                  "id": "cat_food",
                  "name": "Food & Market",
                  "icon": "ShoppingCart",
                  "colour": "#10D9A0",
                  "limit": 0,
                  "spent": 0,
                  "remaining": 0,
                  "percentage_used": 0,
                  "transaction_count": 0,
                  "top_merchant": "string"
                }
              }
            },
            "headers": {
              "traceparent": {
                "$ref": "#/components/headers/Traceparent"
              },
              "Content-Language": {
                "$ref": "#/components/headers/Content-Language"
              },
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/XRateLimitLimit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/XRateLimitRemaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/XRateLimitReset"
              },
              "x-fapi-interaction-id": {
                "$ref": "#/components/headers/XFapiInteractionId"
              }
            }
          },
          "400": {
            "description": "400 Bad Request — the request failed validation.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                },
                "example": {
                  "type": "https://api.kangopenbanking.com/v1/errors/validation-error",
                  "title": "Validation Error",
                  "status": 400
                }
              },
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                },
                "example": {
                  "type": "https://api.kangopenbanking.com/v1/errors/validation-error",
                  "title": "Validation Error",
                  "status": 400
                }
              }
            }
          },
          "401": {
            "description": "401 Unauthorized — credentials are missing, expired or invalid.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                },
                "example": {
                  "type": "https://api.kangopenbanking.com/v1/errors/unauthorized",
                  "title": "Unauthorized",
                  "status": 401
                }
              },
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                },
                "example": {
                  "type": "https://api.kangopenbanking.com/v1/errors/unauthorized",
                  "title": "Unauthorized",
                  "status": 401
                }
              }
            }
          },
          "429": {
            "description": "Rate limit exceeded. Retry after the interval in `Retry-After`.",
            "headers": {
              "Retry-After": {
                "schema": {
                  "type": "integer"
                },
                "description": "Seconds to wait before retrying."
              },
              "X-RateLimit-Limit": {
                "schema": {
                  "type": "integer"
                }
              },
              "X-RateLimit-Remaining": {
                "schema": {
                  "type": "integer"
                }
              },
              "X-RateLimit-Reset": {
                "schema": {
                  "type": "integer"
                }
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                },
                "examples": {
                  "rateLimited": {
                    "$ref": "#/components/examples/ErrorRateLimited"
                  }
                }
              }
            }
          },
          "500": {
            "description": "500 Internal Server Error — an unexpected condition prevented completion.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                },
                "example": {
                  "type": "https://api.kangopenbanking.com/v1/errors/internal-error",
                  "title": "Internal Server Error",
                  "status": 500
                }
              },
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                },
                "example": {
                  "type": "https://api.kangopenbanking.com/v1/errors/internal-error",
                  "title": "Internal Server Error",
                  "status": 500
                }
              }
            }
          }
        },
        "parameters": [
          {
            "$ref": "#/components/parameters/Traceparent"
          },
          {
            "$ref": "#/components/parameters/Tracestate"
          },
          {
            "$ref": "#/components/parameters/AcceptLanguage"
          }
        ],
        "description": "Budgeting API. Create category. This is a state-changing operation. Where the contract declares an `Idempotency-Key` parameter, the header is required and a retried key replays the original result instead of creating a duplicate.",
        "x-codeSamples": [
          {
            "lang": "cURL",
            "label": "cURL",
            "source": "curl -X POST \"https://api.kangopenbanking.com/v1/budgeting/categories\" \\\n  -H \"Authorization: Bearer $KOB_ACCESS_TOKEN\" \\\n  -H \"Content-Type: application/json\" \\\n  -d '{}'"
          },
          {
            "lang": "JavaScript",
            "label": "Node.js",
            "source": "import { KangOpenBanking } from \"@kangopenbanking/sdk\";\n\nconst kob = new KangOpenBanking({ apiKey: process.env.KOB_API_KEY });\nconst res = await kob.request(\"POST\", \"/v1/budgeting/categories\", { /* payload */ });\nconsole.log(res);"
          },
          {
            "lang": "Python",
            "label": "Python",
            "source": "from kangopenbanking import KangOpenBanking\n\nkob = KangOpenBanking(api_key=os.environ[\"KOB_API_KEY\"])\nres = kob.request(\"POST\", \"/v1/budgeting/categories\", json={})\nprint(res)"
          },
          {
            "lang": "PHP",
            "label": "PHP",
            "source": "<?php\n$kob = new KangOpenBanking\\KangOpenBanking(getenv('KOB_API_KEY'));\n$res = $kob->request('POST', '/v1/budgeting/categories', []);\nprint_r($res);"
          }
        ]
      }
    },
    "/v1/budgeting/categories/{categoryId}": {
      "parameters": [
        {
          "name": "categoryId",
          "in": "path",
          "required": true,
          "schema": {
            "type": "string"
          },
          "description": "Category identifier"
        }
      ],
      "patch": {
        "tags": [
          "Budgeting"
        ],
        "operationId": "budgetingUpdateCategory",
        "summary": "Update category",
        "security": [
          {
            "bearerAuth": []
          }
        ],
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/CategoryCreateRequest"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/BudgetCategory"
                },
                "example": {
                  "id": "cat_food",
                  "name": "Food & Market",
                  "icon": "ShoppingCart",
                  "colour": "#10D9A0",
                  "limit": 0,
                  "spent": 0,
                  "remaining": 0,
                  "percentage_used": 0,
                  "transaction_count": 0,
                  "top_merchant": "string"
                }
              }
            },
            "headers": {
              "traceparent": {
                "$ref": "#/components/headers/Traceparent"
              },
              "Content-Language": {
                "$ref": "#/components/headers/Content-Language"
              },
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/XRateLimitLimit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/XRateLimitRemaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/XRateLimitReset"
              },
              "x-fapi-interaction-id": {
                "$ref": "#/components/headers/XFapiInteractionId"
              }
            }
          },
          "400": {
            "description": "400 Bad Request — the request failed validation.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                },
                "example": {
                  "type": "https://api.kangopenbanking.com/v1/errors/validation-error",
                  "title": "Validation Error",
                  "status": 400
                }
              },
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                },
                "example": {
                  "type": "https://api.kangopenbanking.com/v1/errors/validation-error",
                  "title": "Validation Error",
                  "status": 400
                }
              }
            }
          },
          "401": {
            "description": "401 Unauthorized — credentials are missing, expired or invalid.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                },
                "example": {
                  "type": "https://api.kangopenbanking.com/v1/errors/unauthorized",
                  "title": "Unauthorized",
                  "status": 401
                }
              },
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                },
                "example": {
                  "type": "https://api.kangopenbanking.com/v1/errors/unauthorized",
                  "title": "Unauthorized",
                  "status": 401
                }
              }
            }
          },
          "429": {
            "description": "Rate limit exceeded. Retry after the interval in `Retry-After`.",
            "headers": {
              "Retry-After": {
                "schema": {
                  "type": "integer"
                },
                "description": "Seconds to wait before retrying."
              },
              "X-RateLimit-Limit": {
                "schema": {
                  "type": "integer"
                }
              },
              "X-RateLimit-Remaining": {
                "schema": {
                  "type": "integer"
                }
              },
              "X-RateLimit-Reset": {
                "schema": {
                  "type": "integer"
                }
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                },
                "examples": {
                  "rateLimited": {
                    "$ref": "#/components/examples/ErrorRateLimited"
                  }
                }
              }
            }
          },
          "500": {
            "description": "500 Internal Server Error — an unexpected condition prevented completion.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                },
                "example": {
                  "type": "https://api.kangopenbanking.com/v1/errors/internal-error",
                  "title": "Internal Server Error",
                  "status": 500
                }
              },
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                },
                "example": {
                  "type": "https://api.kangopenbanking.com/v1/errors/internal-error",
                  "title": "Internal Server Error",
                  "status": 500
                }
              }
            }
          }
        },
        "parameters": [
          {
            "$ref": "#/components/parameters/Traceparent"
          },
          {
            "$ref": "#/components/parameters/Tracestate"
          },
          {
            "$ref": "#/components/parameters/AcceptLanguage"
          }
        ],
        "description": "Budgeting API. Update category. This operation applies a partial update: only the fields present in the request body are modified.",
        "x-codeSamples": [
          {
            "lang": "cURL",
            "label": "cURL",
            "source": "curl -X PATCH \"https://api.kangopenbanking.com/v1/budgeting/categories/{categoryId}\" \\\n  -H \"Authorization: Bearer $KOB_ACCESS_TOKEN\" \\\n  -H \"Content-Type: application/json\" \\\n  -d '{}'"
          },
          {
            "lang": "JavaScript",
            "label": "Node.js",
            "source": "import { KangOpenBanking } from \"@kangopenbanking/sdk\";\n\nconst kob = new KangOpenBanking({ apiKey: process.env.KOB_API_KEY });\nconst res = await kob.request(\"PATCH\", \"/v1/budgeting/categories/{categoryId}\", { /* payload */ });\nconsole.log(res);"
          },
          {
            "lang": "Python",
            "label": "Python",
            "source": "from kangopenbanking import KangOpenBanking\n\nkob = KangOpenBanking(api_key=os.environ[\"KOB_API_KEY\"])\nres = kob.request(\"PATCH\", \"/v1/budgeting/categories/{categoryId}\", json={})\nprint(res)"
          },
          {
            "lang": "PHP",
            "label": "PHP",
            "source": "<?php\n$kob = new KangOpenBanking\\KangOpenBanking(getenv('KOB_API_KEY'));\n$res = $kob->request('PATCH', '/v1/budgeting/categories/{categoryId}', []);\nprint_r($res);"
          }
        ]
      },
      "delete": {
        "tags": [
          "Budgeting"
        ],
        "operationId": "budgetingDeleteCategory",
        "summary": "Delete category",
        "security": [
          {
            "bearerAuth": []
          }
        ],
        "responses": {
          "204": {
            "description": "Category soft-deleted, or already soft-deleted (idempotent terminal-state replay). No response body.",
            "headers": {
              "traceparent": {
                "$ref": "#/components/headers/Traceparent"
              },
              "Content-Language": {
                "$ref": "#/components/headers/Content-Language"
              },
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/XRateLimitLimit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/XRateLimitRemaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/XRateLimitReset"
              }
            }
          },
          "400": {
            "description": "Malformed category identifier or malformed Idempotency-Key header (INVALID_RESOURCE_ID, INVALID_IDEMPOTENCY_KEY).",
            "headers": {},
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                },
                "examples": {
                  "invalid_idempotency_key": {
                    "$ref": "#/components/examples/ProblemDetailsInvalidIdempotencyKey"
                  }
                }
              },
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                },
                "example": {
                  "type": "https://api.kangopenbanking.com/v1/errors/validation-error",
                  "title": "Validation Error",
                  "status": 400
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "404": {
            "$ref": "#/components/responses/NotFound"
          },
          "409": {
            "description": "Conflict: protected system category (SYSTEM_CATEGORY_PROTECTED), category has active dependencies (CATEGORY_HAS_ACTIVE_DEPENDENCIES), or idempotency conflict (IDEMPOTENCY_KEY_REUSED, IDEMPOTENCY_REQUEST_IN_PROGRESS).",
            "headers": {},
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                },
                "examples": {
                  "system_category_protected": {
                    "$ref": "#/components/examples/ProblemDetailsSystemCategoryProtected"
                  },
                  "category_has_active_dependencies": {
                    "$ref": "#/components/examples/ProblemDetailsCategoryActiveDependencies"
                  },
                  "idempotency_key_reused": {
                    "$ref": "#/components/examples/ProblemDetailsIdempotencyKeyReused"
                  }
                }
              },
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "429": {
            "$ref": "#/components/responses/TooManyRequests"
          },
          "500": {
            "$ref": "#/components/responses/InternalServerError"
          }
        },
        "parameters": [
          {
            "$ref": "#/components/parameters/Traceparent"
          },
          {
            "$ref": "#/components/parameters/Tracestate"
          },
          {
            "$ref": "#/components/parameters/AcceptLanguage"
          },
          {
            "$ref": "#/components/parameters/IdempotencyKeyHeader"
          }
        ],
        "description": "Soft-deletes an eligible user category. The category is not physically removed; historical transactions retain their category linkage. Returns 204 on the first successful transition, on a valid same-key idempotent replay, and when the category is already in the soft-deleted terminal state (no repeated mutation, audit event or notification is emitted). 404 is returned when the category does not exist OR when it exists but lies outside the authenticated caller's authoritative scope (ownership/tenant boundaries are intentionally concealed). System-managed categories cannot be soft-deleted (409 SYSTEM_CATEGORY_PROTECTED). Categories with active dependencies cannot be soft-deleted (409 CATEGORY_HAS_ACTIVE_DEPENDENCIES).",
        "x-codeSamples": [
          {
            "lang": "cURL",
            "label": "cURL",
            "source": "curl -X DELETE \"https://api.kangopenbanking.com/v1/budgeting/categories/{categoryId}\" \\\n  -H \"Authorization: Bearer $KOB_ACCESS_TOKEN\" \\\n  -H \"Content-Type: application/json\""
          },
          {
            "lang": "JavaScript",
            "label": "Node.js",
            "source": "import { KangOpenBanking } from \"@kangopenbanking/sdk\";\n\nconst kob = new KangOpenBanking({ apiKey: process.env.KOB_API_KEY });\nconst res = await kob.request(\"DELETE\", \"/v1/budgeting/categories/{categoryId}\");\nconsole.log(res);"
          },
          {
            "lang": "Python",
            "label": "Python",
            "source": "from kangopenbanking import KangOpenBanking\n\nkob = KangOpenBanking(api_key=os.environ[\"KOB_API_KEY\"])\nres = kob.request(\"DELETE\", \"/v1/budgeting/categories/{categoryId}\")\nprint(res)"
          },
          {
            "lang": "PHP",
            "label": "PHP",
            "source": "<?php\n$kob = new KangOpenBanking\\KangOpenBanking(getenv('KOB_API_KEY'));\n$res = $kob->request('DELETE', '/v1/budgeting/categories/{categoryId}');\nprint_r($res);"
          }
        ]
      }
    },
    "/v1/budgeting/categories/rules": {
      "get": {
        "tags": [
          "Budgeting"
        ],
        "operationId": "budgetingListRules",
        "summary": "List categorisation rules",
        "security": [
          {
            "bearerAuth": []
          }
        ],
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/CategoryRule"
                },
                "example": {
                  "id": "string",
                  "pattern": "string",
                  "category_id": "string",
                  "priority": 100,
                  "created_at": "2026-01-01T00:00:00Z"
                }
              }
            },
            "headers": {
              "traceparent": {
                "$ref": "#/components/headers/Traceparent"
              },
              "Content-Language": {
                "$ref": "#/components/headers/Content-Language"
              },
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/XRateLimitLimit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/XRateLimitRemaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/XRateLimitReset"
              },
              "x-fapi-interaction-id": {
                "$ref": "#/components/headers/XFapiInteractionId"
              }
            }
          },
          "400": {
            "description": "400 Bad Request — the request failed validation.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                },
                "example": {
                  "type": "https://api.kangopenbanking.com/v1/errors/validation-error",
                  "title": "Validation Error",
                  "status": 400
                }
              },
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                },
                "example": {
                  "type": "https://api.kangopenbanking.com/v1/errors/validation-error",
                  "title": "Validation Error",
                  "status": 400
                }
              }
            }
          },
          "401": {
            "description": "401 Unauthorized — credentials are missing, expired or invalid.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                },
                "example": {
                  "type": "https://api.kangopenbanking.com/v1/errors/unauthorized",
                  "title": "Unauthorized",
                  "status": 401
                }
              },
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                },
                "example": {
                  "type": "https://api.kangopenbanking.com/v1/errors/unauthorized",
                  "title": "Unauthorized",
                  "status": 401
                }
              }
            }
          },
          "429": {
            "description": "Rate limit exceeded. Retry after the interval in `Retry-After`.",
            "headers": {
              "Retry-After": {
                "schema": {
                  "type": "integer"
                },
                "description": "Seconds to wait before retrying."
              },
              "X-RateLimit-Limit": {
                "schema": {
                  "type": "integer"
                }
              },
              "X-RateLimit-Remaining": {
                "schema": {
                  "type": "integer"
                }
              },
              "X-RateLimit-Reset": {
                "schema": {
                  "type": "integer"
                }
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                },
                "examples": {
                  "rateLimited": {
                    "$ref": "#/components/examples/ErrorRateLimited"
                  }
                }
              }
            }
          },
          "500": {
            "description": "500 Internal Server Error — an unexpected condition prevented completion.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                },
                "example": {
                  "type": "https://api.kangopenbanking.com/v1/errors/internal-error",
                  "title": "Internal Server Error",
                  "status": 500
                }
              },
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                },
                "example": {
                  "type": "https://api.kangopenbanking.com/v1/errors/internal-error",
                  "title": "Internal Server Error",
                  "status": 500
                }
              }
            }
          }
        },
        "parameters": [
          {
            "$ref": "#/components/parameters/Traceparent"
          },
          {
            "$ref": "#/components/parameters/Tracestate"
          },
          {
            "$ref": "#/components/parameters/AcceptLanguage"
          },
          {
            "$ref": "#/components/parameters/LimitParam"
          },
          {
            "$ref": "#/components/parameters/CursorParam"
          }
        ],
        "description": "Budgeting API. List categorisation rules. This is a read-only operation: it never mutates state and its result is scoped to the authenticated caller.",
        "x-codeSamples": [
          {
            "lang": "cURL",
            "label": "cURL",
            "source": "curl -X GET \"https://api.kangopenbanking.com/v1/budgeting/categories/rules\" \\\n  -H \"Authorization: Bearer $KOB_ACCESS_TOKEN\" \\\n  -H \"Content-Type: application/json\""
          },
          {
            "lang": "JavaScript",
            "label": "Node.js",
            "source": "import { KangOpenBanking } from \"@kangopenbanking/sdk\";\n\nconst kob = new KangOpenBanking({ apiKey: process.env.KOB_API_KEY });\nconst res = await kob.request(\"GET\", \"/v1/budgeting/categories/rules\");\nconsole.log(res);"
          },
          {
            "lang": "Python",
            "label": "Python",
            "source": "from kangopenbanking import KangOpenBanking\n\nkob = KangOpenBanking(api_key=os.environ[\"KOB_API_KEY\"])\nres = kob.request(\"GET\", \"/v1/budgeting/categories/rules\")\nprint(res)"
          },
          {
            "lang": "PHP",
            "label": "PHP",
            "source": "<?php\n$kob = new KangOpenBanking\\KangOpenBanking(getenv('KOB_API_KEY'));\n$res = $kob->request('GET', '/v1/budgeting/categories/rules');\nprint_r($res);"
          }
        ]
      },
      "post": {
        "tags": [
          "Budgeting"
        ],
        "operationId": "budgetingCreateRule",
        "summary": "Create categorisation rule",
        "security": [
          {
            "bearerAuth": []
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/CategoryRule"
              }
            }
          }
        },
        "responses": {
          "201": {
            "description": "Created",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/CategoryRule"
                },
                "example": {
                  "id": "string",
                  "pattern": "string",
                  "category_id": "string",
                  "priority": 100,
                  "created_at": "2026-01-01T00:00:00Z"
                }
              }
            },
            "headers": {
              "traceparent": {
                "$ref": "#/components/headers/Traceparent"
              },
              "Content-Language": {
                "$ref": "#/components/headers/Content-Language"
              },
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/XRateLimitLimit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/XRateLimitRemaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/XRateLimitReset"
              },
              "x-fapi-interaction-id": {
                "$ref": "#/components/headers/XFapiInteractionId"
              }
            }
          },
          "400": {
            "description": "400 Bad Request — the request failed validation.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                },
                "example": {
                  "type": "https://api.kangopenbanking.com/v1/errors/validation-error",
                  "title": "Validation Error",
                  "status": 400
                }
              },
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                },
                "example": {
                  "type": "https://api.kangopenbanking.com/v1/errors/validation-error",
                  "title": "Validation Error",
                  "status": 400
                }
              }
            }
          },
          "401": {
            "description": "401 Unauthorized — credentials are missing, expired or invalid.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                },
                "example": {
                  "type": "https://api.kangopenbanking.com/v1/errors/unauthorized",
                  "title": "Unauthorized",
                  "status": 401
                }
              },
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                },
                "example": {
                  "type": "https://api.kangopenbanking.com/v1/errors/unauthorized",
                  "title": "Unauthorized",
                  "status": 401
                }
              }
            }
          },
          "429": {
            "description": "Rate limit exceeded. Retry after the interval in `Retry-After`.",
            "headers": {
              "Retry-After": {
                "schema": {
                  "type": "integer"
                },
                "description": "Seconds to wait before retrying."
              },
              "X-RateLimit-Limit": {
                "schema": {
                  "type": "integer"
                }
              },
              "X-RateLimit-Remaining": {
                "schema": {
                  "type": "integer"
                }
              },
              "X-RateLimit-Reset": {
                "schema": {
                  "type": "integer"
                }
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                },
                "examples": {
                  "rateLimited": {
                    "$ref": "#/components/examples/ErrorRateLimited"
                  }
                }
              }
            }
          },
          "500": {
            "description": "500 Internal Server Error — an unexpected condition prevented completion.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                },
                "example": {
                  "type": "https://api.kangopenbanking.com/v1/errors/internal-error",
                  "title": "Internal Server Error",
                  "status": 500
                }
              },
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                },
                "example": {
                  "type": "https://api.kangopenbanking.com/v1/errors/internal-error",
                  "title": "Internal Server Error",
                  "status": 500
                }
              }
            }
          }
        },
        "parameters": [
          {
            "$ref": "#/components/parameters/Traceparent"
          },
          {
            "$ref": "#/components/parameters/Tracestate"
          },
          {
            "$ref": "#/components/parameters/AcceptLanguage"
          }
        ],
        "description": "Budgeting API. Create categorisation rule. This is a state-changing operation. Where the contract declares an `Idempotency-Key` parameter, the header is required and a retried key replays the original result instead of creating a duplicate.",
        "x-codeSamples": [
          {
            "lang": "cURL",
            "label": "cURL",
            "source": "curl -X POST \"https://api.kangopenbanking.com/v1/budgeting/categories/rules\" \\\n  -H \"Authorization: Bearer $KOB_ACCESS_TOKEN\" \\\n  -H \"Content-Type: application/json\" \\\n  -d '{}'"
          },
          {
            "lang": "JavaScript",
            "label": "Node.js",
            "source": "import { KangOpenBanking } from \"@kangopenbanking/sdk\";\n\nconst kob = new KangOpenBanking({ apiKey: process.env.KOB_API_KEY });\nconst res = await kob.request(\"POST\", \"/v1/budgeting/categories/rules\", { /* payload */ });\nconsole.log(res);"
          },
          {
            "lang": "Python",
            "label": "Python",
            "source": "from kangopenbanking import KangOpenBanking\n\nkob = KangOpenBanking(api_key=os.environ[\"KOB_API_KEY\"])\nres = kob.request(\"POST\", \"/v1/budgeting/categories/rules\", json={})\nprint(res)"
          },
          {
            "lang": "PHP",
            "label": "PHP",
            "source": "<?php\n$kob = new KangOpenBanking\\KangOpenBanking(getenv('KOB_API_KEY'));\n$res = $kob->request('POST', '/v1/budgeting/categories/rules', []);\nprint_r($res);"
          }
        ]
      }
    },
    "/v1/budgeting/transactions/{transactionId}/recategorise": {
      "parameters": [
        {
          "name": "transactionId",
          "in": "path",
          "required": true,
          "schema": {
            "type": "string"
          },
          "description": "Transaction identifier"
        }
      ],
      "post": {
        "tags": [
          "Budgeting"
        ],
        "operationId": "budgetingRecategoriseTransaction",
        "summary": "Re-categorise a transaction",
        "security": [
          {
            "bearerAuth": []
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "required": [
                  "category_id"
                ],
                "properties": {
                  "category_id": {
                    "type": "string"
                  }
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/BudgetCategory"
                },
                "example": {
                  "id": "cat_food",
                  "name": "Food & Market",
                  "icon": "ShoppingCart",
                  "colour": "#10D9A0",
                  "limit": 0,
                  "spent": 0,
                  "remaining": 0,
                  "percentage_used": 0,
                  "transaction_count": 0,
                  "top_merchant": "string"
                }
              }
            },
            "headers": {
              "traceparent": {
                "$ref": "#/components/headers/Traceparent"
              },
              "Content-Language": {
                "$ref": "#/components/headers/Content-Language"
              },
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/XRateLimitLimit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/XRateLimitRemaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/XRateLimitReset"
              },
              "x-fapi-interaction-id": {
                "$ref": "#/components/headers/XFapiInteractionId"
              }
            }
          },
          "400": {
            "description": "400 Bad Request — the request failed validation.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                },
                "example": {
                  "type": "https://api.kangopenbanking.com/v1/errors/validation-error",
                  "title": "Validation Error",
                  "status": 400
                }
              },
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                },
                "example": {
                  "type": "https://api.kangopenbanking.com/v1/errors/validation-error",
                  "title": "Validation Error",
                  "status": 400
                }
              }
            }
          },
          "401": {
            "description": "401 Unauthorized — credentials are missing, expired or invalid.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                },
                "example": {
                  "type": "https://api.kangopenbanking.com/v1/errors/unauthorized",
                  "title": "Unauthorized",
                  "status": 401
                }
              },
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                },
                "example": {
                  "type": "https://api.kangopenbanking.com/v1/errors/unauthorized",
                  "title": "Unauthorized",
                  "status": 401
                }
              }
            }
          },
          "429": {
            "description": "Rate limit exceeded. Retry after the interval in `Retry-After`.",
            "headers": {
              "Retry-After": {
                "schema": {
                  "type": "integer"
                },
                "description": "Seconds to wait before retrying."
              },
              "X-RateLimit-Limit": {
                "schema": {
                  "type": "integer"
                }
              },
              "X-RateLimit-Remaining": {
                "schema": {
                  "type": "integer"
                }
              },
              "X-RateLimit-Reset": {
                "schema": {
                  "type": "integer"
                }
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                },
                "examples": {
                  "rateLimited": {
                    "$ref": "#/components/examples/ErrorRateLimited"
                  }
                }
              }
            }
          },
          "500": {
            "description": "500 Internal Server Error — an unexpected condition prevented completion.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                },
                "example": {
                  "type": "https://api.kangopenbanking.com/v1/errors/internal-error",
                  "title": "Internal Server Error",
                  "status": 500
                }
              },
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                },
                "example": {
                  "type": "https://api.kangopenbanking.com/v1/errors/internal-error",
                  "title": "Internal Server Error",
                  "status": 500
                }
              }
            }
          }
        },
        "parameters": [
          {
            "$ref": "#/components/parameters/Traceparent"
          },
          {
            "$ref": "#/components/parameters/Tracestate"
          },
          {
            "$ref": "#/components/parameters/AcceptLanguage"
          }
        ],
        "description": "Budgeting API. Re-categorise a transaction. This is a state-changing operation. Where the contract declares an `Idempotency-Key` parameter, the header is required and a retried key replays the original result instead of creating a duplicate.",
        "x-codeSamples": [
          {
            "lang": "cURL",
            "label": "cURL",
            "source": "curl -X POST \"https://api.kangopenbanking.com/v1/budgeting/transactions/{transactionId}/recategorise\" \\\n  -H \"Authorization: Bearer $KOB_ACCESS_TOKEN\" \\\n  -H \"Content-Type: application/json\" \\\n  -d '{}'"
          },
          {
            "lang": "JavaScript",
            "label": "Node.js",
            "source": "import { KangOpenBanking } from \"@kangopenbanking/sdk\";\n\nconst kob = new KangOpenBanking({ apiKey: process.env.KOB_API_KEY });\nconst res = await kob.request(\"POST\", \"/v1/budgeting/transactions/{transactionId}/recategorise\", { /* payload */ });\nconsole.log(res);"
          },
          {
            "lang": "Python",
            "label": "Python",
            "source": "from kangopenbanking import KangOpenBanking\n\nkob = KangOpenBanking(api_key=os.environ[\"KOB_API_KEY\"])\nres = kob.request(\"POST\", \"/v1/budgeting/transactions/{transactionId}/recategorise\", json={})\nprint(res)"
          },
          {
            "lang": "PHP",
            "label": "PHP",
            "source": "<?php\n$kob = new KangOpenBanking\\KangOpenBanking(getenv('KOB_API_KEY'));\n$res = $kob->request('POST', '/v1/budgeting/transactions/{transactionId}/recategorise', []);\nprint_r($res);"
          }
        ]
      }
    },
    "/v1/budgeting/goals": {
      "get": {
        "tags": [
          "Budgeting"
        ],
        "operationId": "budgetingListGoals",
        "summary": "List savings goals",
        "security": [
          {
            "bearerAuth": []
          }
        ],
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/SavingsGoal"
                },
                "example": {
                  "id": "goal_01HXYZ",
                  "name": "string",
                  "target_amount": 0,
                  "current_amount": 0,
                  "deadline": "2026-01-01",
                  "icon": "string",
                  "colour": "#2563EB",
                  "round_up_enabled": false,
                  "round_up_nearest": 500,
                  "linked_piggy_bank_id": "string",
                  "status": "active",
                  "created_at": "2026-01-01T00:00:00Z"
                }
              }
            },
            "headers": {
              "traceparent": {
                "$ref": "#/components/headers/Traceparent"
              },
              "Content-Language": {
                "$ref": "#/components/headers/Content-Language"
              },
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/XRateLimitLimit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/XRateLimitRemaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/XRateLimitReset"
              },
              "x-fapi-interaction-id": {
                "$ref": "#/components/headers/XFapiInteractionId"
              }
            }
          },
          "400": {
            "description": "400 Bad Request — the request failed validation.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                },
                "example": {
                  "type": "https://api.kangopenbanking.com/v1/errors/validation-error",
                  "title": "Validation Error",
                  "status": 400
                }
              },
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                },
                "example": {
                  "type": "https://api.kangopenbanking.com/v1/errors/validation-error",
                  "title": "Validation Error",
                  "status": 400
                }
              }
            }
          },
          "401": {
            "description": "401 Unauthorized — credentials are missing, expired or invalid.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                },
                "example": {
                  "type": "https://api.kangopenbanking.com/v1/errors/unauthorized",
                  "title": "Unauthorized",
                  "status": 401
                }
              },
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                },
                "example": {
                  "type": "https://api.kangopenbanking.com/v1/errors/unauthorized",
                  "title": "Unauthorized",
                  "status": 401
                }
              }
            }
          },
          "429": {
            "description": "Rate limit exceeded. Retry after the interval in `Retry-After`.",
            "headers": {
              "Retry-After": {
                "schema": {
                  "type": "integer"
                },
                "description": "Seconds to wait before retrying."
              },
              "X-RateLimit-Limit": {
                "schema": {
                  "type": "integer"
                }
              },
              "X-RateLimit-Remaining": {
                "schema": {
                  "type": "integer"
                }
              },
              "X-RateLimit-Reset": {
                "schema": {
                  "type": "integer"
                }
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                },
                "examples": {
                  "rateLimited": {
                    "$ref": "#/components/examples/ErrorRateLimited"
                  }
                }
              }
            }
          },
          "500": {
            "description": "500 Internal Server Error — an unexpected condition prevented completion.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                },
                "example": {
                  "type": "https://api.kangopenbanking.com/v1/errors/internal-error",
                  "title": "Internal Server Error",
                  "status": 500
                }
              },
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                },
                "example": {
                  "type": "https://api.kangopenbanking.com/v1/errors/internal-error",
                  "title": "Internal Server Error",
                  "status": 500
                }
              }
            }
          }
        },
        "parameters": [
          {
            "$ref": "#/components/parameters/Traceparent"
          },
          {
            "$ref": "#/components/parameters/Tracestate"
          },
          {
            "$ref": "#/components/parameters/AcceptLanguage"
          },
          {
            "$ref": "#/components/parameters/LimitParam"
          },
          {
            "$ref": "#/components/parameters/CursorParam"
          }
        ],
        "description": "Budgeting API. List savings goals. This is a read-only operation: it never mutates state and its result is scoped to the authenticated caller.",
        "x-codeSamples": [
          {
            "lang": "cURL",
            "label": "cURL",
            "source": "curl -X GET \"https://api.kangopenbanking.com/v1/budgeting/goals\" \\\n  -H \"Authorization: Bearer $KOB_ACCESS_TOKEN\" \\\n  -H \"Content-Type: application/json\""
          },
          {
            "lang": "JavaScript",
            "label": "Node.js",
            "source": "import { KangOpenBanking } from \"@kangopenbanking/sdk\";\n\nconst kob = new KangOpenBanking({ apiKey: process.env.KOB_API_KEY });\nconst res = await kob.request(\"GET\", \"/v1/budgeting/goals\");\nconsole.log(res);"
          },
          {
            "lang": "Python",
            "label": "Python",
            "source": "from kangopenbanking import KangOpenBanking\n\nkob = KangOpenBanking(api_key=os.environ[\"KOB_API_KEY\"])\nres = kob.request(\"GET\", \"/v1/budgeting/goals\")\nprint(res)"
          },
          {
            "lang": "PHP",
            "label": "PHP",
            "source": "<?php\n$kob = new KangOpenBanking\\KangOpenBanking(getenv('KOB_API_KEY'));\n$res = $kob->request('GET', '/v1/budgeting/goals');\nprint_r($res);"
          }
        ]
      },
      "post": {
        "tags": [
          "Budgeting"
        ],
        "operationId": "budgetingCreateGoal",
        "summary": "Create savings goal",
        "security": [
          {
            "bearerAuth": []
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/SavingsGoal"
              }
            }
          }
        },
        "responses": {
          "201": {
            "description": "Created",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/SavingsGoal"
                },
                "example": {
                  "id": "goal_01HXYZ",
                  "name": "string",
                  "target_amount": 0,
                  "current_amount": 0,
                  "deadline": "2026-01-01",
                  "icon": "string",
                  "colour": "#2563EB",
                  "round_up_enabled": false,
                  "round_up_nearest": 500,
                  "linked_piggy_bank_id": "string",
                  "status": "active",
                  "created_at": "2026-01-01T00:00:00Z"
                }
              }
            },
            "headers": {
              "traceparent": {
                "$ref": "#/components/headers/Traceparent"
              },
              "Content-Language": {
                "$ref": "#/components/headers/Content-Language"
              },
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/XRateLimitLimit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/XRateLimitRemaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/XRateLimitReset"
              },
              "x-fapi-interaction-id": {
                "$ref": "#/components/headers/XFapiInteractionId"
              }
            }
          },
          "400": {
            "description": "400 Bad Request — the request failed validation.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                },
                "example": {
                  "type": "https://api.kangopenbanking.com/v1/errors/validation-error",
                  "title": "Validation Error",
                  "status": 400
                }
              },
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                },
                "example": {
                  "type": "https://api.kangopenbanking.com/v1/errors/validation-error",
                  "title": "Validation Error",
                  "status": 400
                }
              }
            }
          },
          "401": {
            "description": "401 Unauthorized — credentials are missing, expired or invalid.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                },
                "example": {
                  "type": "https://api.kangopenbanking.com/v1/errors/unauthorized",
                  "title": "Unauthorized",
                  "status": 401
                }
              },
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                },
                "example": {
                  "type": "https://api.kangopenbanking.com/v1/errors/unauthorized",
                  "title": "Unauthorized",
                  "status": 401
                }
              }
            }
          },
          "429": {
            "description": "Rate limit exceeded. Retry after the interval in `Retry-After`.",
            "headers": {
              "Retry-After": {
                "schema": {
                  "type": "integer"
                },
                "description": "Seconds to wait before retrying."
              },
              "X-RateLimit-Limit": {
                "schema": {
                  "type": "integer"
                }
              },
              "X-RateLimit-Remaining": {
                "schema": {
                  "type": "integer"
                }
              },
              "X-RateLimit-Reset": {
                "schema": {
                  "type": "integer"
                }
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                },
                "examples": {
                  "rateLimited": {
                    "$ref": "#/components/examples/ErrorRateLimited"
                  }
                }
              }
            }
          },
          "500": {
            "description": "500 Internal Server Error — an unexpected condition prevented completion.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                },
                "example": {
                  "type": "https://api.kangopenbanking.com/v1/errors/internal-error",
                  "title": "Internal Server Error",
                  "status": 500
                }
              },
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                },
                "example": {
                  "type": "https://api.kangopenbanking.com/v1/errors/internal-error",
                  "title": "Internal Server Error",
                  "status": 500
                }
              }
            }
          }
        },
        "parameters": [
          {
            "$ref": "#/components/parameters/Traceparent"
          },
          {
            "$ref": "#/components/parameters/Tracestate"
          },
          {
            "$ref": "#/components/parameters/AcceptLanguage"
          }
        ],
        "description": "Budgeting API. Create savings goal. This is a state-changing operation. Where the contract declares an `Idempotency-Key` parameter, the header is required and a retried key replays the original result instead of creating a duplicate.",
        "x-codeSamples": [
          {
            "lang": "cURL",
            "label": "cURL",
            "source": "curl -X POST \"https://api.kangopenbanking.com/v1/budgeting/goals\" \\\n  -H \"Authorization: Bearer $KOB_ACCESS_TOKEN\" \\\n  -H \"Content-Type: application/json\" \\\n  -d '{}'"
          },
          {
            "lang": "JavaScript",
            "label": "Node.js",
            "source": "import { KangOpenBanking } from \"@kangopenbanking/sdk\";\n\nconst kob = new KangOpenBanking({ apiKey: process.env.KOB_API_KEY });\nconst res = await kob.request(\"POST\", \"/v1/budgeting/goals\", { /* payload */ });\nconsole.log(res);"
          },
          {
            "lang": "Python",
            "label": "Python",
            "source": "from kangopenbanking import KangOpenBanking\n\nkob = KangOpenBanking(api_key=os.environ[\"KOB_API_KEY\"])\nres = kob.request(\"POST\", \"/v1/budgeting/goals\", json={})\nprint(res)"
          },
          {
            "lang": "PHP",
            "label": "PHP",
            "source": "<?php\n$kob = new KangOpenBanking\\KangOpenBanking(getenv('KOB_API_KEY'));\n$res = $kob->request('POST', '/v1/budgeting/goals', []);\nprint_r($res);"
          }
        ]
      }
    },
    "/v1/budgeting/goals/{goalId}": {
      "parameters": [
        {
          "name": "goalId",
          "in": "path",
          "required": true,
          "schema": {
            "type": "string"
          },
          "description": "Goal identifier"
        }
      ],
      "get": {
        "tags": [
          "Budgeting"
        ],
        "operationId": "budgetingGetGoal",
        "summary": "Get goal",
        "security": [
          {
            "bearerAuth": []
          }
        ],
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/SavingsGoal"
                },
                "example": {
                  "id": "goal_01HXYZ",
                  "name": "string",
                  "target_amount": 0,
                  "current_amount": 0,
                  "deadline": "2026-01-01",
                  "icon": "string",
                  "colour": "#2563EB",
                  "round_up_enabled": false,
                  "round_up_nearest": 500,
                  "linked_piggy_bank_id": "string",
                  "status": "active",
                  "created_at": "2026-01-01T00:00:00Z"
                }
              }
            },
            "headers": {
              "traceparent": {
                "$ref": "#/components/headers/Traceparent"
              },
              "Content-Language": {
                "$ref": "#/components/headers/Content-Language"
              },
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/XRateLimitLimit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/XRateLimitRemaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/XRateLimitReset"
              },
              "x-fapi-interaction-id": {
                "$ref": "#/components/headers/XFapiInteractionId"
              }
            }
          },
          "400": {
            "description": "400 Bad Request — the request failed validation.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                },
                "example": {
                  "type": "https://api.kangopenbanking.com/v1/errors/validation-error",
                  "title": "Validation Error",
                  "status": 400
                }
              },
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                },
                "example": {
                  "type": "https://api.kangopenbanking.com/v1/errors/validation-error",
                  "title": "Validation Error",
                  "status": 400
                }
              }
            }
          },
          "401": {
            "description": "401 Unauthorized — credentials are missing, expired or invalid.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                },
                "example": {
                  "type": "https://api.kangopenbanking.com/v1/errors/unauthorized",
                  "title": "Unauthorized",
                  "status": 401
                }
              },
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                },
                "example": {
                  "type": "https://api.kangopenbanking.com/v1/errors/unauthorized",
                  "title": "Unauthorized",
                  "status": 401
                }
              }
            }
          },
          "429": {
            "description": "Rate limit exceeded. Retry after the interval in `Retry-After`.",
            "headers": {
              "Retry-After": {
                "schema": {
                  "type": "integer"
                },
                "description": "Seconds to wait before retrying."
              },
              "X-RateLimit-Limit": {
                "schema": {
                  "type": "integer"
                }
              },
              "X-RateLimit-Remaining": {
                "schema": {
                  "type": "integer"
                }
              },
              "X-RateLimit-Reset": {
                "schema": {
                  "type": "integer"
                }
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                },
                "examples": {
                  "rateLimited": {
                    "$ref": "#/components/examples/ErrorRateLimited"
                  }
                }
              }
            }
          },
          "500": {
            "description": "500 Internal Server Error — an unexpected condition prevented completion.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                },
                "example": {
                  "type": "https://api.kangopenbanking.com/v1/errors/internal-error",
                  "title": "Internal Server Error",
                  "status": 500
                }
              },
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                },
                "example": {
                  "type": "https://api.kangopenbanking.com/v1/errors/internal-error",
                  "title": "Internal Server Error",
                  "status": 500
                }
              }
            }
          }
        },
        "parameters": [
          {
            "$ref": "#/components/parameters/Traceparent"
          },
          {
            "$ref": "#/components/parameters/Tracestate"
          },
          {
            "$ref": "#/components/parameters/AcceptLanguage"
          }
        ],
        "description": "Budgeting API. Get goal. This is a read-only operation: it never mutates state and its result is scoped to the authenticated caller.",
        "x-codeSamples": [
          {
            "lang": "cURL",
            "label": "cURL",
            "source": "curl -X GET \"https://api.kangopenbanking.com/v1/budgeting/goals/{goalId}\" \\\n  -H \"Authorization: Bearer $KOB_ACCESS_TOKEN\" \\\n  -H \"Content-Type: application/json\""
          },
          {
            "lang": "JavaScript",
            "label": "Node.js",
            "source": "import { KangOpenBanking } from \"@kangopenbanking/sdk\";\n\nconst kob = new KangOpenBanking({ apiKey: process.env.KOB_API_KEY });\nconst res = await kob.request(\"GET\", \"/v1/budgeting/goals/{goalId}\");\nconsole.log(res);"
          },
          {
            "lang": "Python",
            "label": "Python",
            "source": "from kangopenbanking import KangOpenBanking\n\nkob = KangOpenBanking(api_key=os.environ[\"KOB_API_KEY\"])\nres = kob.request(\"GET\", \"/v1/budgeting/goals/{goalId}\")\nprint(res)"
          },
          {
            "lang": "PHP",
            "label": "PHP",
            "source": "<?php\n$kob = new KangOpenBanking\\KangOpenBanking(getenv('KOB_API_KEY'));\n$res = $kob->request('GET', '/v1/budgeting/goals/{goalId}');\nprint_r($res);"
          }
        ]
      },
      "patch": {
        "tags": [
          "Budgeting"
        ],
        "operationId": "budgetingUpdateGoal",
        "summary": "Update goal",
        "security": [
          {
            "bearerAuth": []
          }
        ],
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/SavingsGoal"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/SavingsGoal"
                },
                "example": {
                  "id": "goal_01HXYZ",
                  "name": "string",
                  "target_amount": 0,
                  "current_amount": 0,
                  "deadline": "2026-01-01",
                  "icon": "string",
                  "colour": "#2563EB",
                  "round_up_enabled": false,
                  "round_up_nearest": 500,
                  "linked_piggy_bank_id": "string",
                  "status": "active",
                  "created_at": "2026-01-01T00:00:00Z"
                }
              }
            },
            "headers": {
              "traceparent": {
                "$ref": "#/components/headers/Traceparent"
              },
              "Content-Language": {
                "$ref": "#/components/headers/Content-Language"
              },
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/XRateLimitLimit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/XRateLimitRemaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/XRateLimitReset"
              },
              "x-fapi-interaction-id": {
                "$ref": "#/components/headers/XFapiInteractionId"
              }
            }
          },
          "400": {
            "description": "400 Bad Request — the request failed validation.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                },
                "example": {
                  "type": "https://api.kangopenbanking.com/v1/errors/validation-error",
                  "title": "Validation Error",
                  "status": 400
                }
              },
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                },
                "example": {
                  "type": "https://api.kangopenbanking.com/v1/errors/validation-error",
                  "title": "Validation Error",
                  "status": 400
                }
              }
            }
          },
          "401": {
            "description": "401 Unauthorized — credentials are missing, expired or invalid.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                },
                "example": {
                  "type": "https://api.kangopenbanking.com/v1/errors/unauthorized",
                  "title": "Unauthorized",
                  "status": 401
                }
              },
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                },
                "example": {
                  "type": "https://api.kangopenbanking.com/v1/errors/unauthorized",
                  "title": "Unauthorized",
                  "status": 401
                }
              }
            }
          },
          "429": {
            "description": "Rate limit exceeded. Retry after the interval in `Retry-After`.",
            "headers": {
              "Retry-After": {
                "schema": {
                  "type": "integer"
                },
                "description": "Seconds to wait before retrying."
              },
              "X-RateLimit-Limit": {
                "schema": {
                  "type": "integer"
                }
              },
              "X-RateLimit-Remaining": {
                "schema": {
                  "type": "integer"
                }
              },
              "X-RateLimit-Reset": {
                "schema": {
                  "type": "integer"
                }
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                },
                "examples": {
                  "rateLimited": {
                    "$ref": "#/components/examples/ErrorRateLimited"
                  }
                }
              }
            }
          },
          "500": {
            "description": "500 Internal Server Error — an unexpected condition prevented completion.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                },
                "example": {
                  "type": "https://api.kangopenbanking.com/v1/errors/internal-error",
                  "title": "Internal Server Error",
                  "status": 500
                }
              },
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                },
                "example": {
                  "type": "https://api.kangopenbanking.com/v1/errors/internal-error",
                  "title": "Internal Server Error",
                  "status": 500
                }
              }
            }
          }
        },
        "parameters": [
          {
            "$ref": "#/components/parameters/Traceparent"
          },
          {
            "$ref": "#/components/parameters/Tracestate"
          },
          {
            "$ref": "#/components/parameters/AcceptLanguage"
          }
        ],
        "description": "Budgeting API. Update goal. This operation applies a partial update: only the fields present in the request body are modified.",
        "x-codeSamples": [
          {
            "lang": "cURL",
            "label": "cURL",
            "source": "curl -X PATCH \"https://api.kangopenbanking.com/v1/budgeting/goals/{goalId}\" \\\n  -H \"Authorization: Bearer $KOB_ACCESS_TOKEN\" \\\n  -H \"Content-Type: application/json\" \\\n  -d '{}'"
          },
          {
            "lang": "JavaScript",
            "label": "Node.js",
            "source": "import { KangOpenBanking } from \"@kangopenbanking/sdk\";\n\nconst kob = new KangOpenBanking({ apiKey: process.env.KOB_API_KEY });\nconst res = await kob.request(\"PATCH\", \"/v1/budgeting/goals/{goalId}\", { /* payload */ });\nconsole.log(res);"
          },
          {
            "lang": "Python",
            "label": "Python",
            "source": "from kangopenbanking import KangOpenBanking\n\nkob = KangOpenBanking(api_key=os.environ[\"KOB_API_KEY\"])\nres = kob.request(\"PATCH\", \"/v1/budgeting/goals/{goalId}\", json={})\nprint(res)"
          },
          {
            "lang": "PHP",
            "label": "PHP",
            "source": "<?php\n$kob = new KangOpenBanking\\KangOpenBanking(getenv('KOB_API_KEY'));\n$res = $kob->request('PATCH', '/v1/budgeting/goals/{goalId}', []);\nprint_r($res);"
          }
        ]
      },
      "delete": {
        "tags": [
          "Budgeting"
        ],
        "operationId": "budgetingDeleteGoal",
        "summary": "Delete goal",
        "security": [
          {
            "bearerAuth": []
          }
        ],
        "responses": {
          "204": {
            "description": "Goal archived, already archived (idempotent terminal-state replay), or valid same-key idempotent replay. No response body.",
            "headers": {
              "traceparent": {
                "$ref": "#/components/headers/Traceparent"
              },
              "Content-Language": {
                "$ref": "#/components/headers/Content-Language"
              },
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/XRateLimitLimit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/XRateLimitRemaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/XRateLimitReset"
              }
            }
          },
          "400": {
            "description": "Malformed goal identifier or malformed Idempotency-Key header (INVALID_RESOURCE_ID, INVALID_IDEMPOTENCY_KEY). UUIDv5 and oversized idempotency header values are rejected here.",
            "headers": {},
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                },
                "examples": {
                  "invalid_idempotency_key": {
                    "$ref": "#/components/examples/ProblemDetailsInvalidIdempotencyKey"
                  }
                }
              },
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                },
                "example": {
                  "type": "https://api.kangopenbanking.com/v1/errors/validation-error",
                  "title": "Validation Error",
                  "status": 400
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "404": {
            "$ref": "#/components/responses/NotFound"
          },
          "409": {
            "description": "Conflict: unresolved financial operations (GOAL_HAS_PENDING_FINANCIAL_OPERATIONS), unsupported lifecycle transition (GOAL_STATE_CONFLICT), or idempotency conflict (IDEMPOTENCY_KEY_REUSED when the same key is reused with a changed request body; IDEMPOTENCY_REQUEST_IN_PROGRESS for a concurrent same-key request).",
            "headers": {},
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                },
                "examples": {
                  "goal_has_pending_financial_operations": {
                    "$ref": "#/components/examples/ProblemDetailsGoalHasPendingFinancialOperations"
                  },
                  "goal_state_conflict": {
                    "$ref": "#/components/examples/ProblemDetailsGoalStateConflict"
                  },
                  "idempotency_key_reused": {
                    "$ref": "#/components/examples/ProblemDetailsIdempotencyKeyReused"
                  }
                }
              },
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "429": {
            "$ref": "#/components/responses/TooManyRequests"
          },
          "500": {
            "$ref": "#/components/responses/InternalServerError"
          }
        },
        "parameters": [
          {
            "$ref": "#/components/parameters/Traceparent"
          },
          {
            "$ref": "#/components/parameters/Tracestate"
          },
          {
            "$ref": "#/components/parameters/AcceptLanguage"
          },
          {
            "$ref": "#/components/parameters/IdempotencyKeyHeader"
          }
        ],
        "description": "Archives an eligible savings goal by transitioning it to its approved terminal archived state. The goal is not physically deleted; contributions, progress history, round-up transactions and events, ledger entries, payment records, settlement records and reconciliation records are preserved unchanged. No automatic refund, reversal or cancellation is performed. Returns 204 on the first successful transition, on a valid same-key idempotent replay, and when the goal is already in the archived terminal state (no repeated mutation, audit event or notification is emitted). 404 is returned when the goal does not exist OR when it exists but lies outside the authenticated caller's authoritative scope (ownership/tenant boundaries are intentionally concealed). Archival is blocked (409 GOAL_HAS_PENDING_FINANCIAL_OPERATIONS) while the goal has unresolved contributions, transfers, settlements, payment instructions or round-up instructions; unsupported lifecycle transitions return 409 GOAL_STATE_CONFLICT.",
        "x-codeSamples": [
          {
            "lang": "cURL",
            "label": "cURL",
            "source": "curl -X DELETE \"https://api.kangopenbanking.com/v1/budgeting/goals/{goalId}\" \\\n  -H \"Authorization: Bearer $KOB_ACCESS_TOKEN\" \\\n  -H \"Content-Type: application/json\""
          },
          {
            "lang": "JavaScript",
            "label": "Node.js",
            "source": "import { KangOpenBanking } from \"@kangopenbanking/sdk\";\n\nconst kob = new KangOpenBanking({ apiKey: process.env.KOB_API_KEY });\nconst res = await kob.request(\"DELETE\", \"/v1/budgeting/goals/{goalId}\");\nconsole.log(res);"
          },
          {
            "lang": "Python",
            "label": "Python",
            "source": "from kangopenbanking import KangOpenBanking\n\nkob = KangOpenBanking(api_key=os.environ[\"KOB_API_KEY\"])\nres = kob.request(\"DELETE\", \"/v1/budgeting/goals/{goalId}\")\nprint(res)"
          },
          {
            "lang": "PHP",
            "label": "PHP",
            "source": "<?php\n$kob = new KangOpenBanking\\KangOpenBanking(getenv('KOB_API_KEY'));\n$res = $kob->request('DELETE', '/v1/budgeting/goals/{goalId}');\nprint_r($res);"
          }
        ]
      }
    },
    "/v1/budgeting/goals/{goalId}/progress": {
      "parameters": [
        {
          "name": "goalId",
          "in": "path",
          "required": true,
          "schema": {
            "type": "string"
          },
          "description": "Goal identifier"
        }
      ],
      "get": {
        "tags": [
          "Budgeting"
        ],
        "operationId": "budgetingGetGoalProgress",
        "summary": "Get goal progress",
        "security": [
          {
            "bearerAuth": []
          }
        ],
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/GoalProgress"
                },
                "example": {
                  "goal_id": "string",
                  "percentage_complete": 0,
                  "amount_remaining": 0,
                  "projected_completion_date": "2026-01-01",
                  "weekly_required": 0,
                  "on_track": true,
                  "milestones_reached": [
                    25
                  ],
                  "next_milestone": 0,
                  "round_up_total_this_month": 0
                }
              }
            },
            "headers": {
              "traceparent": {
                "$ref": "#/components/headers/Traceparent"
              },
              "Content-Language": {
                "$ref": "#/components/headers/Content-Language"
              },
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/XRateLimitLimit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/XRateLimitRemaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/XRateLimitReset"
              },
              "x-fapi-interaction-id": {
                "$ref": "#/components/headers/XFapiInteractionId"
              }
            }
          },
          "400": {
            "description": "400 Bad Request — the request failed validation.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                },
                "example": {
                  "type": "https://api.kangopenbanking.com/v1/errors/validation-error",
                  "title": "Validation Error",
                  "status": 400
                }
              },
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                },
                "example": {
                  "type": "https://api.kangopenbanking.com/v1/errors/validation-error",
                  "title": "Validation Error",
                  "status": 400
                }
              }
            }
          },
          "401": {
            "description": "401 Unauthorized — credentials are missing, expired or invalid.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                },
                "example": {
                  "type": "https://api.kangopenbanking.com/v1/errors/unauthorized",
                  "title": "Unauthorized",
                  "status": 401
                }
              },
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                },
                "example": {
                  "type": "https://api.kangopenbanking.com/v1/errors/unauthorized",
                  "title": "Unauthorized",
                  "status": 401
                }
              }
            }
          },
          "429": {
            "description": "Rate limit exceeded. Retry after the interval in `Retry-After`.",
            "headers": {
              "Retry-After": {
                "schema": {
                  "type": "integer"
                },
                "description": "Seconds to wait before retrying."
              },
              "X-RateLimit-Limit": {
                "schema": {
                  "type": "integer"
                }
              },
              "X-RateLimit-Remaining": {
                "schema": {
                  "type": "integer"
                }
              },
              "X-RateLimit-Reset": {
                "schema": {
                  "type": "integer"
                }
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                },
                "examples": {
                  "rateLimited": {
                    "$ref": "#/components/examples/ErrorRateLimited"
                  }
                }
              }
            }
          },
          "500": {
            "description": "500 Internal Server Error — an unexpected condition prevented completion.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                },
                "example": {
                  "type": "https://api.kangopenbanking.com/v1/errors/internal-error",
                  "title": "Internal Server Error",
                  "status": 500
                }
              },
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                },
                "example": {
                  "type": "https://api.kangopenbanking.com/v1/errors/internal-error",
                  "title": "Internal Server Error",
                  "status": 500
                }
              }
            }
          }
        },
        "parameters": [
          {
            "$ref": "#/components/parameters/Traceparent"
          },
          {
            "$ref": "#/components/parameters/Tracestate"
          },
          {
            "$ref": "#/components/parameters/AcceptLanguage"
          },
          {
            "$ref": "#/components/parameters/LimitParam"
          },
          {
            "$ref": "#/components/parameters/CursorParam"
          }
        ],
        "description": "Budgeting API. Get goal progress. This is a read-only operation: it never mutates state and its result is scoped to the authenticated caller.",
        "x-codeSamples": [
          {
            "lang": "cURL",
            "label": "cURL",
            "source": "curl -X GET \"https://api.kangopenbanking.com/v1/budgeting/goals/{goalId}/progress\" \\\n  -H \"Authorization: Bearer $KOB_ACCESS_TOKEN\" \\\n  -H \"Content-Type: application/json\""
          },
          {
            "lang": "JavaScript",
            "label": "Node.js",
            "source": "import { KangOpenBanking } from \"@kangopenbanking/sdk\";\n\nconst kob = new KangOpenBanking({ apiKey: process.env.KOB_API_KEY });\nconst res = await kob.request(\"GET\", \"/v1/budgeting/goals/{goalId}/progress\");\nconsole.log(res);"
          },
          {
            "lang": "Python",
            "label": "Python",
            "source": "from kangopenbanking import KangOpenBanking\n\nkob = KangOpenBanking(api_key=os.environ[\"KOB_API_KEY\"])\nres = kob.request(\"GET\", \"/v1/budgeting/goals/{goalId}/progress\")\nprint(res)"
          },
          {
            "lang": "PHP",
            "label": "PHP",
            "source": "<?php\n$kob = new KangOpenBanking\\KangOpenBanking(getenv('KOB_API_KEY'));\n$res = $kob->request('GET', '/v1/budgeting/goals/{goalId}/progress');\nprint_r($res);"
          }
        ]
      }
    },
    "/v1/budgeting/goals/{goalId}/round-up": {
      "parameters": [
        {
          "name": "goalId",
          "in": "path",
          "required": true,
          "schema": {
            "type": "string"
          },
          "description": "Goal identifier"
        }
      ],
      "post": {
        "tags": [
          "Budgeting"
        ],
        "operationId": "budgetingEnableRoundUp",
        "summary": "Enable round-up for goal",
        "security": [
          {
            "bearerAuth": []
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "required": [
                  "nearest"
                ],
                "properties": {
                  "nearest": {
                    "type": "integer",
                    "enum": [
                      500,
                      1000,
                      2000
                    ]
                  }
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/SavingsGoal"
                },
                "example": {
                  "id": "goal_01HXYZ",
                  "name": "string",
                  "target_amount": 0,
                  "current_amount": 0,
                  "deadline": "2026-01-01",
                  "icon": "string",
                  "colour": "#2563EB",
                  "round_up_enabled": false,
                  "round_up_nearest": 500,
                  "linked_piggy_bank_id": "string",
                  "status": "active",
                  "created_at": "2026-01-01T00:00:00Z"
                }
              }
            },
            "headers": {
              "traceparent": {
                "$ref": "#/components/headers/Traceparent"
              },
              "Content-Language": {
                "$ref": "#/components/headers/Content-Language"
              },
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/XRateLimitLimit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/XRateLimitRemaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/XRateLimitReset"
              },
              "x-fapi-interaction-id": {
                "$ref": "#/components/headers/XFapiInteractionId"
              }
            }
          },
          "400": {
            "description": "400 Bad Request — the request failed validation.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                },
                "example": {
                  "type": "https://api.kangopenbanking.com/v1/errors/validation-error",
                  "title": "Validation Error",
                  "status": 400
                }
              },
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                },
                "example": {
                  "type": "https://api.kangopenbanking.com/v1/errors/validation-error",
                  "title": "Validation Error",
                  "status": 400
                }
              }
            }
          },
          "401": {
            "description": "401 Unauthorized — credentials are missing, expired or invalid.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                },
                "example": {
                  "type": "https://api.kangopenbanking.com/v1/errors/unauthorized",
                  "title": "Unauthorized",
                  "status": 401
                }
              },
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                },
                "example": {
                  "type": "https://api.kangopenbanking.com/v1/errors/unauthorized",
                  "title": "Unauthorized",
                  "status": 401
                }
              }
            }
          },
          "429": {
            "description": "Rate limit exceeded. Retry after the interval in `Retry-After`.",
            "headers": {
              "Retry-After": {
                "schema": {
                  "type": "integer"
                },
                "description": "Seconds to wait before retrying."
              },
              "X-RateLimit-Limit": {
                "schema": {
                  "type": "integer"
                }
              },
              "X-RateLimit-Remaining": {
                "schema": {
                  "type": "integer"
                }
              },
              "X-RateLimit-Reset": {
                "schema": {
                  "type": "integer"
                }
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                },
                "examples": {
                  "rateLimited": {
                    "$ref": "#/components/examples/ErrorRateLimited"
                  }
                }
              }
            }
          },
          "500": {
            "description": "500 Internal Server Error — an unexpected condition prevented completion.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                },
                "example": {
                  "type": "https://api.kangopenbanking.com/v1/errors/internal-error",
                  "title": "Internal Server Error",
                  "status": 500
                }
              },
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                },
                "example": {
                  "type": "https://api.kangopenbanking.com/v1/errors/internal-error",
                  "title": "Internal Server Error",
                  "status": 500
                }
              }
            }
          }
        },
        "parameters": [
          {
            "$ref": "#/components/parameters/Traceparent"
          },
          {
            "$ref": "#/components/parameters/Tracestate"
          },
          {
            "$ref": "#/components/parameters/AcceptLanguage"
          }
        ],
        "description": "Budgeting API. Enable round-up for goal. This is a state-changing operation. Where the contract declares an `Idempotency-Key` parameter, the header is required and a retried key replays the original result instead of creating a duplicate.",
        "x-codeSamples": [
          {
            "lang": "cURL",
            "label": "cURL",
            "source": "curl -X POST \"https://api.kangopenbanking.com/v1/budgeting/goals/{goalId}/round-up\" \\\n  -H \"Authorization: Bearer $KOB_ACCESS_TOKEN\" \\\n  -H \"Content-Type: application/json\" \\\n  -d '{}'"
          },
          {
            "lang": "JavaScript",
            "label": "Node.js",
            "source": "import { KangOpenBanking } from \"@kangopenbanking/sdk\";\n\nconst kob = new KangOpenBanking({ apiKey: process.env.KOB_API_KEY });\nconst res = await kob.request(\"POST\", \"/v1/budgeting/goals/{goalId}/round-up\", { /* payload */ });\nconsole.log(res);"
          },
          {
            "lang": "Python",
            "label": "Python",
            "source": "from kangopenbanking import KangOpenBanking\n\nkob = KangOpenBanking(api_key=os.environ[\"KOB_API_KEY\"])\nres = kob.request(\"POST\", \"/v1/budgeting/goals/{goalId}/round-up\", json={})\nprint(res)"
          },
          {
            "lang": "PHP",
            "label": "PHP",
            "source": "<?php\n$kob = new KangOpenBanking\\KangOpenBanking(getenv('KOB_API_KEY'));\n$res = $kob->request('POST', '/v1/budgeting/goals/{goalId}/round-up', []);\nprint_r($res);"
          }
        ]
      },
      "delete": {
        "tags": [
          "Budgeting"
        ],
        "operationId": "budgetingDisableRoundUp",
        "summary": "Disable round-up for goal",
        "security": [
          {
            "bearerAuth": []
          }
        ],
        "responses": {
          "204": {
            "description": "Round-up disabled, already disabled (idempotent terminal-state replay), or valid same-key idempotent replay. No response body.",
            "headers": {
              "traceparent": {
                "$ref": "#/components/headers/Traceparent"
              },
              "Content-Language": {
                "$ref": "#/components/headers/Content-Language"
              },
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/XRateLimitLimit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/XRateLimitRemaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/XRateLimitReset"
              }
            }
          },
          "400": {
            "description": "Malformed goal identifier or malformed Idempotency-Key header (INVALID_RESOURCE_ID, INVALID_IDEMPOTENCY_KEY). UUIDv5 and oversized idempotency header values are rejected here.",
            "headers": {},
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                },
                "examples": {
                  "invalid_idempotency_key": {
                    "$ref": "#/components/examples/ProblemDetailsInvalidIdempotencyKey"
                  }
                }
              },
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                },
                "example": {
                  "type": "https://api.kangopenbanking.com/v1/errors/validation-error",
                  "title": "Validation Error",
                  "status": 400
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "404": {
            "$ref": "#/components/responses/NotFound"
          },
          "409": {
            "description": "Conflict: pending round-up instructions block disablement per the ratified policy (ROUNDUP_HAS_PENDING_INSTRUCTIONS), round-up configuration state prevents immediate disablement (ROUNDUP_STATE_CONFLICT), or idempotency conflict (IDEMPOTENCY_KEY_REUSED, IDEMPOTENCY_REQUEST_IN_PROGRESS).",
            "headers": {},
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                },
                "examples": {
                  "roundup_has_pending_instructions": {
                    "$ref": "#/components/examples/ProblemDetailsRoundupHasPendingInstructions"
                  },
                  "roundup_state_conflict": {
                    "$ref": "#/components/examples/ProblemDetailsRoundupStateConflict"
                  },
                  "idempotency_key_reused": {
                    "$ref": "#/components/examples/ProblemDetailsIdempotencyKeyReused"
                  }
                }
              },
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "429": {
            "$ref": "#/components/responses/TooManyRequests"
          },
          "500": {
            "$ref": "#/components/responses/InternalServerError"
          }
        },
        "parameters": [
          {
            "$ref": "#/components/parameters/Traceparent"
          },
          {
            "$ref": "#/components/parameters/Tracestate"
          },
          {
            "$ref": "#/components/parameters/AcceptLanguage"
          },
          {
            "$ref": "#/components/parameters/IdempotencyKeyHeader"
          }
        ],
        "description": "Disables future round-up activity for the specified savings goal by flipping the round-up configuration flag to disabled. The round-up configuration row, completed round-up transactions, round-up events, ledger postings, reconciliation records and audit trail are preserved unchanged. Existing pending round-up instructions are not implicitly cancelled, reversed or settled by this operation. Returns 204 on the first successful transition, on a valid same-key idempotent replay, and when round-up is already disabled (no repeated mutation, audit event or notification is emitted). 404 is returned when the goal or round-up configuration does not exist OR when it lies outside the authenticated caller's authoritative scope (ownership/tenant boundaries are intentionally concealed). 409 is returned when a ratified pending-instruction policy blocks disablement (ROUNDUP_HAS_PENDING_INSTRUCTIONS) or when the round-up configuration is in a state that cannot be disabled immediately (ROUNDUP_STATE_CONFLICT).",
        "x-codeSamples": [
          {
            "lang": "cURL",
            "label": "cURL",
            "source": "curl -X DELETE \"https://api.kangopenbanking.com/v1/budgeting/goals/{goalId}/round-up\" \\\n  -H \"Authorization: Bearer $KOB_ACCESS_TOKEN\" \\\n  -H \"Content-Type: application/json\""
          },
          {
            "lang": "JavaScript",
            "label": "Node.js",
            "source": "import { KangOpenBanking } from \"@kangopenbanking/sdk\";\n\nconst kob = new KangOpenBanking({ apiKey: process.env.KOB_API_KEY });\nconst res = await kob.request(\"DELETE\", \"/v1/budgeting/goals/{goalId}/round-up\");\nconsole.log(res);"
          },
          {
            "lang": "Python",
            "label": "Python",
            "source": "from kangopenbanking import KangOpenBanking\n\nkob = KangOpenBanking(api_key=os.environ[\"KOB_API_KEY\"])\nres = kob.request(\"DELETE\", \"/v1/budgeting/goals/{goalId}/round-up\")\nprint(res)"
          },
          {
            "lang": "PHP",
            "label": "PHP",
            "source": "<?php\n$kob = new KangOpenBanking\\KangOpenBanking(getenv('KOB_API_KEY'));\n$res = $kob->request('DELETE', '/v1/budgeting/goals/{goalId}/round-up');\nprint_r($res);"
          }
        ]
      }
    },
    "/v1/budgeting/goals/{goalId}/contribute": {
      "parameters": [
        {
          "name": "goalId",
          "in": "path",
          "required": true,
          "schema": {
            "type": "string"
          },
          "description": "Goal identifier"
        }
      ],
      "post": {
        "tags": [
          "Budgeting"
        ],
        "operationId": "budgetingContributeToGoal",
        "summary": "Manual goal contribution",
        "security": [
          {
            "bearerAuth": []
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "required": [
                  "amount"
                ],
                "properties": {
                  "amount": {
                    "type": "integer",
                    "minimum": 1
                  },
                  "idempotency_key": {
                    "type": "string",
                    "format": "uuid"
                  }
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/SavingsGoal"
                },
                "example": {
                  "id": "goal_01HXYZ",
                  "name": "string",
                  "target_amount": 0,
                  "current_amount": 0,
                  "deadline": "2026-01-01",
                  "icon": "string",
                  "colour": "#2563EB",
                  "round_up_enabled": false,
                  "round_up_nearest": 500,
                  "linked_piggy_bank_id": "string",
                  "status": "active",
                  "created_at": "2026-01-01T00:00:00Z"
                }
              }
            },
            "headers": {
              "traceparent": {
                "$ref": "#/components/headers/Traceparent"
              },
              "Content-Language": {
                "$ref": "#/components/headers/Content-Language"
              },
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/XRateLimitLimit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/XRateLimitRemaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/XRateLimitReset"
              },
              "x-fapi-interaction-id": {
                "$ref": "#/components/headers/XFapiInteractionId"
              }
            }
          },
          "400": {
            "description": "400 Bad Request — the request failed validation.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                },
                "example": {
                  "type": "https://api.kangopenbanking.com/v1/errors/validation-error",
                  "title": "Validation Error",
                  "status": 400
                }
              },
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                },
                "example": {
                  "type": "https://api.kangopenbanking.com/v1/errors/validation-error",
                  "title": "Validation Error",
                  "status": 400
                }
              }
            }
          },
          "401": {
            "description": "401 Unauthorized — credentials are missing, expired or invalid.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                },
                "example": {
                  "type": "https://api.kangopenbanking.com/v1/errors/unauthorized",
                  "title": "Unauthorized",
                  "status": 401
                }
              },
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                },
                "example": {
                  "type": "https://api.kangopenbanking.com/v1/errors/unauthorized",
                  "title": "Unauthorized",
                  "status": 401
                }
              }
            }
          },
          "429": {
            "description": "Rate limit exceeded. Retry after the interval in `Retry-After`.",
            "headers": {
              "Retry-After": {
                "schema": {
                  "type": "integer"
                },
                "description": "Seconds to wait before retrying."
              },
              "X-RateLimit-Limit": {
                "schema": {
                  "type": "integer"
                }
              },
              "X-RateLimit-Remaining": {
                "schema": {
                  "type": "integer"
                }
              },
              "X-RateLimit-Reset": {
                "schema": {
                  "type": "integer"
                }
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                },
                "examples": {
                  "rateLimited": {
                    "$ref": "#/components/examples/ErrorRateLimited"
                  }
                }
              }
            }
          },
          "500": {
            "description": "500 Internal Server Error — an unexpected condition prevented completion.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                },
                "example": {
                  "type": "https://api.kangopenbanking.com/v1/errors/internal-error",
                  "title": "Internal Server Error",
                  "status": 500
                }
              },
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                },
                "example": {
                  "type": "https://api.kangopenbanking.com/v1/errors/internal-error",
                  "title": "Internal Server Error",
                  "status": 500
                }
              }
            }
          }
        },
        "parameters": [
          {
            "$ref": "#/components/parameters/Traceparent"
          },
          {
            "$ref": "#/components/parameters/Tracestate"
          },
          {
            "$ref": "#/components/parameters/AcceptLanguage"
          }
        ],
        "description": "Budgeting API. Manual goal contribution. This is a state-changing operation. Where the contract declares an `Idempotency-Key` parameter, the header is required and a retried key replays the original result instead of creating a duplicate.",
        "x-codeSamples": [
          {
            "lang": "cURL",
            "label": "cURL",
            "source": "curl -X POST \"https://api.kangopenbanking.com/v1/budgeting/goals/{goalId}/contribute\" \\\n  -H \"Authorization: Bearer $KOB_ACCESS_TOKEN\" \\\n  -H \"Content-Type: application/json\" \\\n  -d '{}'"
          },
          {
            "lang": "JavaScript",
            "label": "Node.js",
            "source": "import { KangOpenBanking } from \"@kangopenbanking/sdk\";\n\nconst kob = new KangOpenBanking({ apiKey: process.env.KOB_API_KEY });\nconst res = await kob.request(\"POST\", \"/v1/budgeting/goals/{goalId}/contribute\", { /* payload */ });\nconsole.log(res);"
          },
          {
            "lang": "Python",
            "label": "Python",
            "source": "from kangopenbanking import KangOpenBanking\n\nkob = KangOpenBanking(api_key=os.environ[\"KOB_API_KEY\"])\nres = kob.request(\"POST\", \"/v1/budgeting/goals/{goalId}/contribute\", json={})\nprint(res)"
          },
          {
            "lang": "PHP",
            "label": "PHP",
            "source": "<?php\n$kob = new KangOpenBanking\\KangOpenBanking(getenv('KOB_API_KEY'));\n$res = $kob->request('POST', '/v1/budgeting/goals/{goalId}/contribute', []);\nprint_r($res);"
          }
        ]
      }
    },
    "/v1/budgeting/njangi/{groupId}/schedule": {
      "parameters": [
        {
          "name": "groupId",
          "in": "path",
          "required": true,
          "schema": {
            "type": "string"
          },
          "description": "Njangi group identifier"
        }
      ],
      "get": {
        "tags": [
          "Budgeting"
        ],
        "operationId": "budgetingGetNjangiSchedule",
        "summary": "Get Njangi schedule",
        "security": [
          {
            "bearerAuth": []
          }
        ],
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/NjangiSchedule"
                },
                "example": {
                  "group_id": "string",
                  "group_name": "string",
                  "next_contribution_date": "2026-01-01",
                  "next_contribution_amount": 0,
                  "days_until_due": 0,
                  "budget_impact_xaf": 0,
                  "reminder_enabled": true
                }
              }
            },
            "headers": {
              "traceparent": {
                "$ref": "#/components/headers/Traceparent"
              },
              "Content-Language": {
                "$ref": "#/components/headers/Content-Language"
              },
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/XRateLimitLimit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/XRateLimitRemaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/XRateLimitReset"
              },
              "x-fapi-interaction-id": {
                "$ref": "#/components/headers/XFapiInteractionId"
              }
            }
          },
          "400": {
            "description": "400 Bad Request — the request failed validation.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                },
                "example": {
                  "type": "https://api.kangopenbanking.com/v1/errors/validation-error",
                  "title": "Validation Error",
                  "status": 400
                }
              },
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                },
                "example": {
                  "type": "https://api.kangopenbanking.com/v1/errors/validation-error",
                  "title": "Validation Error",
                  "status": 400
                }
              }
            }
          },
          "401": {
            "description": "401 Unauthorized — credentials are missing, expired or invalid.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                },
                "example": {
                  "type": "https://api.kangopenbanking.com/v1/errors/unauthorized",
                  "title": "Unauthorized",
                  "status": 401
                }
              },
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                },
                "example": {
                  "type": "https://api.kangopenbanking.com/v1/errors/unauthorized",
                  "title": "Unauthorized",
                  "status": 401
                }
              }
            }
          },
          "429": {
            "description": "Rate limit exceeded. Retry after the interval in `Retry-After`.",
            "headers": {
              "Retry-After": {
                "schema": {
                  "type": "integer"
                },
                "description": "Seconds to wait before retrying."
              },
              "X-RateLimit-Limit": {
                "schema": {
                  "type": "integer"
                }
              },
              "X-RateLimit-Remaining": {
                "schema": {
                  "type": "integer"
                }
              },
              "X-RateLimit-Reset": {
                "schema": {
                  "type": "integer"
                }
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                },
                "examples": {
                  "rateLimited": {
                    "$ref": "#/components/examples/ErrorRateLimited"
                  }
                }
              }
            }
          },
          "500": {
            "description": "500 Internal Server Error — an unexpected condition prevented completion.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                },
                "example": {
                  "type": "https://api.kangopenbanking.com/v1/errors/internal-error",
                  "title": "Internal Server Error",
                  "status": 500
                }
              },
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                },
                "example": {
                  "type": "https://api.kangopenbanking.com/v1/errors/internal-error",
                  "title": "Internal Server Error",
                  "status": 500
                }
              }
            }
          }
        },
        "parameters": [
          {
            "$ref": "#/components/parameters/Traceparent"
          },
          {
            "$ref": "#/components/parameters/Tracestate"
          },
          {
            "$ref": "#/components/parameters/AcceptLanguage"
          }
        ],
        "description": "Budgeting API. Get Njangi schedule. This is a read-only operation: it never mutates state and its result is scoped to the authenticated caller.",
        "x-codeSamples": [
          {
            "lang": "cURL",
            "label": "cURL",
            "source": "curl -X GET \"https://api.kangopenbanking.com/v1/budgeting/njangi/{groupId}/schedule\" \\\n  -H \"Authorization: Bearer $KOB_ACCESS_TOKEN\" \\\n  -H \"Content-Type: application/json\""
          },
          {
            "lang": "JavaScript",
            "label": "Node.js",
            "source": "import { KangOpenBanking } from \"@kangopenbanking/sdk\";\n\nconst kob = new KangOpenBanking({ apiKey: process.env.KOB_API_KEY });\nconst res = await kob.request(\"GET\", \"/v1/budgeting/njangi/{groupId}/schedule\");\nconsole.log(res);"
          },
          {
            "lang": "Python",
            "label": "Python",
            "source": "from kangopenbanking import KangOpenBanking\n\nkob = KangOpenBanking(api_key=os.environ[\"KOB_API_KEY\"])\nres = kob.request(\"GET\", \"/v1/budgeting/njangi/{groupId}/schedule\")\nprint(res)"
          },
          {
            "lang": "PHP",
            "label": "PHP",
            "source": "<?php\n$kob = new KangOpenBanking\\KangOpenBanking(getenv('KOB_API_KEY'));\n$res = $kob->request('GET', '/v1/budgeting/njangi/{groupId}/schedule');\nprint_r($res);"
          }
        ]
      }
    },
    "/v1/budgeting/njangi/{groupId}/budget-impact": {
      "parameters": [
        {
          "name": "groupId",
          "in": "path",
          "required": true,
          "schema": {
            "type": "string"
          },
          "description": "Njangi group identifier"
        }
      ],
      "get": {
        "tags": [
          "Budgeting"
        ],
        "operationId": "budgetingGetNjangiBudgetImpact",
        "summary": "Get Njangi budget impact",
        "security": [
          {
            "bearerAuth": []
          }
        ],
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/NjangiSchedule"
                },
                "example": {
                  "group_id": "string",
                  "group_name": "string",
                  "next_contribution_date": "2026-01-01",
                  "next_contribution_amount": 0,
                  "days_until_due": 0,
                  "budget_impact_xaf": 0,
                  "reminder_enabled": true
                }
              }
            },
            "headers": {
              "traceparent": {
                "$ref": "#/components/headers/Traceparent"
              },
              "Content-Language": {
                "$ref": "#/components/headers/Content-Language"
              },
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/XRateLimitLimit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/XRateLimitRemaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/XRateLimitReset"
              },
              "x-fapi-interaction-id": {
                "$ref": "#/components/headers/XFapiInteractionId"
              }
            }
          },
          "400": {
            "description": "400 Bad Request — the request failed validation.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                },
                "example": {
                  "type": "https://api.kangopenbanking.com/v1/errors/validation-error",
                  "title": "Validation Error",
                  "status": 400
                }
              },
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                },
                "example": {
                  "type": "https://api.kangopenbanking.com/v1/errors/validation-error",
                  "title": "Validation Error",
                  "status": 400
                }
              }
            }
          },
          "401": {
            "description": "401 Unauthorized — credentials are missing, expired or invalid.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                },
                "example": {
                  "type": "https://api.kangopenbanking.com/v1/errors/unauthorized",
                  "title": "Unauthorized",
                  "status": 401
                }
              },
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                },
                "example": {
                  "type": "https://api.kangopenbanking.com/v1/errors/unauthorized",
                  "title": "Unauthorized",
                  "status": 401
                }
              }
            }
          },
          "429": {
            "description": "Rate limit exceeded. Retry after the interval in `Retry-After`.",
            "headers": {
              "Retry-After": {
                "schema": {
                  "type": "integer"
                },
                "description": "Seconds to wait before retrying."
              },
              "X-RateLimit-Limit": {
                "schema": {
                  "type": "integer"
                }
              },
              "X-RateLimit-Remaining": {
                "schema": {
                  "type": "integer"
                }
              },
              "X-RateLimit-Reset": {
                "schema": {
                  "type": "integer"
                }
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                },
                "examples": {
                  "rateLimited": {
                    "$ref": "#/components/examples/ErrorRateLimited"
                  }
                }
              }
            }
          },
          "500": {
            "description": "500 Internal Server Error — an unexpected condition prevented completion.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                },
                "example": {
                  "type": "https://api.kangopenbanking.com/v1/errors/internal-error",
                  "title": "Internal Server Error",
                  "status": 500
                }
              },
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                },
                "example": {
                  "type": "https://api.kangopenbanking.com/v1/errors/internal-error",
                  "title": "Internal Server Error",
                  "status": 500
                }
              }
            }
          }
        },
        "parameters": [
          {
            "$ref": "#/components/parameters/Traceparent"
          },
          {
            "$ref": "#/components/parameters/Tracestate"
          },
          {
            "$ref": "#/components/parameters/AcceptLanguage"
          }
        ],
        "description": "Budgeting API. Get Njangi budget impact. This is a read-only operation: it never mutates state and its result is scoped to the authenticated caller.",
        "x-codeSamples": [
          {
            "lang": "cURL",
            "label": "cURL",
            "source": "curl -X GET \"https://api.kangopenbanking.com/v1/budgeting/njangi/{groupId}/budget-impact\" \\\n  -H \"Authorization: Bearer $KOB_ACCESS_TOKEN\" \\\n  -H \"Content-Type: application/json\""
          },
          {
            "lang": "JavaScript",
            "label": "Node.js",
            "source": "import { KangOpenBanking } from \"@kangopenbanking/sdk\";\n\nconst kob = new KangOpenBanking({ apiKey: process.env.KOB_API_KEY });\nconst res = await kob.request(\"GET\", \"/v1/budgeting/njangi/{groupId}/budget-impact\");\nconsole.log(res);"
          },
          {
            "lang": "Python",
            "label": "Python",
            "source": "from kangopenbanking import KangOpenBanking\n\nkob = KangOpenBanking(api_key=os.environ[\"KOB_API_KEY\"])\nres = kob.request(\"GET\", \"/v1/budgeting/njangi/{groupId}/budget-impact\")\nprint(res)"
          },
          {
            "lang": "PHP",
            "label": "PHP",
            "source": "<?php\n$kob = new KangOpenBanking\\KangOpenBanking(getenv('KOB_API_KEY'));\n$res = $kob->request('GET', '/v1/budgeting/njangi/{groupId}/budget-impact');\nprint_r($res);"
          }
        ]
      }
    },
    "/v1/budgeting/njangi/{groupId}/set-reminder": {
      "parameters": [
        {
          "name": "groupId",
          "in": "path",
          "required": true,
          "schema": {
            "type": "string"
          },
          "description": "Njangi group identifier"
        }
      ],
      "post": {
        "tags": [
          "Budgeting"
        ],
        "operationId": "budgetingSetNjangiReminder",
        "summary": "Set Njangi contribution reminder",
        "security": [
          {
            "bearerAuth": []
          }
        ],
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "days_before": {
                    "type": "integer",
                    "default": 3
                  }
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/NjangiSchedule"
                },
                "example": {
                  "group_id": "string",
                  "group_name": "string",
                  "next_contribution_date": "2026-01-01",
                  "next_contribution_amount": 0,
                  "days_until_due": 0,
                  "budget_impact_xaf": 0,
                  "reminder_enabled": true
                }
              }
            },
            "headers": {
              "traceparent": {
                "$ref": "#/components/headers/Traceparent"
              },
              "Content-Language": {
                "$ref": "#/components/headers/Content-Language"
              },
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/XRateLimitLimit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/XRateLimitRemaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/XRateLimitReset"
              },
              "x-fapi-interaction-id": {
                "$ref": "#/components/headers/XFapiInteractionId"
              }
            }
          },
          "400": {
            "description": "400 Bad Request — the request failed validation.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                },
                "example": {
                  "type": "https://api.kangopenbanking.com/v1/errors/validation-error",
                  "title": "Validation Error",
                  "status": 400
                }
              },
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                },
                "example": {
                  "type": "https://api.kangopenbanking.com/v1/errors/validation-error",
                  "title": "Validation Error",
                  "status": 400
                }
              }
            }
          },
          "401": {
            "description": "401 Unauthorized — credentials are missing, expired or invalid.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                },
                "example": {
                  "type": "https://api.kangopenbanking.com/v1/errors/unauthorized",
                  "title": "Unauthorized",
                  "status": 401
                }
              },
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                },
                "example": {
                  "type": "https://api.kangopenbanking.com/v1/errors/unauthorized",
                  "title": "Unauthorized",
                  "status": 401
                }
              }
            }
          },
          "429": {
            "description": "Rate limit exceeded. Retry after the interval in `Retry-After`.",
            "headers": {
              "Retry-After": {
                "schema": {
                  "type": "integer"
                },
                "description": "Seconds to wait before retrying."
              },
              "X-RateLimit-Limit": {
                "schema": {
                  "type": "integer"
                }
              },
              "X-RateLimit-Remaining": {
                "schema": {
                  "type": "integer"
                }
              },
              "X-RateLimit-Reset": {
                "schema": {
                  "type": "integer"
                }
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                },
                "examples": {
                  "rateLimited": {
                    "$ref": "#/components/examples/ErrorRateLimited"
                  }
                }
              }
            }
          },
          "500": {
            "description": "500 Internal Server Error — an unexpected condition prevented completion.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                },
                "example": {
                  "type": "https://api.kangopenbanking.com/v1/errors/internal-error",
                  "title": "Internal Server Error",
                  "status": 500
                }
              },
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                },
                "example": {
                  "type": "https://api.kangopenbanking.com/v1/errors/internal-error",
                  "title": "Internal Server Error",
                  "status": 500
                }
              }
            }
          }
        },
        "parameters": [
          {
            "$ref": "#/components/parameters/Traceparent"
          },
          {
            "$ref": "#/components/parameters/Tracestate"
          },
          {
            "$ref": "#/components/parameters/AcceptLanguage"
          }
        ],
        "description": "Budgeting API. Set Njangi contribution reminder. This is a state-changing operation. Where the contract declares an `Idempotency-Key` parameter, the header is required and a retried key replays the original result instead of creating a duplicate.",
        "x-codeSamples": [
          {
            "lang": "cURL",
            "label": "cURL",
            "source": "curl -X POST \"https://api.kangopenbanking.com/v1/budgeting/njangi/{groupId}/set-reminder\" \\\n  -H \"Authorization: Bearer $KOB_ACCESS_TOKEN\" \\\n  -H \"Content-Type: application/json\" \\\n  -d '{}'"
          },
          {
            "lang": "JavaScript",
            "label": "Node.js",
            "source": "import { KangOpenBanking } from \"@kangopenbanking/sdk\";\n\nconst kob = new KangOpenBanking({ apiKey: process.env.KOB_API_KEY });\nconst res = await kob.request(\"POST\", \"/v1/budgeting/njangi/{groupId}/set-reminder\", { /* payload */ });\nconsole.log(res);"
          },
          {
            "lang": "Python",
            "label": "Python",
            "source": "from kangopenbanking import KangOpenBanking\n\nkob = KangOpenBanking(api_key=os.environ[\"KOB_API_KEY\"])\nres = kob.request(\"POST\", \"/v1/budgeting/njangi/{groupId}/set-reminder\", json={})\nprint(res)"
          },
          {
            "lang": "PHP",
            "label": "PHP",
            "source": "<?php\n$kob = new KangOpenBanking\\KangOpenBanking(getenv('KOB_API_KEY'));\n$res = $kob->request('POST', '/v1/budgeting/njangi/{groupId}/set-reminder', []);\nprint_r($res);"
          }
        ]
      }
    },
    "/v1/budgeting/insights": {
      "get": {
        "tags": [
          "Budgeting"
        ],
        "operationId": "budgetingGetInsights",
        "summary": "Get cached AI insight",
        "security": [
          {
            "bearerAuth": []
          }
        ],
        "parameters": [
          {
            "$ref": "#/components/parameters/BudgetingLangQuery"
          },
          {
            "$ref": "#/components/parameters/Traceparent"
          },
          {
            "$ref": "#/components/parameters/Tracestate"
          },
          {
            "$ref": "#/components/parameters/AcceptLanguage"
          },
          {
            "$ref": "#/components/parameters/LimitParam"
          },
          {
            "$ref": "#/components/parameters/CursorParam"
          }
        ],
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/BudgetInsight"
                },
                "example": {
                  "answer": "string",
                  "lang": "en",
                  "confidence": 0,
                  "suggested_action": {
                    "type": "update_category_limit",
                    "category_id": "string",
                    "suggested_limit": 0
                  },
                  "generated_at": "2026-01-01T00:00:00Z"
                }
              }
            },
            "headers": {
              "traceparent": {
                "$ref": "#/components/headers/Traceparent"
              },
              "Content-Language": {
                "$ref": "#/components/headers/Content-Language"
              },
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/XRateLimitLimit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/XRateLimitRemaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/XRateLimitReset"
              },
              "x-fapi-interaction-id": {
                "$ref": "#/components/headers/XFapiInteractionId"
              }
            }
          },
          "400": {
            "description": "400 Bad Request — the request failed validation.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                },
                "example": {
                  "type": "https://api.kangopenbanking.com/v1/errors/validation-error",
                  "title": "Validation Error",
                  "status": 400
                }
              },
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                },
                "example": {
                  "type": "https://api.kangopenbanking.com/v1/errors/validation-error",
                  "title": "Validation Error",
                  "status": 400
                }
              }
            }
          },
          "401": {
            "description": "401 Unauthorized — credentials are missing, expired or invalid.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                },
                "example": {
                  "type": "https://api.kangopenbanking.com/v1/errors/unauthorized",
                  "title": "Unauthorized",
                  "status": 401
                }
              },
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                },
                "example": {
                  "type": "https://api.kangopenbanking.com/v1/errors/unauthorized",
                  "title": "Unauthorized",
                  "status": 401
                }
              }
            }
          },
          "429": {
            "description": "Rate limit exceeded. Retry after the interval in `Retry-After`.",
            "headers": {
              "Retry-After": {
                "schema": {
                  "type": "integer"
                },
                "description": "Seconds to wait before retrying."
              },
              "X-RateLimit-Limit": {
                "schema": {
                  "type": "integer"
                }
              },
              "X-RateLimit-Remaining": {
                "schema": {
                  "type": "integer"
                }
              },
              "X-RateLimit-Reset": {
                "schema": {
                  "type": "integer"
                }
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                },
                "examples": {
                  "rateLimited": {
                    "$ref": "#/components/examples/ErrorRateLimited"
                  }
                }
              }
            }
          },
          "500": {
            "description": "500 Internal Server Error — an unexpected condition prevented completion.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                },
                "example": {
                  "type": "https://api.kangopenbanking.com/v1/errors/internal-error",
                  "title": "Internal Server Error",
                  "status": 500
                }
              },
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                },
                "example": {
                  "type": "https://api.kangopenbanking.com/v1/errors/internal-error",
                  "title": "Internal Server Error",
                  "status": 500
                }
              }
            }
          }
        },
        "description": "Budgeting API. Get cached AI insight. This is a read-only operation: it never mutates state and its result is scoped to the authenticated caller.",
        "x-codeSamples": [
          {
            "lang": "cURL",
            "label": "cURL",
            "source": "curl -X GET \"https://api.kangopenbanking.com/v1/budgeting/insights\" \\\n  -H \"Authorization: Bearer $KOB_ACCESS_TOKEN\" \\\n  -H \"Content-Type: application/json\""
          },
          {
            "lang": "JavaScript",
            "label": "Node.js",
            "source": "import { KangOpenBanking } from \"@kangopenbanking/sdk\";\n\nconst kob = new KangOpenBanking({ apiKey: process.env.KOB_API_KEY });\nconst res = await kob.request(\"GET\", \"/v1/budgeting/insights\");\nconsole.log(res);"
          },
          {
            "lang": "Python",
            "label": "Python",
            "source": "from kangopenbanking import KangOpenBanking\n\nkob = KangOpenBanking(api_key=os.environ[\"KOB_API_KEY\"])\nres = kob.request(\"GET\", \"/v1/budgeting/insights\")\nprint(res)"
          },
          {
            "lang": "PHP",
            "label": "PHP",
            "source": "<?php\n$kob = new KangOpenBanking\\KangOpenBanking(getenv('KOB_API_KEY'));\n$res = $kob->request('GET', '/v1/budgeting/insights');\nprint_r($res);"
          }
        ]
      }
    },
    "/v1/budgeting/insights/ask": {
      "post": {
        "tags": [
          "Budgeting"
        ],
        "operationId": "budgetingAskInsight",
        "summary": "Ask the AI adviser (rate-limited 10/day)",
        "security": [
          {
            "bearerAuth": []
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/InsightAskRequest"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/InsightAskResponse"
                },
                "example": {
                  "answer": "string",
                  "lang": "en",
                  "confidence": 0,
                  "suggested_action": {
                    "type": "update_category_limit",
                    "category_id": "string",
                    "suggested_limit": 0
                  },
                  "generated_at": "2026-01-01T00:00:00Z"
                }
              }
            },
            "headers": {
              "traceparent": {
                "$ref": "#/components/headers/Traceparent"
              },
              "Content-Language": {
                "$ref": "#/components/headers/Content-Language"
              },
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/XRateLimitLimit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/XRateLimitRemaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/XRateLimitReset"
              },
              "x-fapi-interaction-id": {
                "$ref": "#/components/headers/XFapiInteractionId"
              }
            }
          },
          "400": {
            "description": "400 Bad Request — the request failed validation.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                },
                "example": {
                  "type": "https://api.kangopenbanking.com/v1/errors/validation-error",
                  "title": "Validation Error",
                  "status": 400
                }
              },
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                },
                "example": {
                  "type": "https://api.kangopenbanking.com/v1/errors/validation-error",
                  "title": "Validation Error",
                  "status": 400
                }
              }
            }
          },
          "401": {
            "description": "401 Unauthorized — credentials are missing, expired or invalid.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                },
                "example": {
                  "type": "https://api.kangopenbanking.com/v1/errors/unauthorized",
                  "title": "Unauthorized",
                  "status": 401
                }
              },
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                },
                "example": {
                  "type": "https://api.kangopenbanking.com/v1/errors/unauthorized",
                  "title": "Unauthorized",
                  "status": 401
                }
              }
            }
          },
          "429": {
            "description": "Rate limit exceeded. Retry after the interval in `Retry-After`.",
            "headers": {
              "Retry-After": {
                "schema": {
                  "type": "integer"
                },
                "description": "Seconds to wait before retrying."
              },
              "X-RateLimit-Limit": {
                "schema": {
                  "type": "integer"
                }
              },
              "X-RateLimit-Remaining": {
                "schema": {
                  "type": "integer"
                }
              },
              "X-RateLimit-Reset": {
                "schema": {
                  "type": "integer"
                }
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                },
                "examples": {
                  "rateLimited": {
                    "$ref": "#/components/examples/ErrorRateLimited"
                  }
                }
              }
            }
          },
          "500": {
            "description": "500 Internal Server Error — an unexpected condition prevented completion.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                },
                "example": {
                  "type": "https://api.kangopenbanking.com/v1/errors/internal-error",
                  "title": "Internal Server Error",
                  "status": 500
                }
              },
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                },
                "example": {
                  "type": "https://api.kangopenbanking.com/v1/errors/internal-error",
                  "title": "Internal Server Error",
                  "status": 500
                }
              }
            }
          }
        },
        "parameters": [
          {
            "$ref": "#/components/parameters/Traceparent"
          },
          {
            "$ref": "#/components/parameters/Tracestate"
          },
          {
            "$ref": "#/components/parameters/AcceptLanguage"
          }
        ],
        "description": "Budgeting API. Ask the AI adviser (rate-limited 10/day). This is a state-changing operation. Where the contract declares an `Idempotency-Key` parameter, the header is required and a retried key replays the original result instead of creating a duplicate.",
        "x-codeSamples": [
          {
            "lang": "cURL",
            "label": "cURL",
            "source": "curl -X POST \"https://api.kangopenbanking.com/v1/budgeting/insights/ask\" \\\n  -H \"Authorization: Bearer $KOB_ACCESS_TOKEN\" \\\n  -H \"Content-Type: application/json\" \\\n  -d '{}'"
          },
          {
            "lang": "JavaScript",
            "label": "Node.js",
            "source": "import { KangOpenBanking } from \"@kangopenbanking/sdk\";\n\nconst kob = new KangOpenBanking({ apiKey: process.env.KOB_API_KEY });\nconst res = await kob.request(\"POST\", \"/v1/budgeting/insights/ask\", { /* payload */ });\nconsole.log(res);"
          },
          {
            "lang": "Python",
            "label": "Python",
            "source": "from kangopenbanking import KangOpenBanking\n\nkob = KangOpenBanking(api_key=os.environ[\"KOB_API_KEY\"])\nres = kob.request(\"POST\", \"/v1/budgeting/insights/ask\", json={})\nprint(res)"
          },
          {
            "lang": "PHP",
            "label": "PHP",
            "source": "<?php\n$kob = new KangOpenBanking\\KangOpenBanking(getenv('KOB_API_KEY'));\n$res = $kob->request('POST', '/v1/budgeting/insights/ask', []);\nprint_r($res);"
          }
        ]
      }
    },
    "/v1/budgeting/alerts": {
      "get": {
        "tags": [
          "Budgeting"
        ],
        "operationId": "budgetingListAlerts",
        "summary": "List budget alerts",
        "security": [
          {
            "bearerAuth": []
          }
        ],
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/BudgetAlert"
                },
                "example": {
                  "id": "string",
                  "type": "budget.threshold_reached",
                  "severity": "info",
                  "message": "string",
                  "category_id": "string",
                  "created_at": "2026-01-01T00:00:00Z",
                  "dismissed": true
                }
              }
            },
            "headers": {
              "traceparent": {
                "$ref": "#/components/headers/Traceparent"
              },
              "Content-Language": {
                "$ref": "#/components/headers/Content-Language"
              },
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/XRateLimitLimit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/XRateLimitRemaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/XRateLimitReset"
              },
              "x-fapi-interaction-id": {
                "$ref": "#/components/headers/XFapiInteractionId"
              }
            }
          },
          "400": {
            "description": "400 Bad Request — the request failed validation.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                },
                "example": {
                  "type": "https://api.kangopenbanking.com/v1/errors/validation-error",
                  "title": "Validation Error",
                  "status": 400
                }
              },
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                },
                "example": {
                  "type": "https://api.kangopenbanking.com/v1/errors/validation-error",
                  "title": "Validation Error",
                  "status": 400
                }
              }
            }
          },
          "401": {
            "description": "401 Unauthorized — credentials are missing, expired or invalid.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                },
                "example": {
                  "type": "https://api.kangopenbanking.com/v1/errors/unauthorized",
                  "title": "Unauthorized",
                  "status": 401
                }
              },
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                },
                "example": {
                  "type": "https://api.kangopenbanking.com/v1/errors/unauthorized",
                  "title": "Unauthorized",
                  "status": 401
                }
              }
            }
          },
          "429": {
            "description": "Rate limit exceeded. Retry after the interval in `Retry-After`.",
            "headers": {
              "Retry-After": {
                "schema": {
                  "type": "integer"
                },
                "description": "Seconds to wait before retrying."
              },
              "X-RateLimit-Limit": {
                "schema": {
                  "type": "integer"
                }
              },
              "X-RateLimit-Remaining": {
                "schema": {
                  "type": "integer"
                }
              },
              "X-RateLimit-Reset": {
                "schema": {
                  "type": "integer"
                }
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                },
                "examples": {
                  "rateLimited": {
                    "$ref": "#/components/examples/ErrorRateLimited"
                  }
                }
              }
            }
          },
          "500": {
            "description": "500 Internal Server Error — an unexpected condition prevented completion.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                },
                "example": {
                  "type": "https://api.kangopenbanking.com/v1/errors/internal-error",
                  "title": "Internal Server Error",
                  "status": 500
                }
              },
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                },
                "example": {
                  "type": "https://api.kangopenbanking.com/v1/errors/internal-error",
                  "title": "Internal Server Error",
                  "status": 500
                }
              }
            }
          }
        },
        "parameters": [
          {
            "$ref": "#/components/parameters/Traceparent"
          },
          {
            "$ref": "#/components/parameters/Tracestate"
          },
          {
            "$ref": "#/components/parameters/AcceptLanguage"
          },
          {
            "$ref": "#/components/parameters/LimitParam"
          },
          {
            "$ref": "#/components/parameters/CursorParam"
          }
        ],
        "description": "Budgeting API. List budget alerts. This is a read-only operation: it never mutates state and its result is scoped to the authenticated caller.",
        "x-codeSamples": [
          {
            "lang": "cURL",
            "label": "cURL",
            "source": "curl -X GET \"https://api.kangopenbanking.com/v1/budgeting/alerts\" \\\n  -H \"Authorization: Bearer $KOB_ACCESS_TOKEN\" \\\n  -H \"Content-Type: application/json\""
          },
          {
            "lang": "JavaScript",
            "label": "Node.js",
            "source": "import { KangOpenBanking } from \"@kangopenbanking/sdk\";\n\nconst kob = new KangOpenBanking({ apiKey: process.env.KOB_API_KEY });\nconst res = await kob.request(\"GET\", \"/v1/budgeting/alerts\");\nconsole.log(res);"
          },
          {
            "lang": "Python",
            "label": "Python",
            "source": "from kangopenbanking import KangOpenBanking\n\nkob = KangOpenBanking(api_key=os.environ[\"KOB_API_KEY\"])\nres = kob.request(\"GET\", \"/v1/budgeting/alerts\")\nprint(res)"
          },
          {
            "lang": "PHP",
            "label": "PHP",
            "source": "<?php\n$kob = new KangOpenBanking\\KangOpenBanking(getenv('KOB_API_KEY'));\n$res = $kob->request('GET', '/v1/budgeting/alerts');\nprint_r($res);"
          }
        ]
      }
    },
    "/v1/budgeting/alerts/{alertId}/dismiss": {
      "parameters": [
        {
          "name": "alertId",
          "in": "path",
          "required": true,
          "schema": {
            "type": "string"
          },
          "description": "Alert identifier"
        }
      ],
      "patch": {
        "tags": [
          "Budgeting"
        ],
        "operationId": "budgetingDismissAlert",
        "summary": "Dismiss alert",
        "security": [
          {
            "bearerAuth": []
          }
        ],
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/BudgetAlert"
                },
                "example": {
                  "id": "string",
                  "type": "budget.threshold_reached",
                  "severity": "info",
                  "message": "string",
                  "category_id": "string",
                  "created_at": "2026-01-01T00:00:00Z",
                  "dismissed": true
                }
              }
            },
            "headers": {
              "traceparent": {
                "$ref": "#/components/headers/Traceparent"
              },
              "Content-Language": {
                "$ref": "#/components/headers/Content-Language"
              },
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/XRateLimitLimit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/XRateLimitRemaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/XRateLimitReset"
              },
              "x-fapi-interaction-id": {
                "$ref": "#/components/headers/XFapiInteractionId"
              }
            }
          },
          "400": {
            "description": "400 Bad Request — the request failed validation.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                },
                "example": {
                  "type": "https://api.kangopenbanking.com/v1/errors/validation-error",
                  "title": "Validation Error",
                  "status": 400
                }
              },
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                },
                "example": {
                  "type": "https://api.kangopenbanking.com/v1/errors/validation-error",
                  "title": "Validation Error",
                  "status": 400
                }
              }
            }
          },
          "401": {
            "description": "401 Unauthorized — credentials are missing, expired or invalid.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                },
                "example": {
                  "type": "https://api.kangopenbanking.com/v1/errors/unauthorized",
                  "title": "Unauthorized",
                  "status": 401
                }
              },
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                },
                "example": {
                  "type": "https://api.kangopenbanking.com/v1/errors/unauthorized",
                  "title": "Unauthorized",
                  "status": 401
                }
              }
            }
          },
          "429": {
            "description": "Rate limit exceeded. Retry after the interval in `Retry-After`.",
            "headers": {
              "Retry-After": {
                "schema": {
                  "type": "integer"
                },
                "description": "Seconds to wait before retrying."
              },
              "X-RateLimit-Limit": {
                "schema": {
                  "type": "integer"
                }
              },
              "X-RateLimit-Remaining": {
                "schema": {
                  "type": "integer"
                }
              },
              "X-RateLimit-Reset": {
                "schema": {
                  "type": "integer"
                }
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                },
                "examples": {
                  "rateLimited": {
                    "$ref": "#/components/examples/ErrorRateLimited"
                  }
                }
              }
            }
          },
          "500": {
            "description": "500 Internal Server Error — an unexpected condition prevented completion.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                },
                "example": {
                  "type": "https://api.kangopenbanking.com/v1/errors/internal-error",
                  "title": "Internal Server Error",
                  "status": 500
                }
              },
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                },
                "example": {
                  "type": "https://api.kangopenbanking.com/v1/errors/internal-error",
                  "title": "Internal Server Error",
                  "status": 500
                }
              }
            }
          }
        },
        "parameters": [
          {
            "$ref": "#/components/parameters/Traceparent"
          },
          {
            "$ref": "#/components/parameters/Tracestate"
          },
          {
            "$ref": "#/components/parameters/AcceptLanguage"
          }
        ],
        "description": "Budgeting API. Dismiss alert. This operation applies a partial update: only the fields present in the request body are modified.",
        "x-codeSamples": [
          {
            "lang": "cURL",
            "label": "cURL",
            "source": "curl -X PATCH \"https://api.kangopenbanking.com/v1/budgeting/alerts/{alertId}/dismiss\" \\\n  -H \"Authorization: Bearer $KOB_ACCESS_TOKEN\" \\\n  -H \"Content-Type: application/json\""
          },
          {
            "lang": "JavaScript",
            "label": "Node.js",
            "source": "import { KangOpenBanking } from \"@kangopenbanking/sdk\";\n\nconst kob = new KangOpenBanking({ apiKey: process.env.KOB_API_KEY });\nconst res = await kob.request(\"PATCH\", \"/v1/budgeting/alerts/{alertId}/dismiss\");\nconsole.log(res);"
          },
          {
            "lang": "Python",
            "label": "Python",
            "source": "from kangopenbanking import KangOpenBanking\n\nkob = KangOpenBanking(api_key=os.environ[\"KOB_API_KEY\"])\nres = kob.request(\"PATCH\", \"/v1/budgeting/alerts/{alertId}/dismiss\")\nprint(res)"
          },
          {
            "lang": "PHP",
            "label": "PHP",
            "source": "<?php\n$kob = new KangOpenBanking\\KangOpenBanking(getenv('KOB_API_KEY'));\n$res = $kob->request('PATCH', '/v1/budgeting/alerts/{alertId}/dismiss');\nprint_r($res);"
          }
        ]
      }
    },
    "/v1/budgeting/analytics/monthly": {
      "get": {
        "tags": [
          "Budgeting"
        ],
        "operationId": "budgetingGetMonthlyAnalytics",
        "summary": "Monthly spending analytics",
        "security": [
          {
            "bearerAuth": []
          }
        ],
        "parameters": [
          {
            "name": "months",
            "in": "query",
            "schema": {
              "type": "integer",
              "default": 3,
              "minimum": 1,
              "maximum": 12
            }
          },
          {
            "$ref": "#/components/parameters/Traceparent"
          },
          {
            "$ref": "#/components/parameters/Tracestate"
          },
          {
            "$ref": "#/components/parameters/AcceptLanguage"
          }
        ],
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/MonthlyAnalytics"
                },
                "example": {
                  "months": [
                    {
                      "month": "2026-03",
                      "total_spent": 0,
                      "by_category": {}
                    }
                  ]
                }
              }
            },
            "headers": {
              "traceparent": {
                "$ref": "#/components/headers/Traceparent"
              },
              "Content-Language": {
                "$ref": "#/components/headers/Content-Language"
              },
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/XRateLimitLimit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/XRateLimitRemaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/XRateLimitReset"
              },
              "x-fapi-interaction-id": {
                "$ref": "#/components/headers/XFapiInteractionId"
              }
            }
          },
          "400": {
            "description": "400 Bad Request — the request failed validation.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                },
                "example": {
                  "type": "https://api.kangopenbanking.com/v1/errors/validation-error",
                  "title": "Validation Error",
                  "status": 400
                }
              },
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                },
                "example": {
                  "type": "https://api.kangopenbanking.com/v1/errors/validation-error",
                  "title": "Validation Error",
                  "status": 400
                }
              }
            }
          },
          "401": {
            "description": "401 Unauthorized — credentials are missing, expired or invalid.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                },
                "example": {
                  "type": "https://api.kangopenbanking.com/v1/errors/unauthorized",
                  "title": "Unauthorized",
                  "status": 401
                }
              },
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                },
                "example": {
                  "type": "https://api.kangopenbanking.com/v1/errors/unauthorized",
                  "title": "Unauthorized",
                  "status": 401
                }
              }
            }
          },
          "429": {
            "description": "Rate limit exceeded. Retry after the interval in `Retry-After`.",
            "headers": {
              "Retry-After": {
                "schema": {
                  "type": "integer"
                },
                "description": "Seconds to wait before retrying."
              },
              "X-RateLimit-Limit": {
                "schema": {
                  "type": "integer"
                }
              },
              "X-RateLimit-Remaining": {
                "schema": {
                  "type": "integer"
                }
              },
              "X-RateLimit-Reset": {
                "schema": {
                  "type": "integer"
                }
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                },
                "examples": {
                  "rateLimited": {
                    "$ref": "#/components/examples/ErrorRateLimited"
                  }
                }
              }
            }
          },
          "500": {
            "description": "500 Internal Server Error — an unexpected condition prevented completion.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                },
                "example": {
                  "type": "https://api.kangopenbanking.com/v1/errors/internal-error",
                  "title": "Internal Server Error",
                  "status": 500
                }
              },
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                },
                "example": {
                  "type": "https://api.kangopenbanking.com/v1/errors/internal-error",
                  "title": "Internal Server Error",
                  "status": 500
                }
              }
            }
          }
        },
        "description": "Budgeting API. Monthly spending analytics. This is a read-only operation: it never mutates state and its result is scoped to the authenticated caller.",
        "x-codeSamples": [
          {
            "lang": "cURL",
            "label": "cURL",
            "source": "curl -X GET \"https://api.kangopenbanking.com/v1/budgeting/analytics/monthly\" \\\n  -H \"Authorization: Bearer $KOB_ACCESS_TOKEN\" \\\n  -H \"Content-Type: application/json\""
          },
          {
            "lang": "JavaScript",
            "label": "Node.js",
            "source": "import { KangOpenBanking } from \"@kangopenbanking/sdk\";\n\nconst kob = new KangOpenBanking({ apiKey: process.env.KOB_API_KEY });\nconst res = await kob.request(\"GET\", \"/v1/budgeting/analytics/monthly\");\nconsole.log(res);"
          },
          {
            "lang": "Python",
            "label": "Python",
            "source": "from kangopenbanking import KangOpenBanking\n\nkob = KangOpenBanking(api_key=os.environ[\"KOB_API_KEY\"])\nres = kob.request(\"GET\", \"/v1/budgeting/analytics/monthly\")\nprint(res)"
          },
          {
            "lang": "PHP",
            "label": "PHP",
            "source": "<?php\n$kob = new KangOpenBanking\\KangOpenBanking(getenv('KOB_API_KEY'));\n$res = $kob->request('GET', '/v1/budgeting/analytics/monthly');\nprint_r($res);"
          }
        ]
      }
    },
    "/v1/budgeting/analytics/merchants": {
      "get": {
        "tags": [
          "Budgeting"
        ],
        "operationId": "budgetingGetMerchantAnalytics",
        "summary": "Top merchants analytics",
        "security": [
          {
            "bearerAuth": []
          }
        ],
        "parameters": [
          {
            "name": "period",
            "in": "query",
            "schema": {
              "type": "string",
              "enum": [
                "this_week",
                "this_month",
                "last_month"
              ],
              "default": "this_month"
            }
          },
          {
            "$ref": "#/components/parameters/Traceparent"
          },
          {
            "$ref": "#/components/parameters/Tracestate"
          },
          {
            "$ref": "#/components/parameters/AcceptLanguage"
          },
          {
            "$ref": "#/components/parameters/LimitParam"
          },
          {
            "$ref": "#/components/parameters/CursorParam"
          }
        ],
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/MerchantAnalytics"
                },
                "example": {
                  "period": "string",
                  "merchants": [
                    {
                      "name": "string",
                      "category_id": "string",
                      "total_spent": 0,
                      "transaction_count": 0
                    }
                  ]
                }
              }
            },
            "headers": {
              "traceparent": {
                "$ref": "#/components/headers/Traceparent"
              },
              "Content-Language": {
                "$ref": "#/components/headers/Content-Language"
              },
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/XRateLimitLimit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/XRateLimitRemaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/XRateLimitReset"
              },
              "x-fapi-interaction-id": {
                "$ref": "#/components/headers/XFapiInteractionId"
              }
            }
          },
          "400": {
            "description": "400 Bad Request — the request failed validation.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                },
                "example": {
                  "type": "https://api.kangopenbanking.com/v1/errors/validation-error",
                  "title": "Validation Error",
                  "status": 400
                }
              },
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                },
                "example": {
                  "type": "https://api.kangopenbanking.com/v1/errors/validation-error",
                  "title": "Validation Error",
                  "status": 400
                }
              }
            }
          },
          "401": {
            "description": "401 Unauthorized — credentials are missing, expired or invalid.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                },
                "example": {
                  "type": "https://api.kangopenbanking.com/v1/errors/unauthorized",
                  "title": "Unauthorized",
                  "status": 401
                }
              },
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                },
                "example": {
                  "type": "https://api.kangopenbanking.com/v1/errors/unauthorized",
                  "title": "Unauthorized",
                  "status": 401
                }
              }
            }
          },
          "429": {
            "description": "Rate limit exceeded. Retry after the interval in `Retry-After`.",
            "headers": {
              "Retry-After": {
                "schema": {
                  "type": "integer"
                },
                "description": "Seconds to wait before retrying."
              },
              "X-RateLimit-Limit": {
                "schema": {
                  "type": "integer"
                }
              },
              "X-RateLimit-Remaining": {
                "schema": {
                  "type": "integer"
                }
              },
              "X-RateLimit-Reset": {
                "schema": {
                  "type": "integer"
                }
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                },
                "examples": {
                  "rateLimited": {
                    "$ref": "#/components/examples/ErrorRateLimited"
                  }
                }
              }
            }
          },
          "500": {
            "description": "500 Internal Server Error — an unexpected condition prevented completion.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                },
                "example": {
                  "type": "https://api.kangopenbanking.com/v1/errors/internal-error",
                  "title": "Internal Server Error",
                  "status": 500
                }
              },
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                },
                "example": {
                  "type": "https://api.kangopenbanking.com/v1/errors/internal-error",
                  "title": "Internal Server Error",
                  "status": 500
                }
              }
            }
          }
        },
        "description": "Budgeting API. Top merchants analytics. This is a read-only operation: it never mutates state and its result is scoped to the authenticated caller.",
        "x-codeSamples": [
          {
            "lang": "cURL",
            "label": "cURL",
            "source": "curl -X GET \"https://api.kangopenbanking.com/v1/budgeting/analytics/merchants\" \\\n  -H \"Authorization: Bearer $KOB_ACCESS_TOKEN\" \\\n  -H \"Content-Type: application/json\""
          },
          {
            "lang": "JavaScript",
            "label": "Node.js",
            "source": "import { KangOpenBanking } from \"@kangopenbanking/sdk\";\n\nconst kob = new KangOpenBanking({ apiKey: process.env.KOB_API_KEY });\nconst res = await kob.request(\"GET\", \"/v1/budgeting/analytics/merchants\");\nconsole.log(res);"
          },
          {
            "lang": "Python",
            "label": "Python",
            "source": "from kangopenbanking import KangOpenBanking\n\nkob = KangOpenBanking(api_key=os.environ[\"KOB_API_KEY\"])\nres = kob.request(\"GET\", \"/v1/budgeting/analytics/merchants\")\nprint(res)"
          },
          {
            "lang": "PHP",
            "label": "PHP",
            "source": "<?php\n$kob = new KangOpenBanking\\KangOpenBanking(getenv('KOB_API_KEY'));\n$res = $kob->request('GET', '/v1/budgeting/analytics/merchants');\nprint_r($res);"
          }
        ]
      }
    },
    "/v1/budgeting/analytics/categories/trends": {
      "get": {
        "tags": [
          "Budgeting"
        ],
        "operationId": "budgetingGetCategoryTrends",
        "summary": "Category spending trends",
        "security": [
          {
            "bearerAuth": []
          }
        ],
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/MonthlyAnalytics"
                },
                "example": {
                  "months": [
                    {
                      "month": "2026-03",
                      "total_spent": 0,
                      "by_category": {}
                    }
                  ]
                }
              }
            },
            "headers": {
              "traceparent": {
                "$ref": "#/components/headers/Traceparent"
              },
              "Content-Language": {
                "$ref": "#/components/headers/Content-Language"
              },
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/XRateLimitLimit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/XRateLimitRemaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/XRateLimitReset"
              },
              "x-fapi-interaction-id": {
                "$ref": "#/components/headers/XFapiInteractionId"
              }
            }
          },
          "400": {
            "description": "400 Bad Request — the request failed validation.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                },
                "example": {
                  "type": "https://api.kangopenbanking.com/v1/errors/validation-error",
                  "title": "Validation Error",
                  "status": 400
                }
              },
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                },
                "example": {
                  "type": "https://api.kangopenbanking.com/v1/errors/validation-error",
                  "title": "Validation Error",
                  "status": 400
                }
              }
            }
          },
          "401": {
            "description": "401 Unauthorized — credentials are missing, expired or invalid.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                },
                "example": {
                  "type": "https://api.kangopenbanking.com/v1/errors/unauthorized",
                  "title": "Unauthorized",
                  "status": 401
                }
              },
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                },
                "example": {
                  "type": "https://api.kangopenbanking.com/v1/errors/unauthorized",
                  "title": "Unauthorized",
                  "status": 401
                }
              }
            }
          },
          "429": {
            "description": "Rate limit exceeded. Retry after the interval in `Retry-After`.",
            "headers": {
              "Retry-After": {
                "schema": {
                  "type": "integer"
                },
                "description": "Seconds to wait before retrying."
              },
              "X-RateLimit-Limit": {
                "schema": {
                  "type": "integer"
                }
              },
              "X-RateLimit-Remaining": {
                "schema": {
                  "type": "integer"
                }
              },
              "X-RateLimit-Reset": {
                "schema": {
                  "type": "integer"
                }
              }
            },
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                },
                "examples": {
                  "rateLimited": {
                    "$ref": "#/components/examples/ErrorRateLimited"
                  }
                }
              }
            }
          },
          "500": {
            "description": "500 Internal Server Error — an unexpected condition prevented completion.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                },
                "example": {
                  "type": "https://api.kangopenbanking.com/v1/errors/internal-error",
                  "title": "Internal Server Error",
                  "status": 500
                }
              },
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                },
                "example": {
                  "type": "https://api.kangopenbanking.com/v1/errors/internal-error",
                  "title": "Internal Server Error",
                  "status": 500
                }
              }
            }
          }
        },
        "parameters": [
          {
            "$ref": "#/components/parameters/Traceparent"
          },
          {
            "$ref": "#/components/parameters/Tracestate"
          },
          {
            "$ref": "#/components/parameters/AcceptLanguage"
          },
          {
            "$ref": "#/components/parameters/LimitParam"
          },
          {
            "$ref": "#/components/parameters/CursorParam"
          }
        ],
        "description": "Budgeting API. Category spending trends. This is a read-only operation: it never mutates state and its result is scoped to the authenticated caller.",
        "x-codeSamples": [
          {
            "lang": "cURL",
            "label": "cURL",
            "source": "curl -X GET \"https://api.kangopenbanking.com/v1/budgeting/analytics/categories/trends\" \\\n  -H \"Authorization: Bearer $KOB_ACCESS_TOKEN\" \\\n  -H \"Content-Type: application/json\""
          },
          {
            "lang": "JavaScript",
            "label": "Node.js",
            "source": "import { KangOpenBanking } from \"@kangopenbanking/sdk\";\n\nconst kob = new KangOpenBanking({ apiKey: process.env.KOB_API_KEY });\nconst res = await kob.request(\"GET\", \"/v1/budgeting/analytics/categories/trends\");\nconsole.log(res);"
          },
          {
            "lang": "Python",
            "label": "Python",
            "source": "from kangopenbanking import KangOpenBanking\n\nkob = KangOpenBanking(api_key=os.environ[\"KOB_API_KEY\"])\nres = kob.request(\"GET\", \"/v1/budgeting/analytics/categories/trends\")\nprint(res)"
          },
          {
            "lang": "PHP",
            "label": "PHP",
            "source": "<?php\n$kob = new KangOpenBanking\\KangOpenBanking(getenv('KOB_API_KEY'));\n$res = $kob->request('GET', '/v1/budgeting/analytics/categories/trends');\nprint_r($res);"
          }
        ]
      }
    }
  },
  "externalDocs": {
    "description": "Kang Open Banking Developer Portal — sandbox guides, test credentials, free-forever sandbox console",
    "url": "https://kangopenbanking.com/developer/sandbox"
  },
  "x-api-standards": {
    "rest": "Pure REST: nouns + HTTP verbs. POST /v1/charges, GET /v1/charges/{id}, GET /v1/charges.",
    "base_url": "https://api.kangopenbanking.com/v1",
    "single_canonical_origin": true,
    "internal_routing_exposed": false,
    "environment": "sandbox"
  },
  "x-pagination": {
    "style": "cursor",
    "default_limit": 25,
    "max_limit": 100,
    "parameters": {
      "limit": {
        "in": "query",
        "type": "integer",
        "min": 1,
        "max": 100,
        "default": 25
      },
      "starting_after": {
        "in": "query",
        "type": "string",
        "description": "Cursor: return items after this resource id"
      },
      "ending_before": {
        "in": "query",
        "type": "string",
        "description": "Cursor: return items before this resource id"
      }
    },
    "response_envelope": {
      "object": "list",
      "data": "array",
      "has_more": "boolean",
      "next_cursor": "string|null"
    },
    "legacy": {
      "offset": "Accepted for backwards compatibility on AISP endpoints; cursor pagination preferred for new integrations."
    }
  },
  "x-error-catalog": {
    "envelope": {
      "error": "Machine-readable error type (e.g. invalid_request_error, authentication_error, rate_limit_error)",
      "error_code": "Domain-prefixed code (AUTH_001, PAY_003, LED_002, …)",
      "message": "Human-readable description",
      "error_id": "Trace id — include in support tickets",
      "timestamp": "ISO 8601",
      "details": "Optional field-level validation errors"
    },
    "domains": {
      "AUTH_": "Authentication & OAuth2",
      "PAY_": "Payment Gateway",
      "LED_": "Ledger",
      "PISP_": "Payment Initiation",
      "AISP_": "Account Information",
      "KYC_": "Compliance & Verification",
      "WH_": "Webhooks",
      "RATE_": "Rate limiting"
    },
    "http_status_map": {
      "400": "invalid_request_error",
      "401": "authentication_error",
      "403": "permission_error",
      "404": "not_found_error",
      "409": "idempotency_error",
      "422": "validation_error",
      "429": "rate_limit_error",
      "500": "api_error"
    }
  },
  "x-deprecation-policy": {
    "minimum_notice_days": 180,
    "headers_emitted_on_deprecated_endpoints": [
      "Deprecation",
      "Sunset",
      "Link"
    ],
    "channels": [
      "Changelog",
      "Email to active integrators",
      "Dashboard banner",
      "X-API-Deprecation header"
    ],
    "version_strategy": "Path-based major (/v1, /v2). Minor & patch are backwards compatible. Major version supported ≥ 12 months after successor GA.",
    "backwards_compat_rules": [
      "Never remove a documented field from a response without major version bump",
      "Never tighten a request schema in-place",
      "Never repurpose an enum value",
      "Add new enum values only in additive batches with changelog entry"
    ]
  },
  "x-rate-limits": {
    "tiers": {
      "oauth_token": {
        "limit": 100,
        "window": "1h",
        "per": "client_id"
      },
      "aisp": {
        "limit": 1000,
        "window": "1h",
        "per": "consent_id"
      },
      "pisp": {
        "limit": 500,
        "window": "1h",
        "per": "client_id"
      },
      "gateway": {
        "limit": 1000,
        "window": "1h",
        "per": "merchant_id"
      },
      "sandbox": {
        "limit": 5000,
        "window": "1h",
        "per": "client_id"
      }
    },
    "response_headers": [
      "X-RateLimit-Limit",
      "X-RateLimit-Remaining",
      "X-RateLimit-Reset",
      "Retry-After"
    ],
    "error_status": 429,
    "error_format": "application/problem+json (RFC 7807) — see RateLimitError schema",
    "window_unit": "per_minute",
    "authoritative_source": "spec['x-rate-limits']",
    "note": "All limits in this object are per-minute unless explicitly stated. Markdown documentation mirrors these values."
  },
  "x-sla": {
    "uptime_target": "99.95%",
    "p95_latency_ms": {
      "auth": 250,
      "gateway": 600,
      "aisp": 800,
      "pisp": 1500
    },
    "support_response": {
      "critical": "1h",
      "high": "4h",
      "normal": "1 business day"
    },
    "status_page": "https://kangopenbanking.com/developer/status"
  },
  "x-sandbox": {
    "base_url": "https://api.kangopenbanking.com/v1",
    "key_prefixes": {
      "secret": "sk_test_",
      "publishable": "pk_test_"
    },
    "deterministic": true,
    "magic_amounts": {
      "4000": "declined",
      "4242": "success",
      "5555": "3DS challenge",
      "9999": "delayed success (10s)"
    },
    "test_cards": {
      "4242 4242 4242 4242": "success",
      "4000 0000 0000 0002": "declined",
      "4000 0000 0000 9995": "insufficient funds"
    },
    "test_momo": {
      "237650000000": "MTN MoMo success",
      "237650000001": "MTN MoMo insufficient funds",
      "237690000000": "Orange Money success",
      "237690000001": "Orange Money failed"
    },
    "free": true,
    "guarantee": "Sandbox keys are permanently free (Standing Order P3)."
  },
  "x-sdks": [
    {
      "language": "Node.js / TypeScript",
      "package": "@kangopenbanking/sdk",
      "registry": "npm",
      "version": "1.1.2"
    },
    {
      "language": "Python",
      "package": "kangopenbanking",
      "registry": "PyPI",
      "version": "0.0.1"
    },
    {
      "language": "PHP / Laravel",
      "package": "kangopenbanking/sdk",
      "registry": "Packagist",
      "version": "1.1.2"
    },
    {
      "language": "Postman",
      "url": "https://kangopenbanking.com/developer/guides/postman"
    },
    {
      "language": "Java",
      "name": "com.kangopenbanking:kangopenbanking-sdk-typed",
      "version": "4.28.1",
      "repository": "https://github.com/kangopenbanking/KangOpenBanking-KOB",
      "package_manager": "https://github.com/kangopenbanking/KangOpenBanking-KOB/actions/workflows/sdk-generate.yml",
      "docs": "https://kangopenbanking.com/developer/guides/sdks#java",
      "package": "com.kangopenbanking:kangopenbanking-sdk-typed",
      "registry": "Maven"
    },
    {
      "language": "Go",
      "name": "github.com/kangopenbanking/sdk-go",
      "version": "1.6.1",
      "repository": "https://github.com/kangopenbanking/sdk-go",
      "package_manager": "https://pkg.go.dev/github.com/kangopenbanking/sdk-go",
      "docs": "https://kangopenbanking.com/developer/guides/sdks#go",
      "package": "github.com/kangopenbanking/sdk-go",
      "registry": "pkg.go.dev"
    }
  ],
  "x-webhook-policy": {
    "delivery": "At-least-once",
    "ordering": "Per-resource sequential best-effort; consumers MUST be idempotent on event.id",
    "retry_schedule_seconds": [
      0,
      60,
      300,
      1800,
      7200,
      21600,
      86400
    ],
    "max_attempts": 7,
    "signature_header": "X-Webhook-Signature",
    "event_id_header": "X-Webhook-ID",
    "event_type_header": "X-Webhook-Event",
    "signature_algorithm": "HMAC-SHA256(secret, raw_body) hex",
    "replay_protection": "Reject duplicate X-Webhook-ID within 24h; reject events older than 5 minutes if X-Webhook-Timestamp present",
    "tls": "TLS 1.2+ required on consumer endpoint",
    "signature_header_aliases": [
      "Kang-Signature",
      "X-Kang-Signature",
      "X-KOB-Signature"
    ],
    "event_id_header_aliases": [
      "Kang-Event-ID",
      "Kang-Webhook-ID"
    ],
    "timestamp_header": "X-Webhook-Timestamp",
    "timestamp_header_aliases": [
      "Kang-Timestamp"
    ],
    "header_compatibility_note": "Both X-Webhook-* (legacy) and Kang-* (preferred) header families are emitted on outbound deliveries and accepted on inbound verification. New integrations should prefer the Kang-* family.",
    "x-canonical-headers": {
      "signature": "X-Webhook-Signature",
      "event_id": "X-Webhook-ID",
      "event_type": "X-Webhook-Event",
      "timestamp": "X-Webhook-Timestamp",
      "attempt": "X-Webhook-Attempt"
    },
    "family": "webhook-delivery",
    "x-webhooks-v2-family": {
      "service": "gateway-webhook-deliver-v2",
      "signature_header": "X-Webhook-Signature",
      "signature_format": "t=<unix-seconds>,v1=<hex HMAC-SHA256 of \"<t>.<raw body>\">",
      "timestamp_header": "X-Webhook-Timestamp",
      "event_id_header": "X-Webhook-Event-ID",
      "event_id_body_field": "event_id",
      "delivery_id_header": "X-Webhook-ID",
      "delivery_id_scope": "per-attempt",
      "legacy_signature_header": "X-Webhook-Signature-Legacy",
      "replay_window_seconds": 300
    }
  },
  "x-webhook-events": [
    "charge.succeeded",
    "charge.failed",
    "charge.refunded",
    "payout.created",
    "payout.completed",
    "payout.failed",
    "settlement.created",
    "settlement.completed",
    "consent.authorized",
    "consent.revoked",
    "consent.expired",
    "payment.initiated",
    "payment.completed",
    "payment.failed",
    "dispute.opened",
    "dispute.evidence_required",
    "dispute.resolved",
    "kyc.approved",
    "kyc.rejected",
    "kyb.approved",
    "kyb.rejected",
    "webhook.delivery_failed"
  ],
  "x-state-machine": {
    "name": "charge",
    "description": "Canonical lifecycle for every gateway charge. The /developer/payments/state-machine page is the human-readable mirror.",
    "states": [
      {
        "name": "created",
        "terminal": false
      },
      {
        "name": "processing",
        "terminal": false
      },
      {
        "name": "pending",
        "terminal": false
      },
      {
        "name": "authorized",
        "terminal": false
      },
      {
        "name": "disputed",
        "terminal": false
      },
      {
        "name": "succeeded",
        "terminal": true
      },
      {
        "name": "captured",
        "terminal": true
      },
      {
        "name": "failed",
        "terminal": true
      },
      {
        "name": "cancelled",
        "terminal": true
      },
      {
        "name": "voided",
        "terminal": true
      },
      {
        "name": "expired",
        "terminal": true
      },
      {
        "name": "refunded",
        "terminal": true
      },
      {
        "name": "reversed",
        "terminal": true
      }
    ],
    "transitions": [
      [
        "created",
        "processing"
      ],
      [
        "created",
        "failed"
      ],
      [
        "created",
        "cancelled"
      ],
      [
        "processing",
        "pending"
      ],
      [
        "processing",
        "authorized"
      ],
      [
        "processing",
        "succeeded"
      ],
      [
        "processing",
        "failed"
      ],
      [
        "pending",
        "succeeded"
      ],
      [
        "pending",
        "failed"
      ],
      [
        "pending",
        "expired"
      ],
      [
        "authorized",
        "captured"
      ],
      [
        "authorized",
        "voided"
      ],
      [
        "authorized",
        "expired"
      ],
      [
        "succeeded",
        "refunded"
      ],
      [
        "captured",
        "refunded"
      ],
      [
        "succeeded",
        "reversed"
      ],
      [
        "succeeded",
        "disputed"
      ],
      [
        "disputed",
        "reversed"
      ],
      [
        "disputed",
        "succeeded"
      ]
    ]
  },
  "x-audit-export-bucket": {
    "name": "audit-exports",
    "description": "Immutable, admin-only storage bucket for regulatory audit exports. Write-once via service role; read via short-lived signed URLs.",
    "immutable": true,
    "retention_days": 2557
  },
  "x-observability": {
    "trace_header": "X-Trace-Id",
    "request_header": "X-Request-Id",
    "propagation": "W3C Trace Context (`traceparent`) is accepted; if absent or invalid, a UUID v4 is generated and returned in X-Trace-Id.",
    "slo_targets": {
      "charge_success_rate_24h": ">= 99.5%",
      "webhook_delivery_success_rate_24h": ">= 99.0%",
      "charge_latency_ms": {
        "p50": 200,
        "p95": 800,
        "p99": 1500
      }
    },
    "dashboard": "/admin/slo"
  },
  "x-payment-orchestrator": {
    "flag": "payment_orchestrator_enabled",
    "default": false,
    "guarantees": [
      "Transparent passthrough when flag is OFF — zero behavioural change vs v4.36.0.",
      "Idempotency replay cache TTL extended to 24h via public.idempotency_cache_extended.",
      "Dead-letter queue public.charge_dlq captures charges that exhaust provider 5xx retries (admin replay surface in /admin/orchestrator)."
    ],
    "response_header": "X-Orchestrator",
    "response_header_values": [
      "passthrough",
      "active"
    ]
  },
  "x-data-retention": {
    "table": "public.data_retention_policies",
    "legal_bases": [
      "COBAC AML horizon",
      "GDPR Art. 5(1)(c) & (e)",
      "PSD2 RTS Art. 36"
    ],
    "default_horizons": {
      "kyc_documents": {
        "retention_days": 2555,
        "anonymize_after_days": 2190
      },
      "transactions": {
        "retention_days": 3650
      },
      "consent_events": {
        "retention_days": 2555
      },
      "webhook_deliveries": {
        "retention_days": 365,
        "anonymize_after_days": 180
      }
    },
    "consent_ledger_table": "public.consent_events",
    "regulatory_export_table": "public.compliance_reports"
  },
  "x-risk": {
    "blocklist_table": "public.risk_blocklists",
    "blocklist_identifier_types": [
      "msisdn",
      "email",
      "iban",
      "device_id",
      "ip"
    ],
    "blocklist_severities": [
      "low",
      "medium",
      "high",
      "critical"
    ],
    "baseline_table": "public.merchant_risk_baselines",
    "baseline_window_days": 30,
    "baseline_metrics": [
      "charge_count",
      "avg_amount",
      "p95_amount",
      "max_amount",
      "decline_rate",
      "distinct_customers"
    ],
    "fail_closed": {
      "flag": "risk_fail_closed_enabled",
      "threshold_config": "risk_fail_closed_threshold_xaf",
      "threshold_default_xaf": 1000000,
      "behavior_when_enabled": "POST /v1/gateway/risk/score returns action=block (not fail-open) on internal error if amount_xaf > threshold."
    },
    "standards": [
      "PSD2 RTS Art. 18 (Transaction Risk Analysis)",
      "FATF Rec. 10 (CDD)",
      "COBAC AML"
    ]
  },
  "x-scalability": {
    "kv_cache_table": "public.kv_cache",
    "kv_cache_uses": [
      "OIDC discovery doc cache (TTL 600s)",
      "JWKS cache (TTL 3600s)",
      "Rate-limit counter buckets (TTL 60s)"
    ],
    "typed_sdk_matrix": {
      "hand_tuned": [
        "packages/sdk-node",
        "packages/sdk-python",
        "packages/sdk-php",
        "packages/sdk-go"
      ],
      "auto_generated": [
        "sdks/generated/typescript",
        "sdks/generated/python",
        "sdks/generated/go",
        "sdks/generated/java"
      ]
    },
    "load_harness": {
      "runner": "k6",
      "location": "e2e/load/",
      "scenarios": [
        "charge-burst.js",
        "webhook-flood.js",
        "aisp-read-storm.js"
      ],
      "slo_targets": {
        "charge_p95_ms": 1500,
        "webhook_p95_ms": 800,
        "aisp_p95_ms": 600,
        "error_rate_max": 0.005
      }
    },
    "standards": [
      "Stripe load-test methodology",
      "Adyen capacity-planning guide",
      "KOB SO-5 Dead-Code Rule"
    ]
  },
  "x-maturity-legend": {
    "ga": "Generally available. Stable contract; suitable for production integration subject to licensing status noted in info.description.",
    "preview": "Sandbox/pilot. Implemented in sandbox for integration testing; not yet authorised for production traffic. May change before GA.",
    "experimental": "Experimental. Reference shape only; implementation is partial and may change without a major version bump until promoted."
  },
  "x-pci-scope-legend": {
    "none": "Operation does not transmit, process, or store cardholder data (PAN, CVV, full track, or sensitive auth data). Out of PCI DSS scope.",
    "masked_pan_only": "Operation returns or accepts a truncated PAN (first 6 / last 4 maximum per PCI DSS req 3.3) and no CVV. Out of PCI DSS scope for stored data; safe for application logs and UI.",
    "cardholder_data": "Operation transmits or returns cardholder data (full PAN, expiry, cardholder name) on the wire. In PCI DSS scope. KOB does not store the PAN at rest in its primary datastore; full PAN/CVV is held only inside the Kora-managed card vault (SAQ-D delegated to Kora). All calls require step-up authentication, are rate-limited per principal, and are audit-logged.",
    "sensitive_auth_data": "Operation handles sensitive authentication data (CVV, full track, PIN block). MUST NOT be stored after authorization per PCI DSS req 3.2. KOB only forwards the value to the issuer/processor and discards it."
  },
  "x-kob-standards-posture": {
    "fapi_1_0_advanced": "compatibility-baseline",
    "fapi_2_0_security_profile": "forward-target-not-certified",
    "fapi_2_0_message_signing": "not-implemented",
    "jarm": "not-implemented",
    "dpop": "not-implemented",
    "openid_certification": "not-obtained",
    "par": "implemented",
    "pkce_s256": "implemented",
    "oidc_discovery": "implemented",
    "jwks": "implemented",
    "mtls_client_auth": "documented-trust-bundle-pending"
  }
}
