{
    "openapi": "3.0.3",
    "info": {
        "title": "Zung Banking API",
        "version": "v1",
        "description": "Generated from mfidoc.com. Planned endpoints are excluded.",
        "contact": {
            "email": "dev@mfidoc.com"
        }
    },
    "servers": [
        {
            "url": "https://app.zung.ai/connector/api/banking"
        }
    ],
    "components": {
        "securitySchemes": {
            "bearer": {
                "type": "http",
                "scheme": "bearer"
            }
        }
    },
    "security": [
        {
            "bearer": []
        }
    ],
    "paths": {
        "/me": {
            "get": {
                "tags": [
                    "Authentication"
                ],
                "summary": "Get signed-in staff user",
                "description": "Returns the staff user that owns the token, their institution, branch access and permissions.\n\nDocs: https://mfidoc.com/doc/banking-me",
                "operationId": "bankingMe",
                "responses": {
                    "200": {
                        "description": "OK"
                    },
                    "401": {
                        "description": "Missing or expired token"
                    },
                    "403": {
                        "description": "Not permitted"
                    },
                    "422": {
                        "description": "Validation failed"
                    }
                }
            }
        },
        "/account-status": {
            "get": {
                "tags": [
                    "Authentication"
                ],
                "summary": "Get subscription status",
                "description": "Whether the institution's subscription is active, and which modules it includes.\n\nDocs: https://mfidoc.com/doc/banking-account-status",
                "operationId": "bankingAccountStatus",
                "responses": {
                    "200": {
                        "description": "OK"
                    },
                    "401": {
                        "description": "Missing or expired token"
                    },
                    "403": {
                        "description": "Not permitted"
                    },
                    "422": {
                        "description": "Validation failed"
                    }
                }
            }
        },
        "/2fa/send": {
            "post": {
                "tags": [
                    "Authentication"
                ],
                "summary": "Send a 2FA code",
                "description": "Sends a one-time code to the staff user. Limited to 5 requests a minute.\n\nDocs: https://mfidoc.com/doc/banking-2fa-send",
                "operationId": "banking2faSend",
                "responses": {
                    "200": {
                        "description": "OK"
                    },
                    "401": {
                        "description": "Missing or expired token"
                    },
                    "403": {
                        "description": "Not permitted"
                    },
                    "422": {
                        "description": "Validation failed"
                    }
                }
            }
        },
        "/2fa/verify": {
            "post": {
                "tags": [
                    "Authentication"
                ],
                "summary": "Verify a 2FA code",
                "description": "Completes two-factor sign-in. Limited to 5 attempts a minute.\n\nDocs: https://mfidoc.com/doc/banking-2fa-verify",
                "operationId": "banking2faVerify",
                "responses": {
                    "200": {
                        "description": "OK"
                    },
                    "401": {
                        "description": "Missing or expired token"
                    },
                    "403": {
                        "description": "Not permitted"
                    },
                    "422": {
                        "description": "Validation failed"
                    }
                },
                "requestBody": {
                    "required": true,
                    "content": {
                        "application/json": {
                            "schema": {
                                "type": "object",
                                "properties": {
                                    "code": {
                                        "type": "string",
                                        "description": "The one-time code, max 20 characters"
                                    }
                                },
                                "required": [
                                    "code"
                                ]
                            }
                        },
                        "application/x-www-form-urlencoded": {
                            "schema": {
                                "type": "object",
                                "properties": {
                                    "code": {
                                        "type": "string",
                                        "description": "The one-time code, max 20 characters"
                                    }
                                },
                                "required": [
                                    "code"
                                ]
                            }
                        }
                    }
                }
            }
        },
        "/logout": {
            "post": {
                "tags": [
                    "Authentication"
                ],
                "summary": "Revoke token",
                "description": "Signs the staff user out and revokes the bearer token.\n\nDocs: https://mfidoc.com/doc/banking-logout",
                "operationId": "bankingLogout",
                "responses": {
                    "200": {
                        "description": "OK"
                    },
                    "401": {
                        "description": "Missing or expired token"
                    },
                    "403": {
                        "description": "Not permitted"
                    },
                    "422": {
                        "description": "Validation failed"
                    }
                }
            }
        },
        "/members": {
            "get": {
                "tags": [
                    "Members"
                ],
                "summary": "List members",
                "description": "Paginated list of members visible to the signed-in staff user (respects branch permissions).\n\nDocs: https://mfidoc.com/doc/list-members",
                "operationId": "listMembers",
                "responses": {
                    "200": {
                        "description": "OK"
                    },
                    "401": {
                        "description": "Missing or expired token"
                    },
                    "403": {
                        "description": "Not permitted"
                    },
                    "422": {
                        "description": "Validation failed"
                    }
                },
                "parameters": [
                    {
                        "name": "q",
                        "in": "query",
                        "required": false,
                        "description": "Search by name, member number or mobile number",
                        "schema": {
                            "type": "string"
                        }
                    },
                    {
                        "name": "status",
                        "in": "query",
                        "required": false,
                        "description": "Filter by member status, e.g. active",
                        "schema": {
                            "type": "string"
                        }
                    },
                    {
                        "name": "per_page",
                        "in": "query",
                        "required": false,
                        "description": "Results per page, 1–100 (default 25)",
                        "schema": {
                            "type": "integer"
                        }
                    },
                    {
                        "name": "page",
                        "in": "query",
                        "required": false,
                        "description": "Page number",
                        "schema": {
                            "type": "integer"
                        }
                    }
                ]
            },
            "post": {
                "tags": [
                    "Members"
                ],
                "summary": "Create member",
                "description": "Registers an individual or business member at a branch.\n\nDocs: https://mfidoc.com/doc/create-member",
                "operationId": "createMember",
                "responses": {
                    "200": {
                        "description": "OK"
                    },
                    "401": {
                        "description": "Missing or expired token"
                    },
                    "403": {
                        "description": "Not permitted"
                    },
                    "422": {
                        "description": "Validation failed"
                    }
                },
                "requestBody": {
                    "required": true,
                    "content": {
                        "application/json": {
                            "schema": {
                                "type": "object",
                                "properties": {
                                    "entity": {
                                        "type": "string",
                                        "description": "individual (default) or business"
                                    },
                                    "first_name": {
                                        "type": "string",
                                        "description": "Required for individuals"
                                    },
                                    "supplier_business_name": {
                                        "type": "string",
                                        "description": "Required when entity is business"
                                    },
                                    "mobile": {
                                        "type": "string",
                                        "description": "Mobile number, used for M-Pesa and SMS"
                                    },
                                    "location_id": {
                                        "type": "integer",
                                        "description": "Branch id, from GET /members/form-options"
                                    },
                                    "email": {
                                        "type": "string",
                                        "description": "Email address"
                                    },
                                    "dob": {
                                        "type": "string",
                                        "format": "date",
                                        "description": "Date of birth"
                                    },
                                    "customer_group_id": {
                                        "type": "integer",
                                        "description": "Group / solidarity group"
                                    },
                                    "loan_officer_id": {
                                        "type": "integer",
                                        "description": "Assigned loan officer"
                                    }
                                },
                                "required": [
                                    "first_name",
                                    "mobile",
                                    "location_id"
                                ]
                            }
                        },
                        "application/x-www-form-urlencoded": {
                            "schema": {
                                "type": "object",
                                "properties": {
                                    "entity": {
                                        "type": "string",
                                        "description": "individual (default) or business"
                                    },
                                    "first_name": {
                                        "type": "string",
                                        "description": "Required for individuals"
                                    },
                                    "supplier_business_name": {
                                        "type": "string",
                                        "description": "Required when entity is business"
                                    },
                                    "mobile": {
                                        "type": "string",
                                        "description": "Mobile number, used for M-Pesa and SMS"
                                    },
                                    "location_id": {
                                        "type": "integer",
                                        "description": "Branch id, from GET /members/form-options"
                                    },
                                    "email": {
                                        "type": "string",
                                        "description": "Email address"
                                    },
                                    "dob": {
                                        "type": "string",
                                        "format": "date",
                                        "description": "Date of birth"
                                    },
                                    "customer_group_id": {
                                        "type": "integer",
                                        "description": "Group / solidarity group"
                                    },
                                    "loan_officer_id": {
                                        "type": "integer",
                                        "description": "Assigned loan officer"
                                    }
                                },
                                "required": [
                                    "first_name",
                                    "mobile",
                                    "location_id"
                                ]
                            }
                        }
                    }
                }
            }
        },
        "/members/{id}": {
            "get": {
                "tags": [
                    "Members"
                ],
                "summary": "Get member profile",
                "description": "Full member profile with accounts, KYC, next of kin and documents.\n\nDocs: https://mfidoc.com/doc/get-member",
                "operationId": "getMember",
                "responses": {
                    "200": {
                        "description": "OK"
                    },
                    "401": {
                        "description": "Missing or expired token"
                    },
                    "403": {
                        "description": "Not permitted"
                    },
                    "422": {
                        "description": "Validation failed"
                    }
                },
                "parameters": [
                    {
                        "name": "id",
                        "in": "path",
                        "required": true,
                        "description": "Member id",
                        "schema": {
                            "type": "integer"
                        }
                    }
                ]
            },
            "put": {
                "tags": [
                    "Members"
                ],
                "summary": "Update member",
                "description": "Updates a member. Takes the same fields as Create member.\n\nDocs: https://mfidoc.com/doc/update-member",
                "operationId": "updateMember",
                "responses": {
                    "200": {
                        "description": "OK"
                    },
                    "401": {
                        "description": "Missing or expired token"
                    },
                    "403": {
                        "description": "Not permitted"
                    },
                    "422": {
                        "description": "Validation failed"
                    }
                },
                "parameters": [
                    {
                        "name": "id",
                        "in": "path",
                        "required": true,
                        "description": "Member id",
                        "schema": {
                            "type": "integer"
                        }
                    }
                ]
            }
        },
        "/members/stats": {
            "get": {
                "tags": [
                    "Members"
                ],
                "summary": "Member statistics",
                "description": "Counts of members by status for the signed-in user's branches.\n\nDocs: https://mfidoc.com/doc/member-stats",
                "operationId": "memberStats",
                "responses": {
                    "200": {
                        "description": "OK"
                    },
                    "401": {
                        "description": "Missing or expired token"
                    },
                    "403": {
                        "description": "Not permitted"
                    },
                    "422": {
                        "description": "Validation failed"
                    }
                }
            }
        },
        "/members/form-options": {
            "get": {
                "tags": [
                    "Members"
                ],
                "summary": "Member form options",
                "description": "Branches, groups, loan officers, genders and marital statuses to build a member form.\n\nDocs: https://mfidoc.com/doc/member-form-options",
                "operationId": "memberFormOptions",
                "responses": {
                    "200": {
                        "description": "OK"
                    },
                    "401": {
                        "description": "Missing or expired token"
                    },
                    "403": {
                        "description": "Not permitted"
                    },
                    "422": {
                        "description": "Validation failed"
                    }
                }
            }
        },
        "/members/status": {
            "post": {
                "tags": [
                    "Members"
                ],
                "summary": "Change member status",
                "description": "Activates, deactivates or blacklists members in bulk.\n\nDocs: https://mfidoc.com/doc/member-status",
                "operationId": "memberStatus",
                "responses": {
                    "200": {
                        "description": "OK"
                    },
                    "401": {
                        "description": "Missing or expired token"
                    },
                    "403": {
                        "description": "Not permitted"
                    },
                    "422": {
                        "description": "Validation failed"
                    }
                }
            }
        },
        "/members/{id}/kyc": {
            "post": {
                "tags": [
                    "KYC & Member Records"
                ],
                "summary": "Upload KYC document",
                "description": "Attaches an identity document (national ID, passport, etc.) to a member.\n\nDocs: https://mfidoc.com/doc/add-kyc",
                "operationId": "addKyc",
                "responses": {
                    "200": {
                        "description": "OK"
                    },
                    "401": {
                        "description": "Missing or expired token"
                    },
                    "403": {
                        "description": "Not permitted"
                    },
                    "422": {
                        "description": "Validation failed"
                    }
                },
                "parameters": [
                    {
                        "name": "id",
                        "in": "path",
                        "required": true,
                        "description": "Member id",
                        "schema": {
                            "type": "integer"
                        }
                    }
                ]
            }
        },
        "/kyc/{kyc}/status": {
            "put": {
                "tags": [
                    "KYC & Member Records"
                ],
                "summary": "Review KYC document",
                "description": "Approves or rejects a member's KYC document.\n\nDocs: https://mfidoc.com/doc/kyc-status",
                "operationId": "kycStatus",
                "responses": {
                    "200": {
                        "description": "OK"
                    },
                    "401": {
                        "description": "Missing or expired token"
                    },
                    "403": {
                        "description": "Not permitted"
                    },
                    "422": {
                        "description": "Validation failed"
                    }
                },
                "parameters": [
                    {
                        "name": "kyc",
                        "in": "path",
                        "required": true,
                        "description": "KYC record id",
                        "schema": {
                            "type": "integer"
                        }
                    }
                ],
                "requestBody": {
                    "required": true,
                    "content": {
                        "application/json": {
                            "schema": {
                                "type": "object",
                                "properties": {
                                    "status": {
                                        "type": "string",
                                        "description": "New KYC status"
                                    }
                                },
                                "required": [
                                    "status"
                                ]
                            }
                        },
                        "application/x-www-form-urlencoded": {
                            "schema": {
                                "type": "object",
                                "properties": {
                                    "status": {
                                        "type": "string",
                                        "description": "New KYC status"
                                    }
                                },
                                "required": [
                                    "status"
                                ]
                            }
                        }
                    }
                }
            }
        },
        "/members/{id}/next-of-kin": {
            "post": {
                "tags": [
                    "KYC & Member Records"
                ],
                "summary": "Add next of kin",
                "description": "Records a member's next of kin.\n\nDocs: https://mfidoc.com/doc/add-next-of-kin",
                "operationId": "addNextOfKin",
                "responses": {
                    "200": {
                        "description": "OK"
                    },
                    "401": {
                        "description": "Missing or expired token"
                    },
                    "403": {
                        "description": "Not permitted"
                    },
                    "422": {
                        "description": "Validation failed"
                    }
                },
                "parameters": [
                    {
                        "name": "id",
                        "in": "path",
                        "required": true,
                        "description": "Member id",
                        "schema": {
                            "type": "integer"
                        }
                    }
                ]
            }
        },
        "/members/{id}/work-details": {
            "post": {
                "tags": [
                    "KYC & Member Records"
                ],
                "summary": "Add employment details",
                "description": "Employer, income and work status, used in loan appraisal.\n\nDocs: https://mfidoc.com/doc/add-work-details",
                "operationId": "addWorkDetails",
                "responses": {
                    "200": {
                        "description": "OK"
                    },
                    "401": {
                        "description": "Missing or expired token"
                    },
                    "403": {
                        "description": "Not permitted"
                    },
                    "422": {
                        "description": "Validation failed"
                    }
                },
                "parameters": [
                    {
                        "name": "id",
                        "in": "path",
                        "required": true,
                        "description": "Member id",
                        "schema": {
                            "type": "integer"
                        }
                    }
                ]
            }
        },
        "/members/{id}/bank-details": {
            "post": {
                "tags": [
                    "KYC & Member Records"
                ],
                "summary": "Add bank details",
                "description": "A member's external bank account for disbursements.\n\nDocs: https://mfidoc.com/doc/add-bank-details",
                "operationId": "addBankDetails",
                "responses": {
                    "200": {
                        "description": "OK"
                    },
                    "401": {
                        "description": "Missing or expired token"
                    },
                    "403": {
                        "description": "Not permitted"
                    },
                    "422": {
                        "description": "Validation failed"
                    }
                },
                "parameters": [
                    {
                        "name": "id",
                        "in": "path",
                        "required": true,
                        "description": "Member id",
                        "schema": {
                            "type": "integer"
                        }
                    }
                ]
            }
        },
        "/members/{id}/login": {
            "post": {
                "tags": [
                    "KYC & Member Records"
                ],
                "summary": "Create member portal login",
                "description": "Gives a member a login for the mobile app and member portal.\n\nDocs: https://mfidoc.com/doc/add-member-login",
                "operationId": "addMemberLogin",
                "responses": {
                    "200": {
                        "description": "OK"
                    },
                    "401": {
                        "description": "Missing or expired token"
                    },
                    "403": {
                        "description": "Not permitted"
                    },
                    "422": {
                        "description": "Validation failed"
                    }
                },
                "parameters": [
                    {
                        "name": "id",
                        "in": "path",
                        "required": true,
                        "description": "Member id",
                        "schema": {
                            "type": "integer"
                        }
                    }
                ],
                "requestBody": {
                    "required": true,
                    "content": {
                        "application/json": {
                            "schema": {
                                "type": "object",
                                "properties": {
                                    "email": {
                                        "type": "string",
                                        "description": "Login email"
                                    },
                                    "username": {
                                        "type": "string",
                                        "description": "Username"
                                    },
                                    "password": {
                                        "type": "string",
                                        "description": "At least 6 characters"
                                    }
                                },
                                "required": [
                                    "email",
                                    "username"
                                ]
                            }
                        },
                        "application/x-www-form-urlencoded": {
                            "schema": {
                                "type": "object",
                                "properties": {
                                    "email": {
                                        "type": "string",
                                        "description": "Login email"
                                    },
                                    "username": {
                                        "type": "string",
                                        "description": "Username"
                                    },
                                    "password": {
                                        "type": "string",
                                        "description": "At least 6 characters"
                                    }
                                },
                                "required": [
                                    "email",
                                    "username"
                                ]
                            }
                        }
                    }
                }
            }
        },
        "/members/{id}/documents": {
            "post": {
                "tags": [
                    "KYC & Member Records"
                ],
                "summary": "Upload member document",
                "description": "Stores any supporting document against a member.\n\nDocs: https://mfidoc.com/doc/add-member-document",
                "operationId": "addMemberDocument",
                "responses": {
                    "200": {
                        "description": "OK"
                    },
                    "401": {
                        "description": "Missing or expired token"
                    },
                    "403": {
                        "description": "Not permitted"
                    },
                    "422": {
                        "description": "Validation failed"
                    }
                },
                "parameters": [
                    {
                        "name": "id",
                        "in": "path",
                        "required": true,
                        "description": "Member id",
                        "schema": {
                            "type": "integer"
                        }
                    }
                ]
            }
        },
        "/savings": {
            "get": {
                "tags": [
                    "Savings"
                ],
                "summary": "List savings accounts",
                "description": "Paginated savings accounts with balances.\n\nDocs: https://mfidoc.com/doc/list-savings",
                "operationId": "listSavings",
                "responses": {
                    "200": {
                        "description": "OK"
                    },
                    "401": {
                        "description": "Missing or expired token"
                    },
                    "403": {
                        "description": "Not permitted"
                    },
                    "422": {
                        "description": "Validation failed"
                    }
                },
                "parameters": [
                    {
                        "name": "per_page",
                        "in": "query",
                        "required": false,
                        "description": "1–100 (default 25)",
                        "schema": {
                            "type": "integer"
                        }
                    }
                ]
            }
        },
        "/savings/{id}": {
            "get": {
                "tags": [
                    "Savings"
                ],
                "summary": "Get savings account",
                "description": "One savings account with its product, balance and recent transactions.\n\nDocs: https://mfidoc.com/doc/get-savings",
                "operationId": "getSavings",
                "responses": {
                    "200": {
                        "description": "OK"
                    },
                    "401": {
                        "description": "Missing or expired token"
                    },
                    "403": {
                        "description": "Not permitted"
                    },
                    "422": {
                        "description": "Validation failed"
                    }
                },
                "parameters": [
                    {
                        "name": "id",
                        "in": "path",
                        "required": true,
                        "description": "Savings account id",
                        "schema": {
                            "type": "integer"
                        }
                    }
                ]
            }
        },
        "/savings/apply": {
            "post": {
                "tags": [
                    "Savings"
                ],
                "summary": "Open savings account",
                "description": "Opens a savings account for a member.\n\nDocs: https://mfidoc.com/doc/apply-savings",
                "operationId": "applySavings",
                "responses": {
                    "200": {
                        "description": "OK"
                    },
                    "401": {
                        "description": "Missing or expired token"
                    },
                    "403": {
                        "description": "Not permitted"
                    },
                    "422": {
                        "description": "Validation failed"
                    }
                },
                "requestBody": {
                    "required": true,
                    "content": {
                        "application/json": {
                            "schema": {
                                "type": "object",
                                "properties": {
                                    "contact_id": {
                                        "type": "integer",
                                        "description": "Member id"
                                    }
                                },
                                "required": [
                                    "contact_id"
                                ]
                            }
                        },
                        "application/x-www-form-urlencoded": {
                            "schema": {
                                "type": "object",
                                "properties": {
                                    "contact_id": {
                                        "type": "integer",
                                        "description": "Member id"
                                    }
                                },
                                "required": [
                                    "contact_id"
                                ]
                            }
                        }
                    }
                }
            }
        },
        "/savings/{id}/deposit": {
            "post": {
                "tags": [
                    "Savings"
                ],
                "summary": "Record a deposit",
                "description": "Posts a deposit to a savings account. Send client_ref to make retries safe.\n\nDocs: https://mfidoc.com/doc/savings-deposit",
                "operationId": "savingsDeposit",
                "responses": {
                    "200": {
                        "description": "OK"
                    },
                    "401": {
                        "description": "Missing or expired token"
                    },
                    "403": {
                        "description": "Not permitted"
                    },
                    "422": {
                        "description": "Validation failed"
                    }
                },
                "parameters": [
                    {
                        "name": "id",
                        "in": "path",
                        "required": true,
                        "description": "Savings account id",
                        "schema": {
                            "type": "integer"
                        }
                    }
                ],
                "requestBody": {
                    "required": true,
                    "content": {
                        "application/json": {
                            "schema": {
                                "type": "object",
                                "properties": {
                                    "amount": {
                                        "type": "number",
                                        "description": "Amount in the institution's base currency"
                                    },
                                    "date": {
                                        "type": "string",
                                        "format": "date",
                                        "description": "Value date of the transaction (YYYY-MM-DD)"
                                    },
                                    "payment_type_id": {
                                        "type": "integer",
                                        "description": "Payment channel, from GET /payment-types (cash, M-Pesa, bank...)"
                                    },
                                    "receipt": {
                                        "type": "string",
                                        "description": "Receipt or M-Pesa confirmation code"
                                    },
                                    "description": {
                                        "type": "string",
                                        "description": "Narration shown on the member's statement"
                                    },
                                    "client_ref": {
                                        "type": "string",
                                        "description": "Your unique reference (max 64). Retrying with the same value never posts twice"
                                    }
                                },
                                "required": [
                                    "amount",
                                    "date",
                                    "payment_type_id"
                                ]
                            }
                        },
                        "application/x-www-form-urlencoded": {
                            "schema": {
                                "type": "object",
                                "properties": {
                                    "amount": {
                                        "type": "number",
                                        "description": "Amount in the institution's base currency"
                                    },
                                    "date": {
                                        "type": "string",
                                        "format": "date",
                                        "description": "Value date of the transaction (YYYY-MM-DD)"
                                    },
                                    "payment_type_id": {
                                        "type": "integer",
                                        "description": "Payment channel, from GET /payment-types (cash, M-Pesa, bank...)"
                                    },
                                    "receipt": {
                                        "type": "string",
                                        "description": "Receipt or M-Pesa confirmation code"
                                    },
                                    "description": {
                                        "type": "string",
                                        "description": "Narration shown on the member's statement"
                                    },
                                    "client_ref": {
                                        "type": "string",
                                        "description": "Your unique reference (max 64). Retrying with the same value never posts twice"
                                    }
                                },
                                "required": [
                                    "amount",
                                    "date",
                                    "payment_type_id"
                                ]
                            }
                        }
                    }
                }
            }
        },
        "/savings/{id}/withdraw": {
            "post": {
                "tags": [
                    "Savings"
                ],
                "summary": "Record a withdrawal",
                "description": "Posts a withdrawal. Product rules (minimum balance, notice) are enforced.\n\nDocs: https://mfidoc.com/doc/savings-withdraw",
                "operationId": "savingsWithdraw",
                "responses": {
                    "200": {
                        "description": "OK"
                    },
                    "401": {
                        "description": "Missing or expired token"
                    },
                    "403": {
                        "description": "Not permitted"
                    },
                    "422": {
                        "description": "Validation failed"
                    }
                },
                "parameters": [
                    {
                        "name": "id",
                        "in": "path",
                        "required": true,
                        "description": "Savings account id",
                        "schema": {
                            "type": "integer"
                        }
                    }
                ],
                "requestBody": {
                    "required": true,
                    "content": {
                        "application/json": {
                            "schema": {
                                "type": "object",
                                "properties": {
                                    "amount": {
                                        "type": "number",
                                        "description": "Amount in the institution's base currency"
                                    },
                                    "date": {
                                        "type": "string",
                                        "format": "date",
                                        "description": "Value date of the transaction (YYYY-MM-DD)"
                                    },
                                    "payment_type_id": {
                                        "type": "integer",
                                        "description": "Payment channel, from GET /payment-types (cash, M-Pesa, bank...)"
                                    },
                                    "receipt": {
                                        "type": "string",
                                        "description": "Receipt or M-Pesa confirmation code"
                                    },
                                    "description": {
                                        "type": "string",
                                        "description": "Narration shown on the member's statement"
                                    },
                                    "client_ref": {
                                        "type": "string",
                                        "description": "Your unique reference (max 64). Retrying with the same value never posts twice"
                                    }
                                },
                                "required": [
                                    "amount",
                                    "date",
                                    "payment_type_id"
                                ]
                            }
                        },
                        "application/x-www-form-urlencoded": {
                            "schema": {
                                "type": "object",
                                "properties": {
                                    "amount": {
                                        "type": "number",
                                        "description": "Amount in the institution's base currency"
                                    },
                                    "date": {
                                        "type": "string",
                                        "format": "date",
                                        "description": "Value date of the transaction (YYYY-MM-DD)"
                                    },
                                    "payment_type_id": {
                                        "type": "integer",
                                        "description": "Payment channel, from GET /payment-types (cash, M-Pesa, bank...)"
                                    },
                                    "receipt": {
                                        "type": "string",
                                        "description": "Receipt or M-Pesa confirmation code"
                                    },
                                    "description": {
                                        "type": "string",
                                        "description": "Narration shown on the member's statement"
                                    },
                                    "client_ref": {
                                        "type": "string",
                                        "description": "Your unique reference (max 64). Retrying with the same value never posts twice"
                                    }
                                },
                                "required": [
                                    "amount",
                                    "date",
                                    "payment_type_id"
                                ]
                            }
                        }
                    }
                }
            }
        },
        "/savings/{id}/{action}": {
            "post": {
                "tags": [
                    "Savings"
                ],
                "summary": "Approve, activate or close account",
                "description": "Moves a savings account through its lifecycle.\n\nDocs: https://mfidoc.com/doc/savings-action",
                "operationId": "savingsAction",
                "responses": {
                    "200": {
                        "description": "OK"
                    },
                    "401": {
                        "description": "Missing or expired token"
                    },
                    "403": {
                        "description": "Not permitted"
                    },
                    "422": {
                        "description": "Validation failed"
                    }
                },
                "parameters": [
                    {
                        "name": "id",
                        "in": "path",
                        "required": true,
                        "description": "Savings account id",
                        "schema": {
                            "type": "integer"
                        }
                    },
                    {
                        "name": "action",
                        "in": "path",
                        "required": true,
                        "description": "Lifecycle action, e.g. approve, activate, close",
                        "schema": {
                            "type": "string"
                        }
                    }
                ]
            }
        },
        "/loans": {
            "get": {
                "tags": [
                    "Loans"
                ],
                "summary": "List loans",
                "description": "Paginated loans with status, principal and outstanding balance.\n\nDocs: https://mfidoc.com/doc/list-loans",
                "operationId": "listLoans",
                "responses": {
                    "200": {
                        "description": "OK"
                    },
                    "401": {
                        "description": "Missing or expired token"
                    },
                    "403": {
                        "description": "Not permitted"
                    },
                    "422": {
                        "description": "Validation failed"
                    }
                },
                "parameters": [
                    {
                        "name": "per_page",
                        "in": "query",
                        "required": false,
                        "description": "1–100 (default 25)",
                        "schema": {
                            "type": "integer"
                        }
                    }
                ]
            }
        },
        "/loans/{id}": {
            "get": {
                "tags": [
                    "Loans"
                ],
                "summary": "Get loan",
                "description": "One loan with schedule, charges, guarantors and transactions.\n\nDocs: https://mfidoc.com/doc/get-loan",
                "operationId": "getLoan",
                "responses": {
                    "200": {
                        "description": "OK"
                    },
                    "401": {
                        "description": "Missing or expired token"
                    },
                    "403": {
                        "description": "Not permitted"
                    },
                    "422": {
                        "description": "Validation failed"
                    }
                },
                "parameters": [
                    {
                        "name": "id",
                        "in": "path",
                        "required": true,
                        "description": "Loan id",
                        "schema": {
                            "type": "integer"
                        }
                    }
                ]
            }
        },
        "/loans/apply": {
            "post": {
                "tags": [
                    "Loans"
                ],
                "summary": "Create loan application",
                "description": "Starts a loan application for a member.\n\nDocs: https://mfidoc.com/doc/apply-loan",
                "operationId": "applyLoan",
                "responses": {
                    "200": {
                        "description": "OK"
                    },
                    "401": {
                        "description": "Missing or expired token"
                    },
                    "403": {
                        "description": "Not permitted"
                    },
                    "422": {
                        "description": "Validation failed"
                    }
                },
                "requestBody": {
                    "required": true,
                    "content": {
                        "application/json": {
                            "schema": {
                                "type": "object",
                                "properties": {
                                    "contact_id": {
                                        "type": "integer",
                                        "description": "Member id"
                                    }
                                },
                                "required": [
                                    "contact_id"
                                ]
                            }
                        },
                        "application/x-www-form-urlencoded": {
                            "schema": {
                                "type": "object",
                                "properties": {
                                    "contact_id": {
                                        "type": "integer",
                                        "description": "Member id"
                                    }
                                },
                                "required": [
                                    "contact_id"
                                ]
                            }
                        }
                    }
                }
            }
        },
        "/loans/{id}/{action}": {
            "post": {
                "tags": [
                    "Loans"
                ],
                "summary": "Approve, disburse or reject loan",
                "description": "Moves a loan through appraisal, approval and disbursement.\n\nDocs: https://mfidoc.com/doc/loan-action",
                "operationId": "loanAction",
                "responses": {
                    "200": {
                        "description": "OK"
                    },
                    "401": {
                        "description": "Missing or expired token"
                    },
                    "403": {
                        "description": "Not permitted"
                    },
                    "422": {
                        "description": "Validation failed"
                    }
                },
                "parameters": [
                    {
                        "name": "id",
                        "in": "path",
                        "required": true,
                        "description": "Loan id",
                        "schema": {
                            "type": "integer"
                        }
                    },
                    {
                        "name": "action",
                        "in": "path",
                        "required": true,
                        "description": "Lifecycle action, e.g. approve, disburse, reject",
                        "schema": {
                            "type": "string"
                        }
                    }
                ]
            }
        },
        "/loans/{id}/repayment": {
            "post": {
                "tags": [
                    "Loans"
                ],
                "summary": "Record a repayment",
                "description": "Posts a repayment and allocates it to penalties, fees, interest and principal per the product's rules.\n\nDocs: https://mfidoc.com/doc/loan-repayment",
                "operationId": "loanRepayment",
                "responses": {
                    "200": {
                        "description": "OK"
                    },
                    "401": {
                        "description": "Missing or expired token"
                    },
                    "403": {
                        "description": "Not permitted"
                    },
                    "422": {
                        "description": "Validation failed"
                    }
                },
                "parameters": [
                    {
                        "name": "id",
                        "in": "path",
                        "required": true,
                        "description": "Loan id",
                        "schema": {
                            "type": "integer"
                        }
                    }
                ],
                "requestBody": {
                    "required": true,
                    "content": {
                        "application/json": {
                            "schema": {
                                "type": "object",
                                "properties": {
                                    "amount": {
                                        "type": "number",
                                        "description": "Amount in the institution's base currency"
                                    },
                                    "date": {
                                        "type": "string",
                                        "format": "date",
                                        "description": "Value date of the transaction (YYYY-MM-DD)"
                                    },
                                    "payment_type_id": {
                                        "type": "integer",
                                        "description": "Payment channel, from GET /payment-types (cash, M-Pesa, bank...)"
                                    },
                                    "receipt": {
                                        "type": "string",
                                        "description": "Receipt or M-Pesa confirmation code"
                                    },
                                    "description": {
                                        "type": "string",
                                        "description": "Narration shown on the member's statement"
                                    },
                                    "client_ref": {
                                        "type": "string",
                                        "description": "Your unique reference (max 64). Retrying with the same value never posts twice"
                                    }
                                },
                                "required": [
                                    "amount",
                                    "date",
                                    "payment_type_id"
                                ]
                            }
                        },
                        "application/x-www-form-urlencoded": {
                            "schema": {
                                "type": "object",
                                "properties": {
                                    "amount": {
                                        "type": "number",
                                        "description": "Amount in the institution's base currency"
                                    },
                                    "date": {
                                        "type": "string",
                                        "format": "date",
                                        "description": "Value date of the transaction (YYYY-MM-DD)"
                                    },
                                    "payment_type_id": {
                                        "type": "integer",
                                        "description": "Payment channel, from GET /payment-types (cash, M-Pesa, bank...)"
                                    },
                                    "receipt": {
                                        "type": "string",
                                        "description": "Receipt or M-Pesa confirmation code"
                                    },
                                    "description": {
                                        "type": "string",
                                        "description": "Narration shown on the member's statement"
                                    },
                                    "client_ref": {
                                        "type": "string",
                                        "description": "Your unique reference (max 64). Retrying with the same value never posts twice"
                                    }
                                },
                                "required": [
                                    "amount",
                                    "date",
                                    "payment_type_id"
                                ]
                            }
                        }
                    }
                }
            }
        },
        "/loans/{id}/pro-rata-dues": {
            "get": {
                "tags": [
                    "Loans"
                ],
                "summary": "Pro-rata dues",
                "description": "Interest and fees due if the loan were settled on a given date.\n\nDocs: https://mfidoc.com/doc/loan-pro-rata-dues",
                "operationId": "loanProRataDues",
                "responses": {
                    "200": {
                        "description": "OK"
                    },
                    "401": {
                        "description": "Missing or expired token"
                    },
                    "403": {
                        "description": "Not permitted"
                    },
                    "422": {
                        "description": "Validation failed"
                    }
                },
                "parameters": [
                    {
                        "name": "id",
                        "in": "path",
                        "required": true,
                        "description": "Loan id",
                        "schema": {
                            "type": "integer"
                        }
                    }
                ]
            }
        },
        "/loans/{id}/ai-insight": {
            "post": {
                "tags": [
                    "Loans"
                ],
                "summary": "AI loan insight",
                "description": "An AI-written appraisal summary of the loan and member history for the credit committee.\n\nDocs: https://mfidoc.com/doc/loan-ai-insight",
                "operationId": "loanAiInsight",
                "responses": {
                    "200": {
                        "description": "OK"
                    },
                    "401": {
                        "description": "Missing or expired token"
                    },
                    "403": {
                        "description": "Not permitted"
                    },
                    "422": {
                        "description": "Validation failed"
                    }
                },
                "parameters": [
                    {
                        "name": "id",
                        "in": "path",
                        "required": true,
                        "description": "Loan id",
                        "schema": {
                            "type": "integer"
                        }
                    }
                ]
            }
        },
        "/overview/portfolio-at-risk": {
            "get": {
                "tags": [
                    "Portfolio & Reports"
                ],
                "summary": "Portfolio at risk (PAR)",
                "description": "Outstanding balance in arrears bucketed by PAR 1, 30, 60 and 90. Cached for 10 minutes.\n\nDocs: https://mfidoc.com/doc/portfolio-at-risk",
                "operationId": "portfolioAtRisk",
                "responses": {
                    "200": {
                        "description": "OK"
                    },
                    "401": {
                        "description": "Missing or expired token"
                    },
                    "403": {
                        "description": "Not permitted"
                    },
                    "422": {
                        "description": "Validation failed"
                    }
                }
            }
        },
        "/overview/totals": {
            "get": {
                "tags": [
                    "Portfolio & Reports"
                ],
                "summary": "Dashboard totals",
                "description": "Members, active loans, portfolio outstanding, savings and collections for a date range.\n\nDocs: https://mfidoc.com/doc/overview-totals",
                "operationId": "overviewTotals",
                "responses": {
                    "200": {
                        "description": "OK"
                    },
                    "401": {
                        "description": "Missing or expired token"
                    },
                    "403": {
                        "description": "Not permitted"
                    },
                    "422": {
                        "description": "Validation failed"
                    }
                },
                "parameters": [
                    {
                        "name": "start_date",
                        "in": "query",
                        "required": true,
                        "description": "Range start",
                        "schema": {
                            "type": "string",
                            "format": "date"
                        }
                    },
                    {
                        "name": "end_date",
                        "in": "query",
                        "required": true,
                        "description": "Range end",
                        "schema": {
                            "type": "string",
                            "format": "date"
                        }
                    }
                ]
            }
        },
        "/overview/member-growth": {
            "get": {
                "tags": [
                    "Portfolio & Reports"
                ],
                "summary": "Member growth",
                "description": "New members per month.\n\nDocs: https://mfidoc.com/doc/member-growth",
                "operationId": "memberGrowth",
                "responses": {
                    "200": {
                        "description": "OK"
                    },
                    "401": {
                        "description": "Missing or expired token"
                    },
                    "403": {
                        "description": "Not permitted"
                    },
                    "422": {
                        "description": "Validation failed"
                    }
                }
            }
        },
        "/overview/loans-chart": {
            "get": {
                "tags": [
                    "Portfolio & Reports"
                ],
                "summary": "Disbursed vs collected",
                "description": "Monthly loans released against loans collected for a year.\n\nDocs: https://mfidoc.com/doc/loans-chart",
                "operationId": "loansChart",
                "responses": {
                    "200": {
                        "description": "OK"
                    },
                    "401": {
                        "description": "Missing or expired token"
                    },
                    "403": {
                        "description": "Not permitted"
                    },
                    "422": {
                        "description": "Validation failed"
                    }
                }
            }
        },
        "/overview/pending-loans": {
            "get": {
                "tags": [
                    "Portfolio & Reports"
                ],
                "summary": "Pending loans",
                "description": "Loans awaiting approval or disbursement.\n\nDocs: https://mfidoc.com/doc/pending-loans",
                "operationId": "pendingLoans",
                "responses": {
                    "200": {
                        "description": "OK"
                    },
                    "401": {
                        "description": "Missing or expired token"
                    },
                    "403": {
                        "description": "Not permitted"
                    },
                    "422": {
                        "description": "Validation failed"
                    }
                }
            }
        },
        "/payment-types": {
            "get": {
                "tags": [
                    "Reference Data"
                ],
                "summary": "List payment channels",
                "description": "Active payment types (cash, M-Pesa, bank, cheque). Use the id as payment_type_id.\n\nDocs: https://mfidoc.com/doc/payment-types",
                "operationId": "paymentTypes",
                "responses": {
                    "200": {
                        "description": "OK"
                    },
                    "401": {
                        "description": "Missing or expired token"
                    },
                    "403": {
                        "description": "Not permitted"
                    },
                    "422": {
                        "description": "Validation failed"
                    }
                }
            }
        },
        "/accounts/options": {
            "get": {
                "tags": [
                    "Reference Data"
                ],
                "summary": "Account product options",
                "description": "Loan and savings products a member can apply for.\n\nDocs: https://mfidoc.com/doc/accounts-options",
                "operationId": "accountsOptions",
                "responses": {
                    "200": {
                        "description": "OK"
                    },
                    "401": {
                        "description": "Missing or expired token"
                    },
                    "403": {
                        "description": "Not permitted"
                    },
                    "422": {
                        "description": "Validation failed"
                    }
                }
            }
        }
    }
}