Core retail banking source system: customers, accounts, transactions, cards, products, loans & applications, plus the relationship/servicing layer (interactions, opportunities, complaints). Every record carries a `country` (IN | AU | US) and self-describing money; narrow any list with the `country` filter.
---
**Acting as a user (`X-PS-Impersonate-User`).** Every endpoint accepts an optional `X-PS-Impersonate-User` request header whose value is the email of the instance user to act as. The effective user resolves in this order: the header if present, else the instance's configured default MCP user, else none. User-scoped paths additionally accept the literal `me` in place of an email, and Graph-style apps also serve `/me/…` twins of their `/users/{email}/…` paths that resolve the same way. This header is honored by all operations but is intentionally omitted from each operation's parameter list so it is not surfaced as a per-tool argument by MCP clients; see the `ImpersonateUser` entry under `components.parameters`.
Core retail banking source system: customers, accounts, transactions, cards, products, loans & applications, plus the relationship/servicing layer (interactions, opportunities, complaints). Every record carries a `country` (IN | AU | US) and self-describing money; narrow any list with the `country` filter.
---
**Acting as a user (`X-PS-Impersonate-User`).** Every endpoint accepts an optional `X-PS-Impersonate-User` request header whose value is the email of the instance user to act as. The effective user resolves in this order: the header if present, else the instance's configured default MCP user, else none. User-scoped paths additionally accept the literal `me` in place of an email, and Graph-style apps also serve `/me/…` twins of their `/users/{email}/…` paths that resolve the same way. This header is honored by all operations but is intentionally omitted from each operation's parameter list so it is not surfaced as a per-tool argument by MCP clients; see the `ImpersonateUser` entry under `components.parameters`.
Operations
GET /customers
List banking customers
Purple Retail Banking customers are the retail parties (individuals and SMEs) who hold the accounts, cards and loans in this bank, each with a segment, KYC status, risk rating, relationship manager and country (IN | AU | US). Not CRM accounts or contacts (B2B sales) and not internal employees. Narrow results server-side with this endpoint's named filter params (country, customer_id, status, …) or with OData $filter, $orderby, $select, $search, $top, $skip and $count (MCP clients send those as _filter, _orderby, …) instead of paging through everything.
Authentication
[
{
"patAuth": []
}
]
Request, responses and operation details
{
"summary": "List banking customers",
"parameters": [
{
"$ref": "#/components/parameters/InstanceId"
},
{
"in": "query",
"name": "limit",
"schema": {
"type": "integer",
"default": 50
},
"description": "Max items per page (default 50)"
},
{
"in": "query",
"name": "cursor",
"schema": {
"type": "string"
},
"description": "Pass the previous response's nextCursor to fetch the next page"
},
{
"in": "query",
"name": "$filter",
"schema": {
"type": "string"
},
"description": "OData filter expression. Comparison operators: eq, ne, gt, ge, lt, le. Logical: and, or, not, with parentheses for grouping. String functions: contains(field,'x'), startswith(field,'x'), endswith(field,'x'). Membership: field in ('a','b'). Case-insensitive matching via tolower(field) / toupper(field). Nested fields use a slash, e.g. pto_balance/vacation_days. String literals use single quotes; dates are ISO-8601. Examples: \"status eq 'active'\"; \"salary gt 50000 and department eq 'Engineering'\"; \"contains(tolower(name),'acme')\"; \"closeDate gt 2026-01-01\"."
},
{
"in": "query",
"name": "$select",
"schema": {
"type": "string"
},
"description": "Comma-separated list of fields to return, e.g. \"id,firstName,email\". Nested fields via slash (\"pto_balance/vacation_days\"). The id field is always included."
},
{
"in": "query",
"name": "$orderby",
"schema": {
"type": "string"
},
"description": "Sort clause(s), comma-separated, each \"field [asc|desc]\" (asc is the default). Example: \"createdAt desc, lastName asc\". Null values sort last."
},
{
"in": "query",
"name": "$search",
"schema": {
"type": "string"
},
"description": "Free-text, case-insensitive substring match across the resource's searchable fields."
},
{
"in": "query",
"name": "$top",
"schema": {
"type": "integer"
},
"description": "Maximum number of items to return (page size)."
},
{
"in": "query",
"name": "$skip",
"schema": {
"type": "integer"
},
"description": "Number of matching items to skip before returning results (offset paging). Combine with $top."
},
{
"in": "query",
"name": "$count",
"schema": {
"type": "boolean"
},
"description": "When true, include @odata.count (total matches after $filter/$search, before paging) in the response."
},
{
"in": "query",
"name": "country",
"required": false,
"schema": {
"type": "string",
"enum": [
"IN",
"AU",
"US",
"GB",
"KR",
"DE"
]
},
"description": "Filter to a single country (IN | AU | US)"
},
{
"in": "query",
"name": "segment",
"required": false,
"schema": {
"type": "string",
"enum": [
"mass",
"affluent",
"hni",
"nri",
"sme"
]
},
"description": "Filter by customer segment"
},
{
"in": "query",
"name": "kyc_status",
"required": false,
"schema": {
"type": "string",
"enum": [
"verified",
"pending",
"expired",
"in_remediation"
]
},
"description": "Filter by KYC status"
},
{
"in": "query",
"name": "risk_rating",
"required": false,
"schema": {
"type": "string",
"enum": [
"low",
"medium",
"high"
]
},
"description": "Filter by risk rating"
},
{
"in": "query",
"name": "relationship_manager",
"required": false,
"schema": {
"type": "string"
},
"description": "Filter by relationship manager email"
}
],
"responses": {
"200": {
"description": "Paginated list",
"content": {
"application/json": {
"schema": {
"type": "object",
"properties": {
"data": {
"type": "array",
"items": {
"$ref": "#/components/schemas/Customer"
}
},
"nextCursor": {
"type": "string",
"nullable": true,
"description": "Cursor for the next page, or null on the last page"
},
"total": {
"type": "integer",
"description": "Total documents matching the filter"
}
}
}
}
}
}
},
"description": "Purple Retail Banking customers are the retail parties (individuals and SMEs) who hold the accounts, cards and loans in this bank, each with a segment, KYC status, risk rating, relationship manager and country (IN | AU | US). Not CRM accounts or contacts (B2B sales) and not internal employees. Narrow results server-side with this endpoint's named filter params (country, customer_id, status, …) or with OData $filter, $orderby, $select, $search, $top, $skip and $count (MCP clients send those as _filter, _orderby, …) instead of paging through everything."
}
POST /customers
Onboard customer
Create a new retail banking customer record. Seldom the right move during a servicing conversation: look the person up with the list tool first, since duplicate customers orphan accounts and cards.
Authentication
[
{
"patAuth": []
}
]
Request, responses and operation details
{
"summary": "Onboard customer",
"parameters": [
{
"$ref": "#/components/parameters/InstanceId"
}
],
"requestBody": {
"required": true,
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/Customer"
}
}
}
},
"responses": {
"201": {
"description": "Created",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/Customer"
}
}
}
}
},
"description": "Create a new retail banking customer record. Seldom the right move during a servicing conversation: look the person up with the list tool first, since duplicate customers orphan accounts and cards."
}
GET /customers/{id}
Get banking customer
Fetch one banking customer by id (e.g. CUST-0001) with segment, KYC status, risk rating, credit score, relationship manager and home branch. To get their accounts, cards, loans and open complaints in a single call, use the customer portfolio tool instead.
Authentication
[
{
"patAuth": []
}
]
Request, responses and operation details
{
"summary": "Get banking customer",
"parameters": [
{
"$ref": "#/components/parameters/InstanceId"
},
{
"in": "path",
"name": "id",
"required": true,
"schema": {
"type": "string"
}
}
],
"responses": {
"200": {
"description": "Found",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/Customer"
}
}
}
},
"404": {
"description": "Not found"
}
},
"description": "Fetch one banking customer by id (e.g. CUST-0001) with segment, KYC status, risk rating, credit score, relationship manager and home branch. To get their accounts, cards, loans and open complaints in a single call, use the customer portfolio tool instead."
}
PATCH /customers/{id}
Update banking customer
Partially update a banking customer's profile — contact details, address, segment, relationship manager or risk rating. KYC remediation and watchlist handling live in Purple Risk & Compliance, not here.
Authentication
[
{
"patAuth": []
}
]
Request, responses and operation details
{
"summary": "Update banking customer",
"parameters": [
{
"$ref": "#/components/parameters/InstanceId"
},
{
"in": "path",
"name": "id",
"required": true,
"schema": {
"type": "string"
}
}
],
"requestBody": {
"description": "Fields to update (partial)",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/Customer"
}
}
}
},
"responses": {
"200": {
"description": "Updated",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/Customer"
}
}
}
},
"404": {
"description": "Not found"
}
},
"description": "Partially update a banking customer's profile — contact details, address, segment, relationship manager or risk rating. KYC remediation and watchlist handling live in Purple Risk & Compliance, not here."
}
DELETE /customers/{id}
Delete banking customer
Permanently delete a banking customer record. Destructive and irreversible, and it orphans their accounts, cards, loans and complaints — effectively never correct in a servicing flow.
Authentication
[
{
"patAuth": []
}
]
Request, responses and operation details
{
"summary": "Delete banking customer",
"parameters": [
{
"$ref": "#/components/parameters/InstanceId"
},
{
"in": "path",
"name": "id",
"required": true,
"schema": {
"type": "string"
}
}
],
"responses": {
"200": {
"description": "Deleted",
"content": {
"application/json": {
"schema": {
"type": "object",
"properties": {
"success": {
"type": "boolean"
},
"id": {
"type": "string"
}
}
}
}
}
},
"404": {
"description": "Not found"
}
},
"description": "Permanently delete a banking customer record. Destructive and irreversible, and it orphans their accounts, cards, loans and complaints — effectively never correct in a servicing flow."
}
GET /customers/{id}/portfolio
Get customer 360 portfolio
One-call briefing on a single banking customer: the customer record plus their accounts, cards, loans, opportunities, recent interactions and open complaints. Prefer this over five separate list calls whenever the question is about one named customer.
Authentication
[
{
"patAuth": []
}
]
Request, responses and operation details
{
"summary": "Get customer 360 portfolio",
"description": "One-call briefing on a single banking customer: the customer record plus their accounts, cards, loans, opportunities, recent interactions and open complaints. Prefer this over five separate list calls whenever the question is about one named customer.",
"parameters": [
{
"$ref": "#/components/parameters/InstanceId"
},
{
"in": "path",
"name": "id",
"required": true,
"schema": {
"type": "string"
}
}
],
"responses": {
"200": {
"description": "Aggregated customer portfolio",
"content": {
"application/json": {
"schema": {
"type": "object",
"properties": {
"customer": {
"$ref": "#/components/schemas/Customer"
},
"accounts": {
"type": "array",
"items": {
"$ref": "#/components/schemas/Account"
}
},
"cards": {
"type": "array",
"items": {
"$ref": "#/components/schemas/Card"
}
},
"loans": {
"type": "array",
"items": {
"$ref": "#/components/schemas/Loan"
}
},
"opportunities": {
"type": "array",
"items": {
"$ref": "#/components/schemas/Opportunity"
}
},
"recent_interactions": {
"type": "array",
"items": {
"$ref": "#/components/schemas/Interaction"
}
},
"open_complaints": {
"type": "array",
"items": {
"$ref": "#/components/schemas/Complaint"
}
}
}
}
}
}
},
"404": {
"description": "Customer not found"
}
}
}
GET /bank_accounts
List bank accounts
Deposit and current accounts held by Purple Retail Banking customers, with a self-describing balance, status (active | dormant | frozen | closed), branch and routing details. These are real bank accounts, not CRM accounts (companies) or ERP ledger accounts. Narrow results server-side with this endpoint's named filter params (country, customer_id, status, …) or with OData $filter, $orderby, $select, $search, $top, $skip and $count (MCP clients send those as _filter, _orderby, …) instead of paging through everything.
Authentication
[
{
"patAuth": []
}
]
Request, responses and operation details
{
"summary": "List bank accounts",
"parameters": [
{
"$ref": "#/components/parameters/InstanceId"
},
{
"in": "query",
"name": "limit",
"schema": {
"type": "integer",
"default": 50
},
"description": "Max items per page (default 50)"
},
{
"in": "query",
"name": "cursor",
"schema": {
"type": "string"
},
"description": "Pass the previous response's nextCursor to fetch the next page"
},
{
"in": "query",
"name": "$filter",
"schema": {
"type": "string"
},
"description": "OData filter expression. Comparison operators: eq, ne, gt, ge, lt, le. Logical: and, or, not, with parentheses for grouping. String functions: contains(field,'x'), startswith(field,'x'), endswith(field,'x'). Membership: field in ('a','b'). Case-insensitive matching via tolower(field) / toupper(field). Nested fields use a slash, e.g. pto_balance/vacation_days. String literals use single quotes; dates are ISO-8601. Examples: \"status eq 'active'\"; \"salary gt 50000 and department eq 'Engineering'\"; \"contains(tolower(name),'acme')\"; \"closeDate gt 2026-01-01\"."
},
{
"in": "query",
"name": "$select",
"schema": {
"type": "string"
},
"description": "Comma-separated list of fields to return, e.g. \"id,firstName,email\". Nested fields via slash (\"pto_balance/vacation_days\"). The id field is always included."
},
{
"in": "query",
"name": "$orderby",
"schema": {
"type": "string"
},
"description": "Sort clause(s), comma-separated, each \"field [asc|desc]\" (asc is the default). Example: \"createdAt desc, lastName asc\". Null values sort last."
},
{
"in": "query",
"name": "$search",
"schema": {
"type": "string"
},
"description": "Free-text, case-insensitive substring match across the resource's searchable fields."
},
{
"in": "query",
"name": "$top",
"schema": {
"type": "integer"
},
"description": "Maximum number of items to return (page size)."
},
{
"in": "query",
"name": "$skip",
"schema": {
"type": "integer"
},
"description": "Number of matching items to skip before returning results (offset paging). Combine with $top."
},
{
"in": "query",
"name": "$count",
"schema": {
"type": "boolean"
},
"description": "When true, include @odata.count (total matches after $filter/$search, before paging) in the response."
},
{
"in": "query",
"name": "country",
"required": false,
"schema": {
"type": "string",
"enum": [
"IN",
"AU",
"US",
"GB",
"KR",
"DE"
]
},
"description": "Filter to a single country (IN | AU | US)"
},
{
"in": "query",
"name": "customer_id",
"required": false,
"schema": {
"type": "string"
},
"description": "Filter by customer id"
},
{
"in": "query",
"name": "type",
"required": false,
"schema": {
"type": "string"
},
"description": "Filter by account type"
},
{
"in": "query",
"name": "status",
"required": false,
"schema": {
"type": "string",
"enum": [
"active",
"dormant",
"frozen",
"closed"
]
},
"description": "Filter by status"
}
],
"responses": {
"200": {
"description": "Paginated list",
"content": {
"application/json": {
"schema": {
"type": "object",
"properties": {
"data": {
"type": "array",
"items": {
"$ref": "#/components/schemas/Account"
}
},
"nextCursor": {
"type": "string",
"nullable": true,
"description": "Cursor for the next page, or null on the last page"
},
"total": {
"type": "integer",
"description": "Total documents matching the filter"
}
}
}
}
}
}
},
"description": "Deposit and current accounts held by Purple Retail Banking customers, with a self-describing balance, status (active | dormant | frozen | closed), branch and routing details. These are real bank accounts, not CRM accounts (companies) or ERP ledger accounts. Narrow results server-side with this endpoint's named filter params (country, customer_id, status, …) or with OData $filter, $orderby, $select, $search, $top, $skip and $count (MCP clients send those as _filter, _orderby, …) instead of paging through everything."
}
POST /bank_accounts
Open bank account
Create a new deposit or current account for an existing banking customer. Use this to open an account, not to record a payment into one.
Authentication
[
{
"patAuth": []
}
]
Request, responses and operation details
{
"summary": "Open bank account",
"parameters": [
{
"$ref": "#/components/parameters/InstanceId"
}
],
"requestBody": {
"required": true,
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/Account"
}
}
}
},
"responses": {
"201": {
"description": "Created",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/Account"
}
}
}
}
},
"description": "Create a new deposit or current account for an existing banking customer. Use this to open an account, not to record a payment into one."
}
GET /bank_accounts/{id}
Get bank account
Fetch one bank account by id (e.g. ACCT-0001) with its balance, status, freeze_reason, routing details and status_history — the record to check before freezing or explaining a decline.
Authentication
[
{
"patAuth": []
}
]
Request, responses and operation details
{
"summary": "Get bank account",
"parameters": [
{
"$ref": "#/components/parameters/InstanceId"
},
{
"in": "path",
"name": "id",
"required": true,
"schema": {
"type": "string"
}
}
],
"responses": {
"200": {
"description": "Found",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/Account"
}
}
}
},
"404": {
"description": "Not found"
}
},
"description": "Fetch one bank account by id (e.g. ACCT-0001) with its balance, status, freeze_reason, routing details and status_history — the record to check before freezing or explaining a decline."
}
PATCH /bank_accounts/{id}
Update bank account
Partially update an account's mutable fields such as type, branch or routing. Do not change the status field here to stop activity: the freeze and unfreeze tools enforce the transition and write status_history.
Authentication
[
{
"patAuth": []
}
]
Request, responses and operation details
{
"summary": "Update bank account",
"parameters": [
{
"$ref": "#/components/parameters/InstanceId"
},
{
"in": "path",
"name": "id",
"required": true,
"schema": {
"type": "string"
}
}
],
"requestBody": {
"description": "Fields to update (partial)",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/Account"
}
}
}
},
"responses": {
"200": {
"description": "Updated",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/Account"
}
}
}
},
"404": {
"description": "Not found"
}
},
"description": "Partially update an account's mutable fields such as type, branch or routing. Do not change the status field here to stop activity: the freeze and unfreeze tools enforce the transition and write status_history."
}
DELETE /bank_accounts/{id}
Delete bank account
Permanently delete a bank account record. Destructive and irreversible, and it strands the account's transactions and cards. To stop activity, freeze it; to close it properly, set status to 'closed'.
Authentication
[
{
"patAuth": []
}
]
Request, responses and operation details
{
"summary": "Delete bank account",
"parameters": [
{
"$ref": "#/components/parameters/InstanceId"
},
{
"in": "path",
"name": "id",
"required": true,
"schema": {
"type": "string"
}
}
],
"responses": {
"200": {
"description": "Deleted",
"content": {
"application/json": {
"schema": {
"type": "object",
"properties": {
"success": {
"type": "boolean"
},
"id": {
"type": "string"
}
}
}
}
}
},
"404": {
"description": "Not found"
}
},
"description": "Permanently delete a bank account record. Destructive and irreversible, and it strands the account's transactions and cards. To stop activity, freeze it; to close it properly, set status to 'closed'."
}
POST /bank_accounts/{id}/freeze
Freeze a bank account
Stop all activity on a bank account: sets status to 'frozen' and records the reason in status_history. Use it for suspected fraud or a customer request covering the whole account; to stop just one card use the card block tool instead. Fails with 422 if the account is already frozen or closed. Reversible via unfreeze.
Authentication
[
{
"patAuth": []
}
]
Request, responses and operation details
{
"summary": "Freeze a bank account",
"description": "Stop all activity on a bank account: sets status to 'frozen' and records the reason in status_history. Use it for suspected fraud or a customer request covering the whole account; to stop just one card use the card block tool instead. Fails with 422 if the account is already frozen or closed. Reversible via unfreeze.",
"parameters": [
{
"$ref": "#/components/parameters/InstanceId"
},
{
"in": "path",
"name": "id",
"required": true,
"schema": {
"type": "string"
}
}
],
"requestBody": {
"content": {
"application/json": {
"schema": {
"type": "object",
"properties": {
"reason": {
"type": "string",
"example": "Suspected unauthorised activity"
}
}
}
}
}
},
"responses": {
"200": {
"description": "Frozen",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/Account"
}
}
}
},
"404": {
"description": "Not found"
},
"422": {
"description": "Invalid state transition"
}
}
}
POST /bank_accounts/{id}/unfreeze
Unfreeze a bank account
Return a frozen bank account to 'active' and record why, e.g. once a fraud review clears. Fails with 422 if the account is not currently frozen.
Authentication
[
{
"patAuth": []
}
]
Request, responses and operation details
{
"summary": "Unfreeze a bank account",
"description": "Return a frozen bank account to 'active' and record why, e.g. once a fraud review clears. Fails with 422 if the account is not currently frozen.",
"parameters": [
{
"$ref": "#/components/parameters/InstanceId"
},
{
"in": "path",
"name": "id",
"required": true,
"schema": {
"type": "string"
}
}
],
"requestBody": {
"content": {
"application/json": {
"schema": {
"type": "object",
"properties": {
"reason": {
"type": "string"
}
}
}
}
}
},
"responses": {
"200": {
"description": "Unfrozen",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/Account"
}
}
}
},
"404": {
"description": "Not found"
},
"422": {
"description": "Invalid state transition"
}
}
}
GET /transactions
List account transactions
Money movement on Purple Retail Banking accounts — card, UPI and transfer entries with a self-describing amount, direction (debit | credit), channel, counterparty, status and an is_flagged marker. Customer banking activity, not ERP invoices or employee expenses. Narrow results server-side with this endpoint's named filter params (country, customer_id, status, …) or with OData $filter, $orderby, $select, $search, $top, $skip and $count (MCP clients send those as _filter, _orderby, …) instead of paging through everything.
Authentication
[
{
"patAuth": []
}
]
Request, responses and operation details
{
"summary": "List account transactions",
"parameters": [
{
"$ref": "#/components/parameters/InstanceId"
},
{
"in": "query",
"name": "limit",
"schema": {
"type": "integer",
"default": 50
},
"description": "Max items per page (default 50)"
},
{
"in": "query",
"name": "cursor",
"schema": {
"type": "string"
},
"description": "Pass the previous response's nextCursor to fetch the next page"
},
{
"in": "query",
"name": "$filter",
"schema": {
"type": "string"
},
"description": "OData filter expression. Comparison operators: eq, ne, gt, ge, lt, le. Logical: and, or, not, with parentheses for grouping. String functions: contains(field,'x'), startswith(field,'x'), endswith(field,'x'). Membership: field in ('a','b'). Case-insensitive matching via tolower(field) / toupper(field). Nested fields use a slash, e.g. pto_balance/vacation_days. String literals use single quotes; dates are ISO-8601. Examples: \"status eq 'active'\"; \"salary gt 50000 and department eq 'Engineering'\"; \"contains(tolower(name),'acme')\"; \"closeDate gt 2026-01-01\"."
},
{
"in": "query",
"name": "$select",
"schema": {
"type": "string"
},
"description": "Comma-separated list of fields to return, e.g. \"id,firstName,email\". Nested fields via slash (\"pto_balance/vacation_days\"). The id field is always included."
},
{
"in": "query",
"name": "$orderby",
"schema": {
"type": "string"
},
"description": "Sort clause(s), comma-separated, each \"field [asc|desc]\" (asc is the default). Example: \"createdAt desc, lastName asc\". Null values sort last."
},
{
"in": "query",
"name": "$search",
"schema": {
"type": "string"
},
"description": "Free-text, case-insensitive substring match across the resource's searchable fields."
},
{
"in": "query",
"name": "$top",
"schema": {
"type": "integer"
},
"description": "Maximum number of items to return (page size)."
},
{
"in": "query",
"name": "$skip",
"schema": {
"type": "integer"
},
"description": "Number of matching items to skip before returning results (offset paging). Combine with $top."
},
{
"in": "query",
"name": "$count",
"schema": {
"type": "boolean"
},
"description": "When true, include @odata.count (total matches after $filter/$search, before paging) in the response."
},
{
"in": "query",
"name": "country",
"required": false,
"schema": {
"type": "string",
"enum": [
"IN",
"AU",
"US",
"GB",
"KR",
"DE"
]
},
"description": "Filter to a single country (IN | AU | US)"
},
{
"in": "query",
"name": "account_id",
"required": false,
"schema": {
"type": "string"
},
"description": "Filter by account id"
},
{
"in": "query",
"name": "direction",
"required": false,
"schema": {
"type": "string",
"enum": [
"debit",
"credit"
]
},
"description": "Filter by direction"
},
{
"in": "query",
"name": "channel",
"required": false,
"schema": {
"type": "string"
},
"description": "Filter by channel"
},
{
"in": "query",
"name": "status",
"required": false,
"schema": {
"type": "string",
"enum": [
"posted",
"pending",
"disputed",
"reversed"
]
},
"description": "Filter by status"
}
],
"responses": {
"200": {
"description": "Paginated list",
"content": {
"application/json": {
"schema": {
"type": "object",
"properties": {
"data": {
"type": "array",
"items": {
"$ref": "#/components/schemas/Transaction"
}
},
"nextCursor": {
"type": "string",
"nullable": true,
"description": "Cursor for the next page, or null on the last page"
},
"total": {
"type": "integer",
"description": "Total documents matching the filter"
}
}
}
}
}
}
},
"description": "Money movement on Purple Retail Banking accounts — card, UPI and transfer entries with a self-describing amount, direction (debit | credit), channel, counterparty, status and an is_flagged marker. Customer banking activity, not ERP invoices or employee expenses. Narrow results server-side with this endpoint's named filter params (country, customer_id, status, …) or with OData $filter, $orderby, $select, $search, $top, $skip and $count (MCP clients send those as _filter, _orderby, …) instead of paging through everything."
}
POST /transactions
Create transaction
Write a transaction record against an account. This is a source-system record only: it does not move money and does not recompute the account balance.
Authentication
[
{
"patAuth": []
}
]
Request, responses and operation details
{
"summary": "Create transaction",
"parameters": [
{
"$ref": "#/components/parameters/InstanceId"
}
],
"requestBody": {
"required": true,
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/Transaction"
}
}
}
},
"responses": {
"201": {
"description": "Created",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/Transaction"
}
}
}
}
},
"description": "Write a transaction record against an account. This is a source-system record only: it does not move money and does not recompute the account balance."
}
GET /transactions/{id}
Get transaction
Fetch one transaction by id (e.g. TXN-00001) with its amount, direction, channel, counterparty and status — the entry to cite when a customer queries or disputes a debit.
Authentication
[
{
"patAuth": []
}
]
Request, responses and operation details
{
"summary": "Get transaction",
"parameters": [
{
"$ref": "#/components/parameters/InstanceId"
},
{
"in": "path",
"name": "id",
"required": true,
"schema": {
"type": "string"
}
}
],
"responses": {
"200": {
"description": "Found",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/Transaction"
}
}
}
},
"404": {
"description": "Not found"
}
},
"description": "Fetch one transaction by id (e.g. TXN-00001) with its amount, direction, channel, counterparty and status — the entry to cite when a customer queries or disputes a debit."
}
PATCH /transactions/{id}
Update transaction
Partially update a transaction, typically to mark it disputed or reversed, or to set is_flagged during a fraud review. The fraud alert and case records themselves live in Purple Risk & Compliance.
Authentication
[
{
"patAuth": []
}
]
Request, responses and operation details
{
"summary": "Update transaction",
"parameters": [
{
"$ref": "#/components/parameters/InstanceId"
},
{
"in": "path",
"name": "id",
"required": true,
"schema": {
"type": "string"
}
}
],
"requestBody": {
"description": "Fields to update (partial)",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/Transaction"
}
}
}
},
"responses": {
"200": {
"description": "Updated",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/Transaction"
}
}
}
},
"404": {
"description": "Not found"
}
},
"description": "Partially update a transaction, typically to mark it disputed or reversed, or to set is_flagged during a fraud review. The fraud alert and case records themselves live in Purple Risk & Compliance."
}
DELETE /transactions/{id}
Delete transaction
Permanently delete a transaction record. Destructive and irreversible, and it breaks the account's audit trail — model a real reversal by setting status to 'reversed' instead.
Authentication
[
{
"patAuth": []
}
]
Request, responses and operation details
{
"summary": "Delete transaction",
"parameters": [
{
"$ref": "#/components/parameters/InstanceId"
},
{
"in": "path",
"name": "id",
"required": true,
"schema": {
"type": "string"
}
}
],
"responses": {
"200": {
"description": "Deleted",
"content": {
"application/json": {
"schema": {
"type": "object",
"properties": {
"success": {
"type": "boolean"
},
"id": {
"type": "string"
}
}
}
}
}
},
"404": {
"description": "Not found"
}
},
"description": "Permanently delete a transaction record. Destructive and irreversible, and it breaks the account's audit trail — model a real reversal by setting status to 'reversed' instead."
}
GET /cards
List cards
Debit and credit cards issued to Purple Retail Banking customers, with network, type, masked last_four, the account they draw on, limits and status (active | blocked | expired). Narrow results server-side with this endpoint's named filter params (country, customer_id, status, …) or with OData $filter, $orderby, $select, $search, $top, $skip and $count (MCP clients send those as _filter, _orderby, …) instead of paging through everything.
Authentication
[
{
"patAuth": []
}
]
Request, responses and operation details
{
"summary": "List cards",
"parameters": [
{
"$ref": "#/components/parameters/InstanceId"
},
{
"in": "query",
"name": "limit",
"schema": {
"type": "integer",
"default": 50
},
"description": "Max items per page (default 50)"
},
{
"in": "query",
"name": "cursor",
"schema": {
"type": "string"
},
"description": "Pass the previous response's nextCursor to fetch the next page"
},
{
"in": "query",
"name": "$filter",
"schema": {
"type": "string"
},
"description": "OData filter expression. Comparison operators: eq, ne, gt, ge, lt, le. Logical: and, or, not, with parentheses for grouping. String functions: contains(field,'x'), startswith(field,'x'), endswith(field,'x'). Membership: field in ('a','b'). Case-insensitive matching via tolower(field) / toupper(field). Nested fields use a slash, e.g. pto_balance/vacation_days. String literals use single quotes; dates are ISO-8601. Examples: \"status eq 'active'\"; \"salary gt 50000 and department eq 'Engineering'\"; \"contains(tolower(name),'acme')\"; \"closeDate gt 2026-01-01\"."
},
{
"in": "query",
"name": "$select",
"schema": {
"type": "string"
},
"description": "Comma-separated list of fields to return, e.g. \"id,firstName,email\". Nested fields via slash (\"pto_balance/vacation_days\"). The id field is always included."
},
{
"in": "query",
"name": "$orderby",
"schema": {
"type": "string"
},
"description": "Sort clause(s), comma-separated, each \"field [asc|desc]\" (asc is the default). Example: \"createdAt desc, lastName asc\". Null values sort last."
},
{
"in": "query",
"name": "$search",
"schema": {
"type": "string"
},
"description": "Free-text, case-insensitive substring match across the resource's searchable fields."
},
{
"in": "query",
"name": "$top",
"schema": {
"type": "integer"
},
"description": "Maximum number of items to return (page size)."
},
{
"in": "query",
"name": "$skip",
"schema": {
"type": "integer"
},
"description": "Number of matching items to skip before returning results (offset paging). Combine with $top."
},
{
"in": "query",
"name": "$count",
"schema": {
"type": "boolean"
},
"description": "When true, include @odata.count (total matches after $filter/$search, before paging) in the response."
},
{
"in": "query",
"name": "country",
"required": false,
"schema": {
"type": "string",
"enum": [
"IN",
"AU",
"US",
"GB",
"KR",
"DE"
]
},
"description": "Filter to a single country (IN | AU | US)"
},
{
"in": "query",
"name": "customer_id",
"required": false,
"schema": {
"type": "string"
},
"description": "Filter by customer id"
},
{
"in": "query",
"name": "account_id",
"required": false,
"schema": {
"type": "string"
},
"description": "Filter by account id"
},
{
"in": "query",
"name": "status",
"required": false,
"schema": {
"type": "string",
"enum": [
"active",
"blocked",
"expired"
]
},
"description": "Filter by status"
}
],
"responses": {
"200": {
"description": "Paginated list",
"content": {
"application/json": {
"schema": {
"type": "object",
"properties": {
"data": {
"type": "array",
"items": {
"$ref": "#/components/schemas/Card"
}
},
"nextCursor": {
"type": "string",
"nullable": true,
"description": "Cursor for the next page, or null on the last page"
},
"total": {
"type": "integer",
"description": "Total documents matching the filter"
}
}
}
}
}
}
},
"description": "Debit and credit cards issued to Purple Retail Banking customers, with network, type, masked last_four, the account they draw on, limits and status (active | blocked | expired). Narrow results server-side with this endpoint's named filter params (country, customer_id, status, …) or with OData $filter, $orderby, $select, $search, $top, $skip and $count (MCP clients send those as _filter, _orderby, …) instead of paging through everything."
}
POST /cards
Issue card
Issue a new card to a banking customer and link it to one of their accounts. For a lost card, block the existing card first rather than only issuing a replacement.
Authentication
[
{
"patAuth": []
}
]
Request, responses and operation details
{
"summary": "Issue card",
"parameters": [
{
"$ref": "#/components/parameters/InstanceId"
}
],
"requestBody": {
"required": true,
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/Card"
}
}
}
},
"responses": {
"201": {
"description": "Created",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/Card"
}
}
}
}
},
"description": "Issue a new card to a banking customer and link it to one of their accounts. For a lost card, block the existing card first rather than only issuing a replacement."
}
GET /cards/{id}
Get card
Fetch one card by id with its network, type, last_four, linked account, limits and status — the record to check before blocking or explaining a declined payment.
Authentication
[
{
"patAuth": []
}
]
Request, responses and operation details
{
"summary": "Get card",
"parameters": [
{
"$ref": "#/components/parameters/InstanceId"
},
{
"in": "path",
"name": "id",
"required": true,
"schema": {
"type": "string"
}
}
],
"responses": {
"200": {
"description": "Found",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/Card"
}
}
}
},
"404": {
"description": "Not found"
}
},
"description": "Fetch one card by id with its network, type, last_four, linked account, limits and status — the record to check before blocking or explaining a declined payment."
}
PATCH /cards/{id}
Update card
Partially update card attributes such as limits, linked account or expiry. To stop a card, use the block tool rather than patching status: it enforces the transition and is reversible.
Authentication
[
{
"patAuth": []
}
]
Request, responses and operation details
{
"summary": "Update card",
"parameters": [
{
"$ref": "#/components/parameters/InstanceId"
},
{
"in": "path",
"name": "id",
"required": true,
"schema": {
"type": "string"
}
}
],
"requestBody": {
"description": "Fields to update (partial)",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/Card"
}
}
}
},
"responses": {
"200": {
"description": "Updated",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/Card"
}
}
}
},
"404": {
"description": "Not found"
}
},
"description": "Partially update card attributes such as limits, linked account or expiry. To stop a card, use the block tool rather than patching status: it enforces the transition and is reversible."
}
DELETE /cards/{id}
Delete card
Permanently delete a card record. Destructive and irreversible — for a lost, stolen or compromised card, block it instead, which is reversible and preserves history.
Authentication
[
{
"patAuth": []
}
]
Request, responses and operation details
{
"summary": "Delete card",
"parameters": [
{
"$ref": "#/components/parameters/InstanceId"
},
{
"in": "path",
"name": "id",
"required": true,
"schema": {
"type": "string"
}
}
],
"responses": {
"200": {
"description": "Deleted",
"content": {
"application/json": {
"schema": {
"type": "object",
"properties": {
"success": {
"type": "boolean"
},
"id": {
"type": "string"
}
}
}
}
}
},
"404": {
"description": "Not found"
}
},
"description": "Permanently delete a card record. Destructive and irreversible — for a lost, stolen or compromised card, block it instead, which is reversible and preserves history."
}
POST /cards/{id}/block
Block a card
Stop a single card by setting its status to 'blocked' — the usual response to lost, stolen or compromised plastic. Narrower than freezing the account: the account and the customer's other cards keep working. Fails with 422 if the card is already blocked or expired. Reversible via unblock.
Authentication
[
{
"patAuth": []
}
]
Request, responses and operation details
{
"summary": "Block a card",
"description": "Stop a single card by setting its status to 'blocked' — the usual response to lost, stolen or compromised plastic. Narrower than freezing the account: the account and the customer's other cards keep working. Fails with 422 if the card is already blocked or expired. Reversible via unblock.",
"parameters": [
{
"$ref": "#/components/parameters/InstanceId"
},
{
"in": "path",
"name": "id",
"required": true,
"schema": {
"type": "string"
}
}
],
"requestBody": {
"content": {
"application/json": {
"schema": {
"type": "object",
"properties": {
"reason": {
"type": "string"
}
}
}
}
}
},
"responses": {
"200": {
"description": "Blocked",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/Card"
}
}
}
},
"404": {
"description": "Not found"
},
"422": {
"description": "Invalid state transition"
}
}
}
POST /cards/{id}/unblock
Unblock a card
Return a blocked card to 'active', e.g. after the customer finds it or a fraud review clears. Fails with 422 if the card is not currently blocked.
Authentication
[
{
"patAuth": []
}
]
Request, responses and operation details
{
"summary": "Unblock a card",
"description": "Return a blocked card to 'active', e.g. after the customer finds it or a fraud review clears. Fails with 422 if the card is not currently blocked.",
"parameters": [
{
"$ref": "#/components/parameters/InstanceId"
},
{
"in": "path",
"name": "id",
"required": true,
"schema": {
"type": "string"
}
}
],
"responses": {
"200": {
"description": "Unblocked",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/Card"
}
}
}
},
"404": {
"description": "Not found"
},
"422": {
"description": "Invalid state transition"
}
}
}
GET /products
List banking products
The bank's retail product catalogue (deposit | lending | card | investment | insurance) with interest rate, min/max amounts, eligibility summary and per-country availability. Catalogue definitions — nothing here is held by a specific customer. Narrow results server-side with this endpoint's named filter params (country, customer_id, status, …) or with OData $filter, $orderby, $select, $search, $top, $skip and $count (MCP clients send those as _filter, _orderby, …) instead of paging through everything.
Authentication
[
{
"patAuth": []
}
]
Request, responses and operation details
{
"summary": "List banking products",
"parameters": [
{
"$ref": "#/components/parameters/InstanceId"
},
{
"in": "query",
"name": "limit",
"schema": {
"type": "integer",
"default": 50
},
"description": "Max items per page (default 50)"
},
{
"in": "query",
"name": "cursor",
"schema": {
"type": "string"
},
"description": "Pass the previous response's nextCursor to fetch the next page"
},
{
"in": "query",
"name": "$filter",
"schema": {
"type": "string"
},
"description": "OData filter expression. Comparison operators: eq, ne, gt, ge, lt, le. Logical: and, or, not, with parentheses for grouping. String functions: contains(field,'x'), startswith(field,'x'), endswith(field,'x'). Membership: field in ('a','b'). Case-insensitive matching via tolower(field) / toupper(field). Nested fields use a slash, e.g. pto_balance/vacation_days. String literals use single quotes; dates are ISO-8601. Examples: \"status eq 'active'\"; \"salary gt 50000 and department eq 'Engineering'\"; \"contains(tolower(name),'acme')\"; \"closeDate gt 2026-01-01\"."
},
{
"in": "query",
"name": "$select",
"schema": {
"type": "string"
},
"description": "Comma-separated list of fields to return, e.g. \"id,firstName,email\". Nested fields via slash (\"pto_balance/vacation_days\"). The id field is always included."
},
{
"in": "query",
"name": "$orderby",
"schema": {
"type": "string"
},
"description": "Sort clause(s), comma-separated, each \"field [asc|desc]\" (asc is the default). Example: \"createdAt desc, lastName asc\". Null values sort last."
},
{
"in": "query",
"name": "$search",
"schema": {
"type": "string"
},
"description": "Free-text, case-insensitive substring match across the resource's searchable fields."
},
{
"in": "query",
"name": "$top",
"schema": {
"type": "integer"
},
"description": "Maximum number of items to return (page size)."
},
{
"in": "query",
"name": "$skip",
"schema": {
"type": "integer"
},
"description": "Number of matching items to skip before returning results (offset paging). Combine with $top."
},
{
"in": "query",
"name": "$count",
"schema": {
"type": "boolean"
},
"description": "When true, include @odata.count (total matches after $filter/$search, before paging) in the response."
},
{
"in": "query",
"name": "country",
"required": false,
"schema": {
"type": "string",
"enum": [
"IN",
"AU",
"US",
"GB",
"KR",
"DE"
]
},
"description": "Filter to a single country (IN | AU | US)"
},
{
"in": "query",
"name": "category",
"required": false,
"schema": {
"type": "string",
"enum": [
"deposit",
"lending",
"card",
"investment",
"insurance"
]
},
"description": "Filter by category"
},
{
"in": "query",
"name": "active",
"required": false,
"schema": {
"type": "string"
},
"description": "Filter by active flag"
}
],
"responses": {
"200": {
"description": "Paginated list",
"content": {
"application/json": {
"schema": {
"type": "object",
"properties": {
"data": {
"type": "array",
"items": {
"$ref": "#/components/schemas/Product"
}
},
"nextCursor": {
"type": "string",
"nullable": true,
"description": "Cursor for the next page, or null on the last page"
},
"total": {
"type": "integer",
"description": "Total documents matching the filter"
}
}
}
}
}
}
},
"description": "The bank's retail product catalogue (deposit | lending | card | investment | insurance) with interest rate, min/max amounts, eligibility summary and per-country availability. Catalogue definitions — nothing here is held by a specific customer. Narrow results server-side with this endpoint's named filter params (country, customer_id, status, …) or with OData $filter, $orderby, $select, $search, $top, $skip and $count (MCP clients send those as _filter, _orderby, …) instead of paging through everything."
}
POST /products
Create banking product
Add a product to the retail banking catalogue. This is not how a customer gets a product: that means opening an account, issuing a card, or booking a loan.
Authentication
[
{
"patAuth": []
}
]
Request, responses and operation details
{
"summary": "Create banking product",
"parameters": [
{
"$ref": "#/components/parameters/InstanceId"
}
],
"requestBody": {
"required": true,
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/Product"
}
}
}
},
"responses": {
"201": {
"description": "Created",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/Product"
}
}
}
}
},
"description": "Add a product to the retail banking catalogue. This is not how a customer gets a product: that means opening an account, issuing a card, or booking a loan."
}
GET /products/{id}
Get banking product
Fetch one catalogue product by id with its rate, amount limits, eligibility summary and country availability — the source for 'what does this product require' answers.
Authentication
[
{
"patAuth": []
}
]
Request, responses and operation details
{
"summary": "Get banking product",
"parameters": [
{
"$ref": "#/components/parameters/InstanceId"
},
{
"in": "path",
"name": "id",
"required": true,
"schema": {
"type": "string"
}
}
],
"responses": {
"200": {
"description": "Found",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/Product"
}
}
}
},
"404": {
"description": "Not found"
}
},
"description": "Fetch one catalogue product by id with its rate, amount limits, eligibility summary and country availability — the source for 'what does this product require' answers."
}
PATCH /products/{id}
Update banking product
Update a catalogue product's commercial terms — rate, limits, eligibility text — or clear its active flag when the product is withdrawn.
Authentication
[
{
"patAuth": []
}
]
Request, responses and operation details
{
"summary": "Update banking product",
"parameters": [
{
"$ref": "#/components/parameters/InstanceId"
},
{
"in": "path",
"name": "id",
"required": true,
"schema": {
"type": "string"
}
}
],
"requestBody": {
"description": "Fields to update (partial)",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/Product"
}
}
}
},
"responses": {
"200": {
"description": "Updated",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/Product"
}
}
}
},
"404": {
"description": "Not found"
}
},
"description": "Update a catalogue product's commercial terms — rate, limits, eligibility text — or clear its active flag when the product is withdrawn."
}
DELETE /products/{id}
Delete banking product
Permanently delete a product from the catalogue. Destructive — if customers hold it, set active=false instead so existing accounts and loans still resolve.
Authentication
[
{
"patAuth": []
}
]
Request, responses and operation details
{
"summary": "Delete banking product",
"parameters": [
{
"$ref": "#/components/parameters/InstanceId"
},
{
"in": "path",
"name": "id",
"required": true,
"schema": {
"type": "string"
}
}
],
"responses": {
"200": {
"description": "Deleted",
"content": {
"application/json": {
"schema": {
"type": "object",
"properties": {
"success": {
"type": "boolean"
},
"id": {
"type": "string"
}
}
}
}
}
},
"404": {
"description": "Not found"
}
},
"description": "Permanently delete a product from the catalogue. Destructive — if customers hold it, set active=false instead so existing accounts and loans still resolve."
}
GET /loans
List loans
Disbursed loans held by Purple Retail Banking customers, with principal and outstanding money, EMI, status (active | delinquent | closed | written_off), days past due and delinquency bucket. These are funded loans; applications still in origination are loan applications. Narrow results server-side with this endpoint's named filter params (country, customer_id, status, …) or with OData $filter, $orderby, $select, $search, $top, $skip and $count (MCP clients send those as _filter, _orderby, …) instead of paging through everything.
Authentication
[
{
"patAuth": []
}
]
Request, responses and operation details
{
"summary": "List loans",
"parameters": [
{
"$ref": "#/components/parameters/InstanceId"
},
{
"in": "query",
"name": "limit",
"schema": {
"type": "integer",
"default": 50
},
"description": "Max items per page (default 50)"
},
{
"in": "query",
"name": "cursor",
"schema": {
"type": "string"
},
"description": "Pass the previous response's nextCursor to fetch the next page"
},
{
"in": "query",
"name": "$filter",
"schema": {
"type": "string"
},
"description": "OData filter expression. Comparison operators: eq, ne, gt, ge, lt, le. Logical: and, or, not, with parentheses for grouping. String functions: contains(field,'x'), startswith(field,'x'), endswith(field,'x'). Membership: field in ('a','b'). Case-insensitive matching via tolower(field) / toupper(field). Nested fields use a slash, e.g. pto_balance/vacation_days. String literals use single quotes; dates are ISO-8601. Examples: \"status eq 'active'\"; \"salary gt 50000 and department eq 'Engineering'\"; \"contains(tolower(name),'acme')\"; \"closeDate gt 2026-01-01\"."
},
{
"in": "query",
"name": "$select",
"schema": {
"type": "string"
},
"description": "Comma-separated list of fields to return, e.g. \"id,firstName,email\". Nested fields via slash (\"pto_balance/vacation_days\"). The id field is always included."
},
{
"in": "query",
"name": "$orderby",
"schema": {
"type": "string"
},
"description": "Sort clause(s), comma-separated, each \"field [asc|desc]\" (asc is the default). Example: \"createdAt desc, lastName asc\". Null values sort last."
},
{
"in": "query",
"name": "$search",
"schema": {
"type": "string"
},
"description": "Free-text, case-insensitive substring match across the resource's searchable fields."
},
{
"in": "query",
"name": "$top",
"schema": {
"type": "integer"
},
"description": "Maximum number of items to return (page size)."
},
{
"in": "query",
"name": "$skip",
"schema": {
"type": "integer"
},
"description": "Number of matching items to skip before returning results (offset paging). Combine with $top."
},
{
"in": "query",
"name": "$count",
"schema": {
"type": "boolean"
},
"description": "When true, include @odata.count (total matches after $filter/$search, before paging) in the response."
},
{
"in": "query",
"name": "country",
"required": false,
"schema": {
"type": "string",
"enum": [
"IN",
"AU",
"US",
"GB",
"KR",
"DE"
]
},
"description": "Filter to a single country (IN | AU | US)"
},
{
"in": "query",
"name": "customer_id",
"required": false,
"schema": {
"type": "string"
},
"description": "Filter by customer id"
},
{
"in": "query",
"name": "status",
"required": false,
"schema": {
"type": "string",
"enum": [
"active",
"delinquent",
"closed",
"written_off"
]
},
"description": "Filter by status"
},
{
"in": "query",
"name": "delinquency_bucket",
"required": false,
"schema": {
"type": "string",
"enum": [
"current",
"1-30",
"31-60",
"61-90",
"90+"
]
},
"description": "Filter by delinquency bucket"
}
],
"responses": {
"200": {
"description": "Paginated list",
"content": {
"application/json": {
"schema": {
"type": "object",
"properties": {
"data": {
"type": "array",
"items": {
"$ref": "#/components/schemas/Loan"
}
},
"nextCursor": {
"type": "string",
"nullable": true,
"description": "Cursor for the next page, or null on the last page"
},
"total": {
"type": "integer",
"description": "Total documents matching the filter"
}
}
}
}
}
}
},
"description": "Disbursed loans held by Purple Retail Banking customers, with principal and outstanding money, EMI, status (active | delinquent | closed | written_off), days past due and delinquency bucket. These are funded loans; applications still in origination are loan applications. Narrow results server-side with this endpoint's named filter params (country, customer_id, status, …) or with OData $filter, $orderby, $select, $search, $top, $skip and $count (MCP clients send those as _filter, _orderby, …) instead of paging through everything."
}
POST /loans
Create loan
Book a loan record for a customer. In the normal flow a loan comes into existence by disbursing an approved loan application, so check that pipeline before creating one directly.
Authentication
[
{
"patAuth": []
}
]
Request, responses and operation details
{
"summary": "Create loan",
"parameters": [
{
"$ref": "#/components/parameters/InstanceId"
}
],
"requestBody": {
"required": true,
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/Loan"
}
}
}
},
"responses": {
"201": {
"description": "Created",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/Loan"
}
}
}
}
},
"description": "Book a loan record for a customer. In the normal flow a loan comes into existence by disbursing an approved loan application, so check that pipeline before creating one directly."
}
GET /loans/{id}
Get loan
Fetch one loan by id with its outstanding balance, EMI, dpd and delinquency bucket — the record behind payoff, arrears and collections questions.
Authentication
[
{
"patAuth": []
}
]
Request, responses and operation details
{
"summary": "Get loan",
"parameters": [
{
"$ref": "#/components/parameters/InstanceId"
},
{
"in": "path",
"name": "id",
"required": true,
"schema": {
"type": "string"
}
}
],
"responses": {
"200": {
"description": "Found",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/Loan"
}
}
}
},
"404": {
"description": "Not found"
}
},
"description": "Fetch one loan by id with its outstanding balance, EMI, dpd and delinquency bucket — the record behind payoff, arrears and collections questions."
}
PATCH /loans/{id}
Update loan
Partially update a loan — record repayment progress, refresh dpd and delinquency bucket, or change status as it cures or deteriorates.
Authentication
[
{
"patAuth": []
}
]
Request, responses and operation details
{
"summary": "Update loan",
"parameters": [
{
"$ref": "#/components/parameters/InstanceId"
},
{
"in": "path",
"name": "id",
"required": true,
"schema": {
"type": "string"
}
}
],
"requestBody": {
"description": "Fields to update (partial)",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/Loan"
}
}
}
},
"responses": {
"200": {
"description": "Updated",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/Loan"
}
}
}
},
"404": {
"description": "Not found"
}
},
"description": "Partially update a loan — record repayment progress, refresh dpd and delinquency bucket, or change status as it cures or deteriorates."
}
DELETE /loans/{id}
Delete loan
Permanently delete a loan record. Destructive and irreversible — a settled loan should be status 'closed' and an unrecoverable one 'written_off' so the credit history survives.
Authentication
[
{
"patAuth": []
}
]
Request, responses and operation details
{
"summary": "Delete loan",
"parameters": [
{
"$ref": "#/components/parameters/InstanceId"
},
{
"in": "path",
"name": "id",
"required": true,
"schema": {
"type": "string"
}
}
],
"responses": {
"200": {
"description": "Deleted",
"content": {
"application/json": {
"schema": {
"type": "object",
"properties": {
"success": {
"type": "boolean"
},
"id": {
"type": "string"
}
}
}
}
}
},
"404": {
"description": "Not found"
}
},
"description": "Permanently delete a loan record. Destructive and irreversible — a settled loan should be status 'closed' and an unrecoverable one 'written_off' so the credit history survives."
}
GET /loan_applications
List loan applications
Loan applications in origination, moving through submitted → docs_pending → eligibility → underwriting → approved → disbursed (or rejected), with requested amount, eligibility score and a required-document checklist. Nothing here is money lent yet — that is loans. Narrow results server-side with this endpoint's named filter params (country, customer_id, status, …) or with OData $filter, $orderby, $select, $search, $top, $skip and $count (MCP clients send those as _filter, _orderby, …) instead of paging through everything.
Authentication
[
{
"patAuth": []
}
]
Request, responses and operation details
{
"summary": "List loan applications",
"parameters": [
{
"$ref": "#/components/parameters/InstanceId"
},
{
"in": "query",
"name": "limit",
"schema": {
"type": "integer",
"default": 50
},
"description": "Max items per page (default 50)"
},
{
"in": "query",
"name": "cursor",
"schema": {
"type": "string"
},
"description": "Pass the previous response's nextCursor to fetch the next page"
},
{
"in": "query",
"name": "$filter",
"schema": {
"type": "string"
},
"description": "OData filter expression. Comparison operators: eq, ne, gt, ge, lt, le. Logical: and, or, not, with parentheses for grouping. String functions: contains(field,'x'), startswith(field,'x'), endswith(field,'x'). Membership: field in ('a','b'). Case-insensitive matching via tolower(field) / toupper(field). Nested fields use a slash, e.g. pto_balance/vacation_days. String literals use single quotes; dates are ISO-8601. Examples: \"status eq 'active'\"; \"salary gt 50000 and department eq 'Engineering'\"; \"contains(tolower(name),'acme')\"; \"closeDate gt 2026-01-01\"."
},
{
"in": "query",
"name": "$select",
"schema": {
"type": "string"
},
"description": "Comma-separated list of fields to return, e.g. \"id,firstName,email\". Nested fields via slash (\"pto_balance/vacation_days\"). The id field is always included."
},
{
"in": "query",
"name": "$orderby",
"schema": {
"type": "string"
},
"description": "Sort clause(s), comma-separated, each \"field [asc|desc]\" (asc is the default). Example: \"createdAt desc, lastName asc\". Null values sort last."
},
{
"in": "query",
"name": "$search",
"schema": {
"type": "string"
},
"description": "Free-text, case-insensitive substring match across the resource's searchable fields."
},
{
"in": "query",
"name": "$top",
"schema": {
"type": "integer"
},
"description": "Maximum number of items to return (page size)."
},
{
"in": "query",
"name": "$skip",
"schema": {
"type": "integer"
},
"description": "Number of matching items to skip before returning results (offset paging). Combine with $top."
},
{
"in": "query",
"name": "$count",
"schema": {
"type": "boolean"
},
"description": "When true, include @odata.count (total matches after $filter/$search, before paging) in the response."
},
{
"in": "query",
"name": "country",
"required": false,
"schema": {
"type": "string",
"enum": [
"IN",
"AU",
"US",
"GB",
"KR",
"DE"
]
},
"description": "Filter to a single country (IN | AU | US)"
},
{
"in": "query",
"name": "customer_id",
"required": false,
"schema": {
"type": "string"
},
"description": "Filter by customer id"
},
{
"in": "query",
"name": "stage",
"required": false,
"schema": {
"type": "string",
"enum": [
"submitted",
"docs_pending",
"eligibility",
"underwriting",
"approved",
"rejected",
"disbursed"
]
},
"description": "Filter by stage"
}
],
"responses": {
"200": {
"description": "Paginated list",
"content": {
"application/json": {
"schema": {
"type": "object",
"properties": {
"data": {
"type": "array",
"items": {
"$ref": "#/components/schemas/LoanApplication"
}
},
"nextCursor": {
"type": "string",
"nullable": true,
"description": "Cursor for the next page, or null on the last page"
},
"total": {
"type": "integer",
"description": "Total documents matching the filter"
}
}
}
}
}
}
},
"description": "Loan applications in origination, moving through submitted → docs_pending → eligibility → underwriting → approved → disbursed (or rejected), with requested amount, eligibility score and a required-document checklist. Nothing here is money lent yet — that is loans. Narrow results server-side with this endpoint's named filter params (country, customer_id, status, …) or with OData $filter, $orderby, $select, $search, $top, $skip and $count (MCP clients send those as _filter, _orderby, …) instead of paging through everything."
}
POST /loan_applications
Submit loan application
Submit a new loan application for a customer against a lending product. It enters at the start of the pipeline; move it forward with the transition tool rather than by creating further applications.
Authentication
[
{
"patAuth": []
}
]
Request, responses and operation details
{
"summary": "Submit loan application",
"parameters": [
{
"$ref": "#/components/parameters/InstanceId"
}
],
"requestBody": {
"required": true,
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/LoanApplication"
}
}
}
},
"responses": {
"201": {
"description": "Created",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/LoanApplication"
}
}
}
}
},
"description": "Submit a new loan application for a customer against a lending product. It enters at the start of the pipeline; move it forward with the transition tool rather than by creating further applications."
}
GET /loan_applications/{id}
Get loan application
Fetch one loan application by id with its current stage, eligibility score and per-document status — the check to run before advancing it or chasing paperwork.
Authentication
[
{
"patAuth": []
}
]
Request, responses and operation details
{
"summary": "Get loan application",
"parameters": [
{
"$ref": "#/components/parameters/InstanceId"
},
{
"in": "path",
"name": "id",
"required": true,
"schema": {
"type": "string"
}
}
],
"responses": {
"200": {
"description": "Found",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/LoanApplication"
}
}
}
},
"404": {
"description": "Not found"
}
},
"description": "Fetch one loan application by id with its current stage, eligibility score and per-document status — the check to run before advancing it or chasing paperwork."
}
PATCH /loan_applications/{id}
Update loan application
Partially update application details such as requested amount, product or assigned underwriter. Do not set the stage field here: the transition tool enforces the pipeline, and document status has its own tool.
Authentication
[
{
"patAuth": []
}
]
Request, responses and operation details
{
"summary": "Update loan application",
"parameters": [
{
"$ref": "#/components/parameters/InstanceId"
},
{
"in": "path",
"name": "id",
"required": true,
"schema": {
"type": "string"
}
}
],
"requestBody": {
"description": "Fields to update (partial)",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/LoanApplication"
}
}
}
},
"responses": {
"200": {
"description": "Updated",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/LoanApplication"
}
}
}
},
"404": {
"description": "Not found"
}
},
"description": "Partially update application details such as requested amount, product or assigned underwriter. Do not set the stage field here: the transition tool enforces the pipeline, and document status has its own tool."
}
DELETE /loan_applications/{id}
Delete loan application
Permanently delete a loan application. Destructive and irreversible — a declined case should be transitioned to 'rejected' so the decision and its reason survive.
Authentication
[
{
"patAuth": []
}
]
Request, responses and operation details
{
"summary": "Delete loan application",
"parameters": [
{
"$ref": "#/components/parameters/InstanceId"
},
{
"in": "path",
"name": "id",
"required": true,
"schema": {
"type": "string"
}
}
],
"responses": {
"200": {
"description": "Deleted",
"content": {
"application/json": {
"schema": {
"type": "object",
"properties": {
"success": {
"type": "boolean"
},
"id": {
"type": "string"
}
}
}
}
}
},
"404": {
"description": "Not found"
}
},
"description": "Permanently delete a loan application. Destructive and irreversible — a declined case should be transitioned to 'rejected' so the decision and its reason survive."
}
POST /loan_applications/{id}/documents
Set loan application document status
Mark one required document on a loan application as missing, received or verified, adding it to the checklist if it is not already listed. This is the paperwork step that clears the docs_pending stage; it does not itself advance the application — use the transition tool for that.
Authentication
[
{
"patAuth": []
}
]
Request, responses and operation details
{
"summary": "Set loan application document status",
"description": "Mark one required document on a loan application as missing, received or verified, adding it to the checklist if it is not already listed. This is the paperwork step that clears the docs_pending stage; it does not itself advance the application — use the transition tool for that.",
"parameters": [
{
"$ref": "#/components/parameters/InstanceId"
},
{
"in": "path",
"name": "id",
"required": true,
"schema": {
"type": "string"
}
}
],
"requestBody": {
"required": true,
"content": {
"application/json": {
"schema": {
"type": "object",
"properties": {
"doc_type": {
"type": "string",
"example": "income_proof"
},
"status": {
"type": "string",
"enum": [
"missing",
"received",
"verified"
]
}
},
"required": [
"doc_type",
"status"
]
}
}
}
},
"responses": {
"200": {
"description": "Updated",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/LoanApplication"
}
}
}
},
"400": {
"description": "Invalid body"
},
"404": {
"description": "Not found"
}
}
}
POST /loan_applications/{id}/transition
Advance a loan application
Move a loan application along the origination pipeline: submitted → docs_pending → eligibility → underwriting → approved → disbursed, with 'rejected' allowed from any pre-decision stage. Use this rather than patching the stage field: skipping or reversing stages is rejected with 422, and 'rejected' and 'disbursed' are terminal credit decisions that cannot be undone.
Authentication
[
{
"patAuth": []
}
]
Request, responses and operation details
{
"summary": "Advance a loan application",
"description": "Move a loan application along the origination pipeline: submitted → docs_pending → eligibility → underwriting → approved → disbursed, with 'rejected' allowed from any pre-decision stage. Use this rather than patching the stage field: skipping or reversing stages is rejected with 422, and 'rejected' and 'disbursed' are terminal credit decisions that cannot be undone.",
"parameters": [
{
"$ref": "#/components/parameters/InstanceId"
},
{
"in": "path",
"name": "id",
"required": true,
"schema": {
"type": "string"
}
}
],
"requestBody": {
"required": true,
"content": {
"application/json": {
"schema": {
"type": "object",
"properties": {
"stage": {
"type": "string",
"enum": [
"submitted",
"docs_pending",
"eligibility",
"underwriting",
"approved",
"rejected",
"disbursed"
]
},
"reason": {
"type": "string"
}
},
"required": [
"stage"
]
}
}
}
},
"responses": {
"200": {
"description": "Updated",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/LoanApplication"
}
}
}
},
"400": {
"description": "Invalid stage"
},
"404": {
"description": "Not found"
},
"422": {
"description": "Invalid state transition"
}
}
}
GET /interactions
List customer interactions
Servicing touchpoints logged with a banking customer — calls, meetings, notes and branch visits — with subject, channel and who handled it. Relationship history inside the bank; distinct from CRM activities (B2B sales) and from complaints. Narrow results server-side with this endpoint's named filter params (country, customer_id, status, …) or with OData $filter, $orderby, $select, $search, $top, $skip and $count (MCP clients send those as _filter, _orderby, …) instead of paging through everything.
Authentication
[
{
"patAuth": []
}
]
Request, responses and operation details
{
"summary": "List customer interactions",
"parameters": [
{
"$ref": "#/components/parameters/InstanceId"
},
{
"in": "query",
"name": "limit",
"schema": {
"type": "integer",
"default": 50
},
"description": "Max items per page (default 50)"
},
{
"in": "query",
"name": "cursor",
"schema": {
"type": "string"
},
"description": "Pass the previous response's nextCursor to fetch the next page"
},
{
"in": "query",
"name": "$filter",
"schema": {
"type": "string"
},
"description": "OData filter expression. Comparison operators: eq, ne, gt, ge, lt, le. Logical: and, or, not, with parentheses for grouping. String functions: contains(field,'x'), startswith(field,'x'), endswith(field,'x'). Membership: field in ('a','b'). Case-insensitive matching via tolower(field) / toupper(field). Nested fields use a slash, e.g. pto_balance/vacation_days. String literals use single quotes; dates are ISO-8601. Examples: \"status eq 'active'\"; \"salary gt 50000 and department eq 'Engineering'\"; \"contains(tolower(name),'acme')\"; \"closeDate gt 2026-01-01\"."
},
{
"in": "query",
"name": "$select",
"schema": {
"type": "string"
},
"description": "Comma-separated list of fields to return, e.g. \"id,firstName,email\". Nested fields via slash (\"pto_balance/vacation_days\"). The id field is always included."
},
{
"in": "query",
"name": "$orderby",
"schema": {
"type": "string"
},
"description": "Sort clause(s), comma-separated, each \"field [asc|desc]\" (asc is the default). Example: \"createdAt desc, lastName asc\". Null values sort last."
},
{
"in": "query",
"name": "$search",
"schema": {
"type": "string"
},
"description": "Free-text, case-insensitive substring match across the resource's searchable fields."
},
{
"in": "query",
"name": "$top",
"schema": {
"type": "integer"
},
"description": "Maximum number of items to return (page size)."
},
{
"in": "query",
"name": "$skip",
"schema": {
"type": "integer"
},
"description": "Number of matching items to skip before returning results (offset paging). Combine with $top."
},
{
"in": "query",
"name": "$count",
"schema": {
"type": "boolean"
},
"description": "When true, include @odata.count (total matches after $filter/$search, before paging) in the response."
},
{
"in": "query",
"name": "country",
"required": false,
"schema": {
"type": "string",
"enum": [
"IN",
"AU",
"US",
"GB",
"KR",
"DE"
]
},
"description": "Filter to a single country (IN | AU | US)"
},
{
"in": "query",
"name": "customer_id",
"required": false,
"schema": {
"type": "string"
},
"description": "Filter by customer id"
},
{
"in": "query",
"name": "type",
"required": false,
"schema": {
"type": "string",
"enum": [
"call",
"meeting",
"note",
"visit"
]
},
"description": "Filter by type"
}
],
"responses": {
"200": {
"description": "Paginated list",
"content": {
"application/json": {
"schema": {
"type": "object",
"properties": {
"data": {
"type": "array",
"items": {
"$ref": "#/components/schemas/Interaction"
}
},
"nextCursor": {
"type": "string",
"nullable": true,
"description": "Cursor for the next page, or null on the last page"
},
"total": {
"type": "integer",
"description": "Total documents matching the filter"
}
}
}
}
}
}
},
"description": "Servicing touchpoints logged with a banking customer — calls, meetings, notes and branch visits — with subject, channel and who handled it. Relationship history inside the bank; distinct from CRM activities (B2B sales) and from complaints. Narrow results server-side with this endpoint's named filter params (country, customer_id, status, …) or with OData $filter, $orderby, $select, $search, $top, $skip and $count (MCP clients send those as _filter, _orderby, …) instead of paging through everything."
}
POST /interactions
Log customer interaction
Log a servicing touchpoint (call, meeting, note or visit) against a banking customer. Use this for a contact record; if the customer is raising a grievance, log a complaint instead.
Authentication
[
{
"patAuth": []
}
]
Request, responses and operation details
{
"summary": "Log customer interaction",
"parameters": [
{
"$ref": "#/components/parameters/InstanceId"
}
],
"requestBody": {
"required": true,
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/Interaction"
}
}
}
},
"responses": {
"201": {
"description": "Created",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/Interaction"
}
}
}
}
},
"description": "Log a servicing touchpoint (call, meeting, note or visit) against a banking customer. Use this for a contact record; if the customer is raising a grievance, log a complaint instead."
}
GET /interactions/{id}
Get customer interaction
Fetch one logged interaction by id with its type, subject, notes, handler and timestamp.
Authentication
[
{
"patAuth": []
}
]
Request, responses and operation details
{
"summary": "Get customer interaction",
"parameters": [
{
"$ref": "#/components/parameters/InstanceId"
},
{
"in": "path",
"name": "id",
"required": true,
"schema": {
"type": "string"
}
}
],
"responses": {
"200": {
"description": "Found",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/Interaction"
}
}
}
},
"404": {
"description": "Not found"
}
},
"description": "Fetch one logged interaction by id with its type, subject, notes, handler and timestamp."
}
PATCH /interactions/{id}
Update customer interaction
Correct or extend a logged interaction — its subject, notes or outcome.
Authentication
[
{
"patAuth": []
}
]
Request, responses and operation details
{
"summary": "Update customer interaction",
"parameters": [
{
"$ref": "#/components/parameters/InstanceId"
},
{
"in": "path",
"name": "id",
"required": true,
"schema": {
"type": "string"
}
}
],
"requestBody": {
"description": "Fields to update (partial)",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/Interaction"
}
}
}
},
"responses": {
"200": {
"description": "Updated",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/Interaction"
}
}
}
},
"404": {
"description": "Not found"
}
},
"description": "Correct or extend a logged interaction — its subject, notes or outcome."
}
DELETE /interactions/{id}
Delete customer interaction
Permanently delete a logged interaction, removing it from the customer's contact history. Destructive and irreversible.
Authentication
[
{
"patAuth": []
}
]
Request, responses and operation details
{
"summary": "Delete customer interaction",
"parameters": [
{
"$ref": "#/components/parameters/InstanceId"
},
{
"in": "path",
"name": "id",
"required": true,
"schema": {
"type": "string"
}
}
],
"responses": {
"200": {
"description": "Deleted",
"content": {
"application/json": {
"schema": {
"type": "object",
"properties": {
"success": {
"type": "boolean"
},
"id": {
"type": "string"
}
}
}
}
}
},
"404": {
"description": "Not found"
}
},
"description": "Permanently delete a logged interaction, removing it from the customer's contact history. Destructive and irreversible."
}
GET /bank_opportunities
List banking opportunities
Next-best-action product opportunities identified for a banking customer (deposit | lending | card | investment | insurance) with expected value, stage and a recommendation reason. Retail cross-sell prompts for a relationship manager, not CRM sales opportunities (B2B deals). Narrow results server-side with this endpoint's named filter params (country, customer_id, status, …) or with OData $filter, $orderby, $select, $search, $top, $skip and $count (MCP clients send those as _filter, _orderby, …) instead of paging through everything.
Authentication
[
{
"patAuth": []
}
]
Request, responses and operation details
{
"summary": "List banking opportunities",
"parameters": [
{
"$ref": "#/components/parameters/InstanceId"
},
{
"in": "query",
"name": "limit",
"schema": {
"type": "integer",
"default": 50
},
"description": "Max items per page (default 50)"
},
{
"in": "query",
"name": "cursor",
"schema": {
"type": "string"
},
"description": "Pass the previous response's nextCursor to fetch the next page"
},
{
"in": "query",
"name": "$filter",
"schema": {
"type": "string"
},
"description": "OData filter expression. Comparison operators: eq, ne, gt, ge, lt, le. Logical: and, or, not, with parentheses for grouping. String functions: contains(field,'x'), startswith(field,'x'), endswith(field,'x'). Membership: field in ('a','b'). Case-insensitive matching via tolower(field) / toupper(field). Nested fields use a slash, e.g. pto_balance/vacation_days. String literals use single quotes; dates are ISO-8601. Examples: \"status eq 'active'\"; \"salary gt 50000 and department eq 'Engineering'\"; \"contains(tolower(name),'acme')\"; \"closeDate gt 2026-01-01\"."
},
{
"in": "query",
"name": "$select",
"schema": {
"type": "string"
},
"description": "Comma-separated list of fields to return, e.g. \"id,firstName,email\". Nested fields via slash (\"pto_balance/vacation_days\"). The id field is always included."
},
{
"in": "query",
"name": "$orderby",
"schema": {
"type": "string"
},
"description": "Sort clause(s), comma-separated, each \"field [asc|desc]\" (asc is the default). Example: \"createdAt desc, lastName asc\". Null values sort last."
},
{
"in": "query",
"name": "$search",
"schema": {
"type": "string"
},
"description": "Free-text, case-insensitive substring match across the resource's searchable fields."
},
{
"in": "query",
"name": "$top",
"schema": {
"type": "integer"
},
"description": "Maximum number of items to return (page size)."
},
{
"in": "query",
"name": "$skip",
"schema": {
"type": "integer"
},
"description": "Number of matching items to skip before returning results (offset paging). Combine with $top."
},
{
"in": "query",
"name": "$count",
"schema": {
"type": "boolean"
},
"description": "When true, include @odata.count (total matches after $filter/$search, before paging) in the response."
},
{
"in": "query",
"name": "country",
"required": false,
"schema": {
"type": "string",
"enum": [
"IN",
"AU",
"US",
"GB",
"KR",
"DE"
]
},
"description": "Filter to a single country (IN | AU | US)"
},
{
"in": "query",
"name": "customer_id",
"required": false,
"schema": {
"type": "string"
},
"description": "Filter by customer id"
},
{
"in": "query",
"name": "product_category",
"required": false,
"schema": {
"type": "string",
"enum": [
"deposit",
"lending",
"card",
"investment",
"insurance"
]
},
"description": "Filter by product category"
},
{
"in": "query",
"name": "stage",
"required": false,
"schema": {
"type": "string",
"enum": [
"identified",
"proposed",
"accepted",
"declined"
]
},
"description": "Filter by stage"
}
],
"responses": {
"200": {
"description": "Paginated list",
"content": {
"application/json": {
"schema": {
"type": "object",
"properties": {
"data": {
"type": "array",
"items": {
"$ref": "#/components/schemas/Opportunity"
}
},
"nextCursor": {
"type": "string",
"nullable": true,
"description": "Cursor for the next page, or null on the last page"
},
"total": {
"type": "integer",
"description": "Total documents matching the filter"
}
}
}
}
}
}
},
"description": "Next-best-action product opportunities identified for a banking customer (deposit | lending | card | investment | insurance) with expected value, stage and a recommendation reason. Retail cross-sell prompts for a relationship manager, not CRM sales opportunities (B2B deals). Narrow results server-side with this endpoint's named filter params (country, customer_id, status, …) or with OData $filter, $orderby, $select, $search, $top, $skip and $count (MCP clients send those as _filter, _orderby, …) instead of paging through everything."
}
POST /bank_opportunities
Create banking opportunity
Record a next-best-action product opportunity for a banking customer, with the product category, expected value and why it is being recommended.
Authentication
[
{
"patAuth": []
}
]
Request, responses and operation details
{
"summary": "Create banking opportunity",
"parameters": [
{
"$ref": "#/components/parameters/InstanceId"
}
],
"requestBody": {
"required": true,
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/Opportunity"
}
}
}
},
"responses": {
"201": {
"description": "Created",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/Opportunity"
}
}
}
}
},
"description": "Record a next-best-action product opportunity for a banking customer, with the product category, expected value and why it is being recommended."
}
GET /bank_opportunities/{id}
Get banking opportunity
Fetch one banking opportunity by id with its product category, value, stage and recommendation reason.
Authentication
[
{
"patAuth": []
}
]
Request, responses and operation details
{
"summary": "Get banking opportunity",
"parameters": [
{
"$ref": "#/components/parameters/InstanceId"
},
{
"in": "path",
"name": "id",
"required": true,
"schema": {
"type": "string"
}
}
],
"responses": {
"200": {
"description": "Found",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/Opportunity"
}
}
}
},
"404": {
"description": "Not found"
}
},
"description": "Fetch one banking opportunity by id with its product category, value, stage and recommendation reason."
}
PATCH /bank_opportunities/{id}
Update banking opportunity
Move an opportunity along identified → proposed → accepted | declined, or revise its value and reasoning.
Authentication
[
{
"patAuth": []
}
]
Request, responses and operation details
{
"summary": "Update banking opportunity",
"parameters": [
{
"$ref": "#/components/parameters/InstanceId"
},
{
"in": "path",
"name": "id",
"required": true,
"schema": {
"type": "string"
}
}
],
"requestBody": {
"description": "Fields to update (partial)",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/Opportunity"
}
}
}
},
"responses": {
"200": {
"description": "Updated",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/Opportunity"
}
}
}
},
"404": {
"description": "Not found"
}
},
"description": "Move an opportunity along identified → proposed → accepted | declined, or revise its value and reasoning."
}
DELETE /bank_opportunities/{id}
Delete banking opportunity
Permanently delete a banking opportunity. Destructive — when a customer says no, set the stage to 'declined' instead so the outcome is retained.
Authentication
[
{
"patAuth": []
}
]
Request, responses and operation details
{
"summary": "Delete banking opportunity",
"parameters": [
{
"$ref": "#/components/parameters/InstanceId"
},
{
"in": "path",
"name": "id",
"required": true,
"schema": {
"type": "string"
}
}
],
"responses": {
"200": {
"description": "Deleted",
"content": {
"application/json": {
"schema": {
"type": "object",
"properties": {
"success": {
"type": "boolean"
},
"id": {
"type": "string"
}
}
}
}
}
},
"404": {
"description": "Not found"
}
},
"description": "Permanently delete a banking opportunity. Destructive — when a customer says no, set the stage to 'declined' instead so the outcome is retained."
}
GET /complaints
List customer complaints
Grievances customers have raised against the bank (payments, cards, loans, accounts, atm, digital), each with status logged | investigating | resolved | closed and an SLA clock. Regulated banking complaints, not IT incidents and not fraud cases. Narrow results server-side with this endpoint's named filter params (country, customer_id, status, …) or with OData $filter, $orderby, $select, $search, $top, $skip and $count (MCP clients send those as _filter, _orderby, …) instead of paging through everything.
Authentication
[
{
"patAuth": []
}
]
Request, responses and operation details
{
"summary": "List customer complaints",
"parameters": [
{
"$ref": "#/components/parameters/InstanceId"
},
{
"in": "query",
"name": "limit",
"schema": {
"type": "integer",
"default": 50
},
"description": "Max items per page (default 50)"
},
{
"in": "query",
"name": "cursor",
"schema": {
"type": "string"
},
"description": "Pass the previous response's nextCursor to fetch the next page"
},
{
"in": "query",
"name": "$filter",
"schema": {
"type": "string"
},
"description": "OData filter expression. Comparison operators: eq, ne, gt, ge, lt, le. Logical: and, or, not, with parentheses for grouping. String functions: contains(field,'x'), startswith(field,'x'), endswith(field,'x'). Membership: field in ('a','b'). Case-insensitive matching via tolower(field) / toupper(field). Nested fields use a slash, e.g. pto_balance/vacation_days. String literals use single quotes; dates are ISO-8601. Examples: \"status eq 'active'\"; \"salary gt 50000 and department eq 'Engineering'\"; \"contains(tolower(name),'acme')\"; \"closeDate gt 2026-01-01\"."
},
{
"in": "query",
"name": "$select",
"schema": {
"type": "string"
},
"description": "Comma-separated list of fields to return, e.g. \"id,firstName,email\". Nested fields via slash (\"pto_balance/vacation_days\"). The id field is always included."
},
{
"in": "query",
"name": "$orderby",
"schema": {
"type": "string"
},
"description": "Sort clause(s), comma-separated, each \"field [asc|desc]\" (asc is the default). Example: \"createdAt desc, lastName asc\". Null values sort last."
},
{
"in": "query",
"name": "$search",
"schema": {
"type": "string"
},
"description": "Free-text, case-insensitive substring match across the resource's searchable fields."
},
{
"in": "query",
"name": "$top",
"schema": {
"type": "integer"
},
"description": "Maximum number of items to return (page size)."
},
{
"in": "query",
"name": "$skip",
"schema": {
"type": "integer"
},
"description": "Number of matching items to skip before returning results (offset paging). Combine with $top."
},
{
"in": "query",
"name": "$count",
"schema": {
"type": "boolean"
},
"description": "When true, include @odata.count (total matches after $filter/$search, before paging) in the response."
},
{
"in": "query",
"name": "country",
"required": false,
"schema": {
"type": "string",
"enum": [
"IN",
"AU",
"US",
"GB",
"KR",
"DE"
]
},
"description": "Filter to a single country (IN | AU | US)"
},
{
"in": "query",
"name": "customer_id",
"required": false,
"schema": {
"type": "string"
},
"description": "Filter by customer id"
},
{
"in": "query",
"name": "category",
"required": false,
"schema": {
"type": "string",
"enum": [
"payments",
"cards",
"loans",
"accounts",
"atm",
"digital"
]
},
"description": "Filter by category"
},
{
"in": "query",
"name": "status",
"required": false,
"schema": {
"type": "string",
"enum": [
"logged",
"investigating",
"resolved",
"closed"
]
},
"description": "Filter by status"
}
],
"responses": {
"200": {
"description": "Paginated list",
"content": {
"application/json": {
"schema": {
"type": "object",
"properties": {
"data": {
"type": "array",
"items": {
"$ref": "#/components/schemas/Complaint"
}
},
"nextCursor": {
"type": "string",
"nullable": true,
"description": "Cursor for the next page, or null on the last page"
},
"total": {
"type": "integer",
"description": "Total documents matching the filter"
}
}
}
}
}
}
},
"description": "Grievances customers have raised against the bank (payments, cards, loans, accounts, atm, digital), each with status logged | investigating | resolved | closed and an SLA clock. Regulated banking complaints, not IT incidents and not fraud cases. Narrow results server-side with this endpoint's named filter params (country, customer_id, status, …) or with OData $filter, $orderby, $select, $search, $top, $skip and $count (MCP clients send those as _filter, _orderby, …) instead of paging through everything."
}
POST /complaints
Log customer complaint
Log a new complaint a customer has raised against the bank, with category and description. It starts at 'logged'; move it on with the transition tool.
Authentication
[
{
"patAuth": []
}
]
Request, responses and operation details
{
"summary": "Log customer complaint",
"parameters": [
{
"$ref": "#/components/parameters/InstanceId"
}
],
"requestBody": {
"required": true,
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/Complaint"
}
}
}
},
"responses": {
"201": {
"description": "Created",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/Complaint"
}
}
}
}
},
"description": "Log a new complaint a customer has raised against the bank, with category and description. It starts at 'logged'; move it on with the transition tool."
}
GET /complaints/{id}
Get customer complaint
Fetch one complaint by id with its category, status, resolution notes and SLA timing — the record to check before promising a resolution date.
Authentication
[
{
"patAuth": []
}
]
Request, responses and operation details
{
"summary": "Get customer complaint",
"parameters": [
{
"$ref": "#/components/parameters/InstanceId"
},
{
"in": "path",
"name": "id",
"required": true,
"schema": {
"type": "string"
}
}
],
"responses": {
"200": {
"description": "Found",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/Complaint"
}
}
}
},
"404": {
"description": "Not found"
}
},
"description": "Fetch one complaint by id with its category, status, resolution notes and SLA timing — the record to check before promising a resolution date."
}
PATCH /complaints/{id}
Update customer complaint
Partially update complaint details such as category, description, owner or notes. Use the transition tool for the status lifecycle: it enforces the required order.
Authentication
[
{
"patAuth": []
}
]
Request, responses and operation details
{
"summary": "Update customer complaint",
"parameters": [
{
"$ref": "#/components/parameters/InstanceId"
},
{
"in": "path",
"name": "id",
"required": true,
"schema": {
"type": "string"
}
}
],
"requestBody": {
"description": "Fields to update (partial)",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/Complaint"
}
}
}
},
"responses": {
"200": {
"description": "Updated",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/Complaint"
}
}
}
},
"404": {
"description": "Not found"
}
},
"description": "Partially update complaint details such as category, description, owner or notes. Use the transition tool for the status lifecycle: it enforces the required order."
}
DELETE /complaints/{id}
Delete customer complaint
Permanently delete a complaint. Destructive and irreversible, and it erases regulated complaint history — resolve and close it instead.
Authentication
[
{
"patAuth": []
}
]
Request, responses and operation details
{
"summary": "Delete customer complaint",
"parameters": [
{
"$ref": "#/components/parameters/InstanceId"
},
{
"in": "path",
"name": "id",
"required": true,
"schema": {
"type": "string"
}
}
],
"responses": {
"200": {
"description": "Deleted",
"content": {
"application/json": {
"schema": {
"type": "object",
"properties": {
"success": {
"type": "boolean"
},
"id": {
"type": "string"
}
}
}
}
}
},
"404": {
"description": "Not found"
}
},
"description": "Permanently delete a complaint. Destructive and irreversible, and it erases regulated complaint history — resolve and close it instead."
}
POST /complaints/{id}/transition
Transition a complaint
Move a customer complaint through logged → investigating → resolved → closed, optionally recording resolution notes. Use this rather than patching status: a complaint must be 'resolved' before it can be 'closed', and 'closed' is terminal — a closed complaint cannot be reopened.
Authentication
[
{
"patAuth": []
}
]
Request, responses and operation details
{
"summary": "Transition a complaint",
"description": "Move a customer complaint through logged → investigating → resolved → closed, optionally recording resolution notes. Use this rather than patching status: a complaint must be 'resolved' before it can be 'closed', and 'closed' is terminal — a closed complaint cannot be reopened.",
"parameters": [
{
"$ref": "#/components/parameters/InstanceId"
},
{
"in": "path",
"name": "id",
"required": true,
"schema": {
"type": "string"
}
}
],
"requestBody": {
"required": true,
"content": {
"application/json": {
"schema": {
"type": "object",
"properties": {
"status": {
"type": "string",
"enum": [
"logged",
"investigating",
"resolved",
"closed"
]
},
"resolution_notes": {
"type": "string"
}
},
"required": [
"status"
]
}
}
}
},
"responses": {
"200": {
"description": "Updated",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/Complaint"
}
}
}
},
"400": {
"description": "Invalid status"
},
"404": {
"description": "Not found"
},
"422": {
"description": "Invalid state transition"
}
}
}
GET /known_issues
List banking known issues
Bank-wide known errors and service outages (e.g. a UPI/NPCI outage) with the affected service, customer-facing workaround and status. Check here before investigating one customer's failed payment — it is often already a known issue. Narrow results server-side with this endpoint's named filter params (country, customer_id, status, …) or with OData $filter, $orderby, $select, $search, $top, $skip and $count (MCP clients send those as _filter, _orderby, …) instead of paging through everything.
Authentication
[
{
"patAuth": []
}
]
Request, responses and operation details
{
"summary": "List banking known issues",
"parameters": [
{
"$ref": "#/components/parameters/InstanceId"
},
{
"in": "query",
"name": "limit",
"schema": {
"type": "integer",
"default": 50
},
"description": "Max items per page (default 50)"
},
{
"in": "query",
"name": "cursor",
"schema": {
"type": "string"
},
"description": "Pass the previous response's nextCursor to fetch the next page"
},
{
"in": "query",
"name": "$filter",
"schema": {
"type": "string"
},
"description": "OData filter expression. Comparison operators: eq, ne, gt, ge, lt, le. Logical: and, or, not, with parentheses for grouping. String functions: contains(field,'x'), startswith(field,'x'), endswith(field,'x'). Membership: field in ('a','b'). Case-insensitive matching via tolower(field) / toupper(field). Nested fields use a slash, e.g. pto_balance/vacation_days. String literals use single quotes; dates are ISO-8601. Examples: \"status eq 'active'\"; \"salary gt 50000 and department eq 'Engineering'\"; \"contains(tolower(name),'acme')\"; \"closeDate gt 2026-01-01\"."
},
{
"in": "query",
"name": "$select",
"schema": {
"type": "string"
},
"description": "Comma-separated list of fields to return, e.g. \"id,firstName,email\". Nested fields via slash (\"pto_balance/vacation_days\"). The id field is always included."
},
{
"in": "query",
"name": "$orderby",
"schema": {
"type": "string"
},
"description": "Sort clause(s), comma-separated, each \"field [asc|desc]\" (asc is the default). Example: \"createdAt desc, lastName asc\". Null values sort last."
},
{
"in": "query",
"name": "$search",
"schema": {
"type": "string"
},
"description": "Free-text, case-insensitive substring match across the resource's searchable fields."
},
{
"in": "query",
"name": "$top",
"schema": {
"type": "integer"
},
"description": "Maximum number of items to return (page size)."
},
{
"in": "query",
"name": "$skip",
"schema": {
"type": "integer"
},
"description": "Number of matching items to skip before returning results (offset paging). Combine with $top."
},
{
"in": "query",
"name": "$count",
"schema": {
"type": "boolean"
},
"description": "When true, include @odata.count (total matches after $filter/$search, before paging) in the response."
},
{
"in": "query",
"name": "country",
"required": false,
"schema": {
"type": "string",
"enum": [
"IN",
"AU",
"US",
"GB",
"KR",
"DE"
]
},
"description": "Filter to a single country (IN | AU | US)"
},
{
"in": "query",
"name": "status",
"required": false,
"schema": {
"type": "string",
"enum": [
"known_error",
"resolved"
]
},
"description": "Filter by status"
},
{
"in": "query",
"name": "affected_service",
"required": false,
"schema": {
"type": "string"
},
"description": "Filter by affected service"
}
],
"responses": {
"200": {
"description": "Paginated list",
"content": {
"application/json": {
"schema": {
"type": "object",
"properties": {
"data": {
"type": "array",
"items": {
"$ref": "#/components/schemas/KnownIssue"
}
},
"nextCursor": {
"type": "string",
"nullable": true,
"description": "Cursor for the next page, or null on the last page"
},
"total": {
"type": "integer",
"description": "Total documents matching the filter"
}
}
}
}
}
}
},
"description": "Bank-wide known errors and service outages (e.g. a UPI/NPCI outage) with the affected service, customer-facing workaround and status. Check here before investigating one customer's failed payment — it is often already a known issue. Narrow results server-side with this endpoint's named filter params (country, customer_id, status, …) or with OData $filter, $orderby, $select, $search, $top, $skip and $count (MCP clients send those as _filter, _orderby, …) instead of paging through everything."
}
POST /known_issues
Create banking known issue
Publish a known issue or outage affecting a banking service, including the workaround agents should give customers.
Authentication
[
{
"patAuth": []
}
]
Request, responses and operation details
{
"summary": "Create banking known issue",
"parameters": [
{
"$ref": "#/components/parameters/InstanceId"
}
],
"requestBody": {
"required": true,
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/KnownIssue"
}
}
}
},
"responses": {
"201": {
"description": "Created",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/KnownIssue"
}
}
}
}
},
"description": "Publish a known issue or outage affecting a banking service, including the workaround agents should give customers."
}
GET /known_issues/{id}
Get banking known issue
Fetch one known issue by id with the affected service, workaround, status and when it started.
Authentication
[
{
"patAuth": []
}
]
Request, responses and operation details
{
"summary": "Get banking known issue",
"parameters": [
{
"$ref": "#/components/parameters/InstanceId"
},
{
"in": "path",
"name": "id",
"required": true,
"schema": {
"type": "string"
}
}
],
"responses": {
"200": {
"description": "Found",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/KnownIssue"
}
}
}
},
"404": {
"description": "Not found"
}
},
"description": "Fetch one known issue by id with the affected service, workaround, status and when it started."
}
PATCH /known_issues/{id}
Update banking known issue
Update a known issue — refine the workaround, or set status to 'resolved' once the service recovers.
Authentication
[
{
"patAuth": []
}
]
Request, responses and operation details
{
"summary": "Update banking known issue",
"parameters": [
{
"$ref": "#/components/parameters/InstanceId"
},
{
"in": "path",
"name": "id",
"required": true,
"schema": {
"type": "string"
}
}
],
"requestBody": {
"description": "Fields to update (partial)",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/KnownIssue"
}
}
}
},
"responses": {
"200": {
"description": "Updated",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/KnownIssue"
}
}
}
},
"404": {
"description": "Not found"
}
},
"description": "Update a known issue — refine the workaround, or set status to 'resolved' once the service recovers."
}
DELETE /known_issues/{id}
Delete banking known issue
Permanently delete a known issue record. Destructive — mark it 'resolved' instead so agents can still see that the outage happened.
Authentication
[
{
"patAuth": []
}
]
Request, responses and operation details
{
"summary": "Delete banking known issue",
"parameters": [
{
"$ref": "#/components/parameters/InstanceId"
},
{
"in": "path",
"name": "id",
"required": true,
"schema": {
"type": "string"
}
}
],
"responses": {
"200": {
"description": "Deleted",
"content": {
"application/json": {
"schema": {
"type": "object",
"properties": {
"success": {
"type": "boolean"
},
"id": {
"type": "string"
}
}
}
}
}
},
"404": {
"description": "Not found"
}
},
"description": "Permanently delete a known issue record. Destructive — mark it 'resolved' instead so agents can still see that the outage happened."
}
GET /bank_sla_policies
List banking SLA policies
The bank's service-level commitments by country and category (payments, cards, loans, accounts, atm, digital), giving response and resolution hours and whether a regulatory clock applies. Use these to judge whether a complaint is breaching. Not ITSM SLAs. Narrow results server-side with this endpoint's named filter params (country, customer_id, status, …) or with OData $filter, $orderby, $select, $search, $top, $skip and $count (MCP clients send those as _filter, _orderby, …) instead of paging through everything.
Authentication
[
{
"patAuth": []
}
]
Request, responses and operation details
{
"summary": "List banking SLA policies",
"parameters": [
{
"$ref": "#/components/parameters/InstanceId"
},
{
"in": "query",
"name": "limit",
"schema": {
"type": "integer",
"default": 50
},
"description": "Max items per page (default 50)"
},
{
"in": "query",
"name": "cursor",
"schema": {
"type": "string"
},
"description": "Pass the previous response's nextCursor to fetch the next page"
},
{
"in": "query",
"name": "$filter",
"schema": {
"type": "string"
},
"description": "OData filter expression. Comparison operators: eq, ne, gt, ge, lt, le. Logical: and, or, not, with parentheses for grouping. String functions: contains(field,'x'), startswith(field,'x'), endswith(field,'x'). Membership: field in ('a','b'). Case-insensitive matching via tolower(field) / toupper(field). Nested fields use a slash, e.g. pto_balance/vacation_days. String literals use single quotes; dates are ISO-8601. Examples: \"status eq 'active'\"; \"salary gt 50000 and department eq 'Engineering'\"; \"contains(tolower(name),'acme')\"; \"closeDate gt 2026-01-01\"."
},
{
"in": "query",
"name": "$select",
"schema": {
"type": "string"
},
"description": "Comma-separated list of fields to return, e.g. \"id,firstName,email\". Nested fields via slash (\"pto_balance/vacation_days\"). The id field is always included."
},
{
"in": "query",
"name": "$orderby",
"schema": {
"type": "string"
},
"description": "Sort clause(s), comma-separated, each \"field [asc|desc]\" (asc is the default). Example: \"createdAt desc, lastName asc\". Null values sort last."
},
{
"in": "query",
"name": "$search",
"schema": {
"type": "string"
},
"description": "Free-text, case-insensitive substring match across the resource's searchable fields."
},
{
"in": "query",
"name": "$top",
"schema": {
"type": "integer"
},
"description": "Maximum number of items to return (page size)."
},
{
"in": "query",
"name": "$skip",
"schema": {
"type": "integer"
},
"description": "Number of matching items to skip before returning results (offset paging). Combine with $top."
},
{
"in": "query",
"name": "$count",
"schema": {
"type": "boolean"
},
"description": "When true, include @odata.count (total matches after $filter/$search, before paging) in the response."
},
{
"in": "query",
"name": "country",
"required": false,
"schema": {
"type": "string",
"enum": [
"IN",
"AU",
"US",
"GB",
"KR",
"DE"
]
},
"description": "Filter to a single country (IN | AU | US)"
},
{
"in": "query",
"name": "category",
"required": false,
"schema": {
"type": "string",
"enum": [
"payments",
"cards",
"loans",
"accounts",
"atm",
"digital"
]
},
"description": "Filter by category"
}
],
"responses": {
"200": {
"description": "Paginated list",
"content": {
"application/json": {
"schema": {
"type": "object",
"properties": {
"data": {
"type": "array",
"items": {
"$ref": "#/components/schemas/SlaPolicy"
}
},
"nextCursor": {
"type": "string",
"nullable": true,
"description": "Cursor for the next page, or null on the last page"
},
"total": {
"type": "integer",
"description": "Total documents matching the filter"
}
}
}
}
}
}
},
"description": "The bank's service-level commitments by country and category (payments, cards, loans, accounts, atm, digital), giving response and resolution hours and whether a regulatory clock applies. Use these to judge whether a complaint is breaching. Not ITSM SLAs. Narrow results server-side with this endpoint's named filter params (country, customer_id, status, …) or with OData $filter, $orderby, $select, $search, $top, $skip and $count (MCP clients send those as _filter, _orderby, …) instead of paging through everything."
}
POST /bank_sla_policies
Create banking SLA policy
Define a new banking service-level policy for a country and category, with response/resolution hours and the regulatory-clock flag.
Authentication
[
{
"patAuth": []
}
]
Request, responses and operation details
{
"summary": "Create banking SLA policy",
"parameters": [
{
"$ref": "#/components/parameters/InstanceId"
}
],
"requestBody": {
"required": true,
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/SlaPolicy"
}
}
}
},
"responses": {
"201": {
"description": "Created",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/SlaPolicy"
}
}
}
}
},
"description": "Define a new banking service-level policy for a country and category, with response/resolution hours and the regulatory-clock flag."
}
GET /bank_sla_policies/{id}
Get banking SLA policy
Fetch one banking SLA policy by id with its response and resolution hours and regulatory-clock flag.
Authentication
[
{
"patAuth": []
}
]
Request, responses and operation details
{
"summary": "Get banking SLA policy",
"parameters": [
{
"$ref": "#/components/parameters/InstanceId"
},
{
"in": "path",
"name": "id",
"required": true,
"schema": {
"type": "string"
}
}
],
"responses": {
"200": {
"description": "Found",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/SlaPolicy"
}
}
}
},
"404": {
"description": "Not found"
}
},
"description": "Fetch one banking SLA policy by id with its response and resolution hours and regulatory-clock flag."
}
PATCH /bank_sla_policies/{id}
Update banking SLA policy
Change a banking SLA policy's response or resolution hours, or its regulatory-clock flag.
Authentication
[
{
"patAuth": []
}
]
Request, responses and operation details
{
"summary": "Update banking SLA policy",
"parameters": [
{
"$ref": "#/components/parameters/InstanceId"
},
{
"in": "path",
"name": "id",
"required": true,
"schema": {
"type": "string"
}
}
],
"requestBody": {
"description": "Fields to update (partial)",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/SlaPolicy"
}
}
}
},
"responses": {
"200": {
"description": "Updated",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/SlaPolicy"
}
}
}
},
"404": {
"description": "Not found"
}
},
"description": "Change a banking SLA policy's response or resolution hours, or its regulatory-clock flag."
}
DELETE /bank_sla_policies/{id}
Delete banking SLA policy
Permanently delete a banking SLA policy. Destructive — complaints in that category then have no target to measure against.
Authentication
[
{
"patAuth": []
}
]
Request, responses and operation details
{
"summary": "Delete banking SLA policy",
"parameters": [
{
"$ref": "#/components/parameters/InstanceId"
},
{
"in": "path",
"name": "id",
"required": true,
"schema": {
"type": "string"
}
}
],
"responses": {
"200": {
"description": "Deleted",
"content": {
"application/json": {
"schema": {
"type": "object",
"properties": {
"success": {
"type": "boolean"
},
"id": {
"type": "string"
}
}
}
}
}
},
"404": {
"description": "Not found"
}
},
"description": "Permanently delete a banking SLA policy. Destructive — complaints in that category then have no target to measure against."
}