{"openapi":"3.0.0","info":{"title":"Purple Bank Ops API","version":"1.0.0","description":"BFSI bank operations source system: branch control tower (opening checklists, pending approvals, escalations, operational-risk register) and trade finance (letters of credit with milestones/bottlenecks, bank guarantees). Records carry a `country` (IN | AU | US); trade-finance records link to retail-banking `customer_id`.\n\n---\n\n**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`."},"servers":[{"url":"https://marketplace.moveworks.com/api/purple-suite/bank-ops"}],"security":[{"patAuth":[]}],"components":{"securitySchemes":{"patAuth":{"type":"http","scheme":"bearer"}},"parameters":{"InstanceId":{"in":"header","name":"X-Instance-ID","required":true,"schema":{"type":"string"}},"ImpersonateUser":{"in":"header","name":"X-PS-Impersonate-User","required":false,"schema":{"type":"string","format":"email"},"description":"Optional. Act as a specific user in the target instance — the value is that user's email (must exist in the instance). Resolution order for the effective user: (1) this header, if set; (2) the instance's configured default MCP user; (3) otherwise no user is bound. User-scoped paths (e.g. /users/{email}/…) also accept the literal \"me\", and Graph-style apps serve /me/… twins of those paths (Graph: /me ≡ /users/{signed-in-user}) — both resolve to whatever this header (or the default MCP user) points at. An explicit path email always wins over the header. The unified MCP server does not send this header — it relies on the per-instance default — so it is primarily for direct REST/HTTP callers."}},"schemas":{"Branch":{"type":"object","properties":{"id":{"type":"string","readOnly":true,"example":"BR-001"},"country":{"type":"string","enum":["IN","AU","US","GB","KR","DE"]},"name":{"type":"string","example":"Mumbai Fort Branch"},"city":{"type":"string"},"region":{"type":"string"},"manager":{"type":"string","format":"email"},"status":{"type":"string","enum":["open","closed_today","limited"],"example":"open"},"routing":{"type":"object","properties":{"label":{"type":"string","example":"IFSC"},"code":{"type":"string"}}},"createdAt":{"type":"string","format":"date-time","readOnly":true},"updatedAt":{"type":"string","format":"date-time","readOnly":true}}},"BranchChecklist":{"type":"object","properties":{"id":{"type":"string","readOnly":true,"example":"CKL-0001"},"branch_id":{"type":"string","example":"BR-001"},"country":{"type":"string","enum":["IN","AU","US","GB","KR","DE"]},"date":{"type":"string","format":"date"},"items":{"type":"array","items":{"type":"object","properties":{"item_id":{"type":"string"},"label":{"type":"string"},"category":{"type":"string"},"status":{"type":"string","enum":["pending","done","blocked"]},"completed_by":{"type":"string","nullable":true},"completed_at":{"type":"string","format":"date-time","nullable":true}}}},"overall_status":{"type":"string","enum":["pending","complete"],"example":"pending"},"createdAt":{"type":"string","format":"date-time","readOnly":true},"updatedAt":{"type":"string","format":"date-time","readOnly":true}}},"BranchApproval":{"type":"object","properties":{"id":{"type":"string","readOnly":true,"example":"APR-0001"},"branch_id":{"type":"string"},"country":{"type":"string","enum":["IN","AU","US","GB","KR","DE"]},"type":{"type":"string","enum":["limit_override","fee_waiver","large_withdrawal","loan_exception"],"example":"large_withdrawal"},"requested_by":{"type":"string","format":"email"},"customer_id":{"type":"string","nullable":true},"amount":{"type":"object","properties":{"amount":{"type":"number","example":5000000},"currency":{"type":"string","example":"USD"},"amount_formatted":{"type":"string","example":"$5,000,000"}}},"status":{"type":"string","enum":["pending","approved","rejected"],"example":"pending"},"decision_reason":{"type":"string","nullable":true},"status_history":{"type":"array","readOnly":true,"items":{"type":"object","properties":{"status":{"type":"string"},"note":{"type":"string","nullable":true},"recorded_at":{"type":"string","format":"date-time"}}}},"createdAt":{"type":"string","format":"date-time","readOnly":true},"updatedAt":{"type":"string","format":"date-time","readOnly":true}}},"Escalation":{"type":"object","properties":{"id":{"type":"string","readOnly":true,"example":"ESC-0001"},"branch_id":{"type":"string"},"country":{"type":"string","enum":["IN","AU","US","GB","KR","DE"]},"category":{"type":"string","enum":["service","fraud","system_outage","compliance"],"example":"service"},"severity":{"type":"string","enum":["low","medium","high","critical"],"example":"high"},"status":{"type":"string","enum":["open","acknowledged","resolved"],"example":"open"},"owner":{"type":"string","format":"email"},"summary":{"type":"string"},"linked_ref":{"type":"string","nullable":true,"description":"Optional reference to a fraud case / complaint / incident id"},"raised_at":{"type":"string","format":"date-time"},"status_history":{"type":"array","readOnly":true,"items":{"type":"object","properties":{"status":{"type":"string"},"note":{"type":"string","nullable":true},"recorded_at":{"type":"string","format":"date-time"}}}},"createdAt":{"type":"string","format":"date-time","readOnly":true},"updatedAt":{"type":"string","format":"date-time","readOnly":true}}},"OperationalRisk":{"type":"object","properties":{"id":{"type":"string","readOnly":true,"example":"OPR-0001"},"branch_id":{"type":"string"},"country":{"type":"string","enum":["IN","AU","US","GB","KR","DE"]},"risk_type":{"type":"string","enum":["cash_shortage","sla_breach","staffing","control_gap"],"example":"cash_shortage"},"severity":{"type":"string","enum":["low","medium","high","critical"],"example":"medium"},"status":{"type":"string","enum":["open","mitigating","closed"],"example":"open"},"due_today":{"type":"boolean","example":true},"mitigation_plan":{"type":"string"},"status_history":{"type":"array","readOnly":true,"items":{"type":"object","properties":{"status":{"type":"string"},"note":{"type":"string","nullable":true},"recorded_at":{"type":"string","format":"date-time"}}}},"createdAt":{"type":"string","format":"date-time","readOnly":true},"updatedAt":{"type":"string","format":"date-time","readOnly":true}}},"LetterOfCredit":{"type":"object","properties":{"id":{"type":"string","readOnly":true,"example":"LC-0001"},"customer_id":{"type":"string","example":"CUST-0005"},"country":{"type":"string","enum":["IN","AU","US","GB","KR","DE"]},"applicant":{"type":"string"},"beneficiary":{"type":"string"},"amount":{"type":"object","properties":{"amount":{"type":"number","example":5000000},"currency":{"type":"string","example":"USD"},"amount_formatted":{"type":"string","example":"$5,000,000"}}},"incoterm":{"type":"string","example":"FOB"},"status":{"type":"string","enum":["issued","docs_presented","under_review","accepted","discrepant","settled"],"example":"docs_presented"},"expiry_date":{"type":"string","format":"date"},"milestones":{"type":"array","items":{"type":"object","properties":{"milestone":{"type":"string","enum":["application","issuance","shipment","doc_presentation","payment"]},"status":{"type":"string"},"date":{"type":"string","format":"date-time","nullable":true},"bottleneck_note":{"type":"string","nullable":true}}}},"createdAt":{"type":"string","format":"date-time","readOnly":true},"updatedAt":{"type":"string","format":"date-time","readOnly":true}}},"BankGuarantee":{"type":"object","properties":{"id":{"type":"string","readOnly":true,"example":"BG-0001"},"customer_id":{"type":"string"},"country":{"type":"string","enum":["IN","AU","US","GB","KR","DE"]},"type":{"type":"string","enum":["performance","financial","bid_bond"],"example":"performance"},"amount":{"type":"object","properties":{"amount":{"type":"number","example":5000000},"currency":{"type":"string","example":"USD"},"amount_formatted":{"type":"string","example":"$5,000,000"}}},"status":{"type":"string","enum":["active","invoked","expired","released"],"example":"active"},"expiry_date":{"type":"string","format":"date"},"createdAt":{"type":"string","format":"date-time","readOnly":true},"updatedAt":{"type":"string","format":"date-time","readOnly":true}}}}},"paths":{"/branches":{"get":{"summary":"List retail bank branches","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":["open","closed_today","limited"]},"description":"Filter by status"},{"in":"query","name":"region","required":false,"schema":{"type":"string"},"description":"Filter by region"}],"responses":{"200":{"description":"Paginated list","content":{"application/json":{"schema":{"type":"object","properties":{"data":{"type":"array","items":{"$ref":"#/components/schemas/Branch"}},"nextCursor":{"type":"string","nullable":true},"total":{"type":"integer"}}}}}}},"description":"Physical branches of the Purple Bank Ops bank — name, city, region, country (IN | AU | US | GB | KR | DE), today's opening status and branch manager. Branch ids (BR-###) key this app's checklists, approvals, escalations and operational risks. Supports server-side querying with _filter/_search/_orderby/_select/_top/_skip/_count (OData $-params, renamed with a leading underscore for MCP), plus this tool's simple equality params (country, branch_id, status, …)."},"post":{"summary":"Create branch","parameters":[{"$ref":"#/components/parameters/InstanceId"}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Branch"}}}},"responses":{"201":{"description":"Created","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Branch"}}}}}}},"/branches/{id}":{"get":{"summary":"Get branch","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/Branch"}}}},"404":{"description":"Not found"}}},"patch":{"summary":"Update branch","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/Branch"}}}},"responses":{"200":{"description":"Updated","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Branch"}}}},"404":{"description":"Not found"}}},"delete":{"summary":"Delete branch","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"}}}},"/branches/{id}/control-tower":{"get":{"summary":"Get a branch's control-tower briefing","description":"One call that assembles a single Purple Bank Ops branch's operational picture: today's opening checklist, approvals still pending, unresolved escalations, and operational risks due today. Prefer this over separately listing each collection when the question is about one branch (BR-### id).","parameters":[{"$ref":"#/components/parameters/InstanceId"},{"in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"Aggregated control tower","content":{"application/json":{"schema":{"type":"object","properties":{"branch":{"$ref":"#/components/schemas/Branch"},"todays_checklist":{"$ref":"#/components/schemas/BranchChecklist"},"pending_approvals":{"type":"array","items":{"$ref":"#/components/schemas/BranchApproval"}},"open_escalations":{"type":"array","items":{"$ref":"#/components/schemas/Escalation"}},"operational_risks_due_today":{"type":"array","items":{"$ref":"#/components/schemas/OperationalRisk"}}}}}}},"404":{"description":"Branch not found"}}}},"/branch_checklists":{"get":{"summary":"List daily branch-opening checklists","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":"branch_id","required":false,"schema":{"type":"string"},"description":"Filter by branch id"},{"in":"query","name":"overall_status","required":false,"schema":{"type":"string","enum":["pending","complete"]},"description":"Filter by overall status"}],"responses":{"200":{"description":"Paginated list","content":{"application/json":{"schema":{"type":"object","properties":{"data":{"type":"array","items":{"$ref":"#/components/schemas/BranchChecklist"}},"nextCursor":{"type":"string","nullable":true},"total":{"type":"integer"}}}}}}},"description":"Branch-opening checklists in Purple Bank Ops — one per branch per date, each holding line items (cash count, vault, ATM, …) in pending | done | blocked plus a rolled-up overall_status. Tick individual items off with the checklist complete-item tool rather than patching the record. Supports server-side querying with _filter/_search/_orderby/_select/_top/_skip/_count (OData $-params, renamed with a leading underscore for MCP), plus this tool's simple equality params (country, branch_id, status, …)."},"post":{"summary":"Create branch checklist","parameters":[{"$ref":"#/components/parameters/InstanceId"}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/BranchChecklist"}}}},"responses":{"201":{"description":"Created","content":{"application/json":{"schema":{"$ref":"#/components/schemas/BranchChecklist"}}}}}}},"/branch_checklists/{id}":{"get":{"summary":"Get branch checklist","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/BranchChecklist"}}}},"404":{"description":"Not found"}}},"patch":{"summary":"Update branch checklist","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/BranchChecklist"}}}},"responses":{"200":{"description":"Updated","content":{"application/json":{"schema":{"$ref":"#/components/schemas/BranchChecklist"}}}},"404":{"description":"Not found"}}},"delete":{"summary":"Delete branch checklist","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"}}}},"/branch_checklists/{id}/complete-item":{"post":{"summary":"Complete (or block) a checklist item","description":"Sets a checklist item to done | blocked | pending and recomputes overall_status.","parameters":[{"$ref":"#/components/parameters/InstanceId"},{"in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"item_id":{"type":"string","example":"cash_count"},"status":{"type":"string","enum":["pending","done","blocked"]},"completed_by":{"type":"string"}},"required":["item_id","status"]}}}},"responses":{"200":{"description":"Updated","content":{"application/json":{"schema":{"$ref":"#/components/schemas/BranchChecklist"}}}},"400":{"description":"Invalid body"},"404":{"description":"Not found"}}}},"/branch_approvals":{"get":{"summary":"List branch approval requests","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":"branch_id","required":false,"schema":{"type":"string"},"description":"Filter by branch id"},{"in":"query","name":"type","required":false,"schema":{"type":"string","enum":["limit_override","fee_waiver","large_withdrawal","loan_exception"]},"description":"Filter by type"},{"in":"query","name":"status","required":false,"schema":{"type":"string","enum":["pending","approved","rejected"]},"description":"Filter by status"}],"responses":{"200":{"description":"Paginated list","content":{"application/json":{"schema":{"type":"object","properties":{"data":{"type":"array","items":{"$ref":"#/components/schemas/BranchApproval"}},"nextCursor":{"type":"string","nullable":true},"total":{"type":"integer"}}}}}}},"description":"Decisions a branch needs from an approver in Purple Bank Ops — limit overrides, fee waivers, large withdrawals and loan exceptions, with the requester, amount and status (pending | approved | rejected). These are banking operational approvals, not IT or HR approvals (see the itsm and hrbp apps). Supports server-side querying with _filter/_search/_orderby/_select/_top/_skip/_count (OData $-params, renamed with a leading underscore for MCP), plus this tool's simple equality params (country, branch_id, status, …)."},"post":{"summary":"Create branch approval","parameters":[{"$ref":"#/components/parameters/InstanceId"}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/BranchApproval"}}}},"responses":{"201":{"description":"Created","content":{"application/json":{"schema":{"$ref":"#/components/schemas/BranchApproval"}}}}}}},"/branch_approvals/{id}":{"get":{"summary":"Get branch approval","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/BranchApproval"}}}},"404":{"description":"Not found"}}},"patch":{"summary":"Update branch approval","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/BranchApproval"}}}},"responses":{"200":{"description":"Updated","content":{"application/json":{"schema":{"$ref":"#/components/schemas/BranchApproval"}}}},"404":{"description":"Not found"}}},"delete":{"summary":"Delete branch approval","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"}}}},"/branch_approvals/{id}/transition":{"post":{"summary":"Approve or reject a pending approval","description":"Sets a pending approval to approved | rejected. Already-decided approvals cannot be changed.","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":["approved","rejected"]},"reason":{"type":"string"}},"required":["status"]}}}},"responses":{"200":{"description":"Updated","content":{"application/json":{"schema":{"$ref":"#/components/schemas/BranchApproval"}}}},"400":{"description":"Invalid status"},"404":{"description":"Not found"},"422":{"description":"Already decided"}}}},"/escalations":{"get":{"summary":"List branch escalations","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":"branch_id","required":false,"schema":{"type":"string"},"description":"Filter by branch id"},{"in":"query","name":"category","required":false,"schema":{"type":"string","enum":["service","fraud","system_outage","compliance"]},"description":"Filter by category"},{"in":"query","name":"severity","required":false,"schema":{"type":"string","enum":["low","medium","high","critical"]},"description":"Filter by severity"},{"in":"query","name":"status","required":false,"schema":{"type":"string","enum":["open","acknowledged","resolved"]},"description":"Filter by status"}],"responses":{"200":{"description":"Paginated list","content":{"application/json":{"schema":{"type":"object","properties":{"data":{"type":"array","items":{"$ref":"#/components/schemas/Escalation"}},"nextCursor":{"type":"string","nullable":true},"total":{"type":"integer"}}}}}}},"description":"Operational issues raised by a branch in Purple Bank Ops — service, fraud, system_outage or compliance — with severity, owner, a summary, an optional linked fraud/complaint reference, and status open → acknowledged → resolved. Supports server-side querying with _filter/_search/_orderby/_select/_top/_skip/_count (OData $-params, renamed with a leading underscore for MCP), plus this tool's simple equality params (country, branch_id, status, …)."},"post":{"summary":"Create escalation","parameters":[{"$ref":"#/components/parameters/InstanceId"}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Escalation"}}}},"responses":{"201":{"description":"Created","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Escalation"}}}}}}},"/escalations/{id}":{"get":{"summary":"Get escalation","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/Escalation"}}}},"404":{"description":"Not found"}}},"patch":{"summary":"Update escalation","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/Escalation"}}}},"responses":{"200":{"description":"Updated","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Escalation"}}}},"404":{"description":"Not found"}}},"delete":{"summary":"Delete escalation","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"}}}},"/escalations/{id}/transition":{"post":{"summary":"Transition an escalation","description":"Moves an escalation through open → acknowledged → resolved. Resolved is terminal.","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":["open","acknowledged","resolved"]},"owner":{"type":"string"}},"required":["status"]}}}},"responses":{"200":{"description":"Updated","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Escalation"}}}},"400":{"description":"Invalid status"},"404":{"description":"Not found"},"422":{"description":"Already resolved"}}}},"/operational_risks":{"get":{"summary":"List the branch operational-risk register","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":"branch_id","required":false,"schema":{"type":"string"},"description":"Filter by branch id"},{"in":"query","name":"risk_type","required":false,"schema":{"type":"string","enum":["cash_shortage","sla_breach","staffing","control_gap"]},"description":"Filter by risk type"},{"in":"query","name":"status","required":false,"schema":{"type":"string","enum":["open","mitigating","closed"]},"description":"Filter by status"}],"responses":{"200":{"description":"Paginated list","content":{"application/json":{"schema":{"type":"object","properties":{"data":{"type":"array","items":{"$ref":"#/components/schemas/OperationalRisk"}},"nextCursor":{"type":"string","nullable":true},"total":{"type":"integer"}}}}}}},"description":"Branch-level op-risk entries in Purple Bank Ops — cash_shortage, sla_breach, staffing or control_gap — with severity, mitigation plan, a due_today flag and status open → mitigating → closed. This is day-to-day branch risk, distinct from the enterprise risk-compliance app. Supports server-side querying with _filter/_search/_orderby/_select/_top/_skip/_count (OData $-params, renamed with a leading underscore for MCP), plus this tool's simple equality params (country, branch_id, status, …)."},"post":{"summary":"Create operational risk","parameters":[{"$ref":"#/components/parameters/InstanceId"}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/OperationalRisk"}}}},"responses":{"201":{"description":"Created","content":{"application/json":{"schema":{"$ref":"#/components/schemas/OperationalRisk"}}}}}}},"/operational_risks/{id}":{"get":{"summary":"Get operational risk","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/OperationalRisk"}}}},"404":{"description":"Not found"}}},"patch":{"summary":"Update operational risk","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/OperationalRisk"}}}},"responses":{"200":{"description":"Updated","content":{"application/json":{"schema":{"$ref":"#/components/schemas/OperationalRisk"}}}},"404":{"description":"Not found"}}},"delete":{"summary":"Delete operational risk","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"}}}},"/operational_risks/{id}/transition":{"post":{"summary":"Transition an operational risk","description":"Moves a risk through open → mitigating → closed. Closing clears due_today. Closed is terminal.","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":["open","mitigating","closed"]},"mitigation_plan":{"type":"string"}},"required":["status"]}}}},"responses":{"200":{"description":"Updated","content":{"application/json":{"schema":{"$ref":"#/components/schemas/OperationalRisk"}}}},"400":{"description":"Invalid status"},"404":{"description":"Not found"},"422":{"description":"Already closed"}}}},"/letters_of_credit":{"get":{"summary":"List trade-finance letters of credit","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":["issued","docs_presented","under_review","accepted","discrepant","settled"]},"description":"Filter by status"}],"responses":{"200":{"description":"Paginated list","content":{"application/json":{"schema":{"type":"object","properties":{"data":{"type":"array","items":{"$ref":"#/components/schemas/LetterOfCredit"}},"nextCursor":{"type":"string","nullable":true},"total":{"type":"integer"}}}}}}},"description":"Letters of credit issued for a bank customer in Purple Bank Ops — applicant, beneficiary, amount, incoterm, expiry — each carrying a milestone chain (application → issuance → shipment → doc_presentation → payment) with bottleneck notes, and a status from issued through settled. Supports server-side querying with _filter/_search/_orderby/_select/_top/_skip/_count (OData $-params, renamed with a leading underscore for MCP), plus this tool's simple equality params (country, branch_id, status, …)."},"post":{"summary":"Create letter of credit","parameters":[{"$ref":"#/components/parameters/InstanceId"}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/LetterOfCredit"}}}},"responses":{"201":{"description":"Created","content":{"application/json":{"schema":{"$ref":"#/components/schemas/LetterOfCredit"}}}}}}},"/letters_of_credit/{id}":{"get":{"summary":"Get letter of credit","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/LetterOfCredit"}}}},"404":{"description":"Not found"}}},"patch":{"summary":"Update letter of credit","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/LetterOfCredit"}}}},"responses":{"200":{"description":"Updated","content":{"application/json":{"schema":{"$ref":"#/components/schemas/LetterOfCredit"}}}},"404":{"description":"Not found"}}},"delete":{"summary":"Delete letter of credit","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"}}}},"/letters_of_credit/{id}/advance-milestone":{"post":{"summary":"Advance a letter-of-credit milestone","description":"Updates a milestone (application | issuance | shipment | doc_presentation | payment), optionally recording a bottleneck_note, and optionally advances the LC status. A settled LC is terminal.","parameters":[{"$ref":"#/components/parameters/InstanceId"},{"in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"milestone":{"type":"string","enum":["application","issuance","shipment","doc_presentation","payment"]},"status":{"type":"string","example":"complete"},"bottleneck_note":{"type":"string"},"lc_status":{"type":"string","enum":["issued","docs_presented","under_review","accepted","discrepant","settled"]}},"required":["milestone"]}}}},"responses":{"200":{"description":"Updated","content":{"application/json":{"schema":{"$ref":"#/components/schemas/LetterOfCredit"}}}},"400":{"description":"Invalid milestone/status"},"404":{"description":"Not found"},"422":{"description":"LC already settled"}}}},"/bank_guarantees":{"get":{"summary":"List trade-finance bank guarantees","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":["performance","financial","bid_bond"]},"description":"Filter by type"},{"in":"query","name":"status","required":false,"schema":{"type":"string","enum":["active","invoked","expired","released"]},"description":"Filter by status"}],"responses":{"200":{"description":"Paginated list","content":{"application/json":{"schema":{"type":"object","properties":{"data":{"type":"array","items":{"$ref":"#/components/schemas/BankGuarantee"}},"nextCursor":{"type":"string","nullable":true},"total":{"type":"integer"}}}}}}},"description":"Guarantees the bank has issued on behalf of a customer in Purple Bank Ops — performance, financial or bid_bond — with amount, expiry date and status (active | invoked | expired | released). Guarantees back a customer's obligation; letters of credit settle a trade shipment. Supports server-side querying with _filter/_search/_orderby/_select/_top/_skip/_count (OData $-params, renamed with a leading underscore for MCP), plus this tool's simple equality params (country, branch_id, status, …)."},"post":{"summary":"Create bank guarantee","parameters":[{"$ref":"#/components/parameters/InstanceId"}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/BankGuarantee"}}}},"responses":{"201":{"description":"Created","content":{"application/json":{"schema":{"$ref":"#/components/schemas/BankGuarantee"}}}}}}},"/bank_guarantees/{id}":{"get":{"summary":"Get bank guarantee","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/BankGuarantee"}}}},"404":{"description":"Not found"}}},"patch":{"summary":"Update bank guarantee","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/BankGuarantee"}}}},"responses":{"200":{"description":"Updated","content":{"application/json":{"schema":{"$ref":"#/components/schemas/BankGuarantee"}}}},"404":{"description":"Not found"}}},"delete":{"summary":"Delete bank guarantee","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"}}}}}}